@tanstack/react-location-lite-experimental
Version:
1,082 lines (908 loc) • 32.2 kB
JavaScript
/**
* react-location-lite-experimental
*
* 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
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('history')) :
typeof define === 'function' && define.amd ? define(['exports', 'react', 'history'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactLocationLite = {}, global.React, global.History));
})(this, (function (exports, React, history) { 'use strict';
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespace(React);
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);
}
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;
}
// @ts-nocheck
// We're inlining qss here for compression's sake, but we've included it as a hard dependency for the MIT license it requires.
function encode(obj, pfx) {
var k,
i,
tmp,
str = '';
for (k in obj) {
if ((tmp = obj[k]) !== void 0) {
if (Array.isArray(tmp)) {
for (i = 0; i < tmp.length; i++) {
str && (str += '&');
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
}
} else {
str && (str += '&');
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
}
}
}
return (pfx || '') + str;
}
function toValue(mix) {
if (!mix) return '';
var str = decodeURIComponent(mix);
if (str === 'false') return false;
if (str === 'true') return true;
return +str * 0 === 0 ? +str : str;
}
function decode(str) {
var tmp,
k,
out = {},
arr = str.split('&');
while (tmp = arr.shift()) {
tmp = tmp.split('=');
k = tmp.shift();
if (out[k] !== void 0) {
out[k] = [].concat(out[k], toValue(tmp.shift()));
} else {
out[k] = toValue(tmp.shift());
}
}
return out;
}
const _excluded = ["children", "location", "routes", "basepath"],
_excluded2 = ["to", "search", "hash", "children", "target", "style", "replace", "onClick", "onMouseEnter", "className", "getActiveProps", "getInactiveProps", "activeOptions", "disabled", "_ref"],
_excluded3 = ["style", "className"],
_excluded4 = ["style", "className"],
_excluded5 = ["children"];
// Source
const LocationContext = /*#__PURE__*/React__namespace.createContext(null);
const MatchesContext = /*#__PURE__*/React__namespace.createContext(null);
const routerContext = /*#__PURE__*/React__namespace.createContext(null); // Detect if we're in the DOM
const isDOM = Boolean(typeof window !== 'undefined' && window.document && window.document.createElement);
const useLayoutEffect = isDOM ? React__namespace.useLayoutEffect : React__namespace.useEffect; // This is the default history object if none is defined
const createDefaultHistory = () => isDOM ? history.createBrowserHistory() : history.createMemoryHistory();
class ReactLocation {
//
constructor(options) {
var _options$stringifySea, _options$parseSearch;
this.listeners = [];
this.isTransitioning = false;
this.history = (options == null ? void 0 : options.history) || createDefaultHistory();
this.stringifySearch = (_options$stringifySea = options == null ? void 0 : options.stringifySearch) != null ? _options$stringifySea : defaultStringifySearch;
this.parseSearch = (_options$parseSearch = options == null ? void 0 : options.parseSearch) != null ? _options$parseSearch : defaultParseSearch;
this.current = this.parseLocation(this.history.location);
this.destroy = this.history.listen(event => {
this.current = this.parseLocation(event.location, this.current);
this.notify();
});
}
subscribe(listener) {
this.listeners.push(listener);
return () => {
this.listeners = this.listeners.filter(x => x !== listener);
};
}
notify() {
this.listeners.forEach(listener => listener());
}
buildNext(basepath, dest) {
var _dest$to, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
if (basepath === void 0) {
basepath = '/';
}
if (dest === void 0) {
dest = {};
}
const from = _extends({}, this.current, dest.from);
const pathname = resolvePath(basepath, from.pathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.')); // Pre filters first
const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), from.search) : from.search; // Then the link/navigate function
const destSearch = dest.search === true ? preFilteredSearch // Preserve from true
: dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve from filters
: {}; // Then post filters
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
const search = replaceEqualDeep(from.search, postFilteredSearch);
const searchStr = this.stringifySearch(search);
let hash = dest.hash === true ? from.hash : functionalUpdate(dest.hash, from.hash);
hash = hash ? "#" + hash : '';
return {
pathname,
search,
searchStr,
hash,
href: "" + pathname + searchStr + hash,
key: dest.key
};
}
navigate(next, replace) {
this.current = next;
if (this.navigateTimeout) clearTimeout(this.navigateTimeout);
let nextAction = 'replace';
if (!replace) {
nextAction = 'push';
}
const isSameUrl = this.parseLocation(this.history.location).href === this.current.href;
if (isSameUrl && !this.current.key) {
nextAction = 'replace';
}
if (nextAction === 'replace') {
return this.history.replace({
pathname: this.current.pathname,
hash: this.current.hash,
search: this.current.searchStr
});
}
return this.history.push({
pathname: this.current.pathname,
hash: this.current.hash,
search: this.current.searchStr
});
}
parseLocation(location, previousLocation) {
var _location$hash$split$;
const 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
};
}
}
function MatchesProvider(props) {
return /*#__PURE__*/React__namespace.createElement(MatchesContext.Provider, props);
}
function Router(_ref2) {
let {
children,
location,
routes,
basepath: userBasepath
} = _ref2,
rest = _objectWithoutPropertiesLoose(_ref2, _excluded);
const basepath = cleanPath("/" + (userBasepath != null ? userBasepath : ''));
const [routerState, setRouterState] = React__namespace.useState({
location: location.current,
matches: []
});
const rootMatch = React__namespace.useMemo(() => ({
id: 'root',
params: {},
search: {},
pathname: basepath,
route: null
}), [basepath]);
const router = React__namespace.useMemo(() => {
const routesById = {};
const recurseRoutes = (routes, parent) => {
return routes.map(route => {
var _route$path, _route$children;
const path = (_route$path = route.path) != null ? _route$path : '*';
const 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({}, route, {
id
});
if (routesById[id]) {
{
console.warn("Duplicate routes found with id: " + id, routesById, route);
}
throw new Error();
}
routesById[id] = route;
route.children = (_route$children = route.children) != null && _route$children.length ? recurseRoutes(route.children, route) : undefined;
return route;
});
};
routes = recurseRoutes(routes);
return _extends({}, rest, {
routesById,
routes,
basepath,
rootMatch,
state: routerState
});
}, [routerState, rootMatch, basepath]);
useLayoutEffect(() => {
const update = () => {
const matches = matchRoutes(router, location.current);
setRouterState(() => {
return {
location: location.current,
matches: matches
};
});
};
update();
return location.subscribe(update);
}, [location]);
return /*#__PURE__*/React__namespace.createElement(LocationContext.Provider, {
value: {
location
}
}, /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
value: router
}, /*#__PURE__*/React__namespace.createElement(InitialSideEffects, null), /*#__PURE__*/React__namespace.createElement(MatchesProvider, {
value: [router.rootMatch, ...router.state.matches]
}, children != null ? children : /*#__PURE__*/React__namespace.createElement(Outlet, null))));
}
function InitialSideEffects() {
const location = useLocation();
const buildNext = useBuildNext();
const navigate = useNavigate();
useLayoutEffect(() => {
const next = buildNext({
to: '.',
search: true,
hash: true
});
if (next.href !== location.current.href) {
navigate({
to: '.',
search: true,
hash: true,
fromCurrent: true,
replace: true
});
}
}, []);
return null;
}
function useLocation() {
const context = React__namespace.useContext(LocationContext);
warning(!!context, 'useLocation must be used within a <ReactLocation />');
return context.location;
}
function useRouter() {
const value = React__namespace.useContext(routerContext);
if (!value) {
warning(true, 'You are trying to use useRouter() outside of ReactLocation!');
throw new Error();
}
return value;
}
function matchRoutes(router, currentLocation) {
if (!router.routes.length) {
return [];
}
const matches = [];
const recurse = (routes, parentMatch) => {
var _route$children3;
let {
pathname,
params
} = parentMatch;
const filteredRoutes = router != null && router.filterRoutes ? router == null ? void 0 : router.filterRoutes(routes) : routes;
const route = filteredRoutes.find(route => {
var _route$children2, _route$caseSensitive;
const fullRoutePathName = joinPaths([pathname, route.path]);
const fuzzy = !!(route.path !== '/' || (_route$children2 = route.children) != null && _route$children2.length);
const matchParams = matchRoute(currentLocation, {
to: fullRoutePathName,
search: route.search,
fuzzy,
caseSensitive: (_route$caseSensitive = route.caseSensitive) != null ? _route$caseSensitive : router.caseSensitive
});
if (matchParams) {
params = _extends({}, params, matchParams);
}
return !!matchParams;
});
if (!route) {
return;
}
const interpolatedPath = interpolatePath(route.path, params);
pathname = joinPaths([pathname, interpolatedPath]);
const interpolatedId = interpolatePath(route.id, params, true);
const match = {
id: interpolatedId,
route,
params,
pathname,
search: currentLocation.search
};
matches.push(match);
if ((_route$children3 = route.children) != null && _route$children3.length) {
recurse(route.children, match);
}
};
recurse(router.routes, router.rootMatch);
return matches;
}
function interpolatePath(path, params, leaveWildcard) {
const interpolatedPathSegments = parsePathname(path);
return joinPaths(interpolatedPathSegments.map(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 useParentMatches() {
const router = useRouter();
const match = useMatch();
const matches = router.state.matches;
return matches.slice(0, matches.findIndex(d => d.id === match.id) - 1);
}
function useMatches() {
return React__namespace.useContext(MatchesContext);
}
function useMatch() {
var _useMatches;
return (_useMatches = useMatches()) == null ? void 0 : _useMatches[0];
}
function useNavigate() {
const location = useLocation();
const match = useMatch();
const buildNext = useBuildNext();
function navigate(_ref3) {
var _fromCurrent;
let {
search,
hash,
replace,
from,
to,
fromCurrent
} = _ref3;
fromCurrent = (_fromCurrent = fromCurrent) != null ? _fromCurrent : typeof to === 'undefined';
const next = buildNext({
to,
search,
hash,
from: fromCurrent ? location.current : from != null ? from : {
pathname: match.pathname
}
});
location.navigate(next, replace);
}
return useLatestCallback(navigate);
}
function Navigate(options) {
let navigate = useNavigate();
useLayoutEffect(() => {
navigate(options);
}, [navigate]);
return null;
}
function useBuildNext() {
const location = useLocation();
const router = useRouter();
const buildNext = opts => {
const next = location.buildNext(router.basepath, opts);
const matches = matchRoutes(router, next);
const __preSearchFilters = matches.map(match => {
var _match$route$preSearc;
return (_match$route$preSearc = match.route.preSearchFilters) != null ? _match$route$preSearc : [];
}).flat().filter(Boolean);
const __postSearchFilters = matches.map(match => {
var _match$route$postSear;
return (_match$route$postSear = match.route.postSearchFilters) != null ? _match$route$postSear : [];
}).flat().filter(Boolean);
return location.buildNext(router.basepath, _extends({}, opts, {
__preSearchFilters,
__postSearchFilters
}));
};
return useLatestCallback(buildNext);
}
const Link = function Link(_ref4) {
let {
to = '.',
search,
hash,
children,
target,
style = {},
replace,
onClick,
className = '',
getActiveProps = () => ({
className: 'active'
}),
getInactiveProps = () => ({}),
activeOptions,
disabled,
_ref
} = _ref4,
rest = _objectWithoutPropertiesLoose(_ref4, _excluded2);
const match = useMatch();
const location = useLocation();
const navigate = useNavigate();
const buildNext = useBuildNext(); // If this `to` is a valid external URL, log a warning
try {
const url = new URL("" + to);
warning(false, "<Link /> should not be used for external URLs like: " + url.href);
} catch (e) {}
const next = buildNext({
to,
search,
hash,
from: {
pathname: match.pathname
}
}); // The click handler
const 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,
search,
hash,
replace,
from: {
pathname: match.pathname
}
});
}
}; // Compare path/hash for matches
const pathIsEqual = location.current.pathname === next.pathname;
const currentPathSplit = location.current.pathname.split('/');
const nextPathSplit = next.pathname.split('/');
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
const hashIsEqual = location.current.hash === next.hash; // Combine the matches based on user options
const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
const isActive = pathTest && hashTest; // Get the active props
const _ref5 = isActive ? getActiveProps() : {},
{
style: activeStyle = {},
className: activeClassName = ''
} = _ref5,
activeRest = _objectWithoutPropertiesLoose(_ref5, _excluded3); // Get the inactive props
const _ref6 = isActive ? {} : getInactiveProps(),
{
style: inactiveStyle = {},
className: inactiveClassName = ''
} = _ref6,
inactiveRest = _objectWithoutPropertiesLoose(_ref6, _excluded4);
return /*#__PURE__*/React__namespace.createElement("a", _extends({
ref: _ref,
href: disabled ? undefined : next.href,
onClick: handleClick,
target,
style: _extends({}, 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
}) : children
}));
};
function Outlet() {
var _match$route$element, _match$route$pendingE;
const router = useRouter();
const [_, ...matches] = useMatches();
const match = matches[0];
if (!match) {
return null;
}
const matchElement = (_match$route$element = match.route.element) != null ? _match$route$element : router.defaultElement;
const element = /*#__PURE__*/React__namespace.createElement(MatchesProvider, {
value: matches
}, matchElement != null ? matchElement : /*#__PURE__*/React__namespace.createElement(Outlet, null));
const pendingElement = (_match$route$pendingE = match.route.pendingElement) != null ? _match$route$pendingE : router.defaultPendingElement;
if (pendingElement) {
return /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
fallback: pendingElement
}, element);
}
return element;
}
function useResolvePath() {
const router = useRouter();
const match = useMatch();
return useLatestCallback(path => resolvePath(router.basepath, match.pathname, cleanPath(path)));
}
function useSearch() {
const location = useLocation();
return location.current.search;
}
function matchRoute(currentLocation, matchLocation) {
const pathParams = matchByPath(currentLocation, matchLocation);
const searchMatched = matchBySearch(currentLocation, matchLocation);
if (matchLocation.to && !pathParams) {
return;
}
if (matchLocation.search && !searchMatched) {
return;
}
return pathParams != null ? pathParams : {};
}
function useMatchRoute() {
const router = useRouter();
const resolvePath = useResolvePath();
return useLatestCallback(matchLocation => {
matchLocation = _extends({}, matchLocation, {
to: matchLocation.to ? resolvePath("" + matchLocation.to) : undefined
});
return matchRoute(router.state.location, matchLocation);
});
}
function MatchRoute(_ref7) {
let {
children
} = _ref7,
rest = _objectWithoutPropertiesLoose(_ref7, _excluded5);
const matchRoute = useMatchRoute();
const match = matchRoute(rest);
if (typeof children === 'function') {
return children(match);
}
return match ? children : null;
}
function usePrompt(message, when) {
const location = useLocation();
React__namespace.useEffect(() => {
if (!when) return;
let unblock = location.history.block(transition => {
if (window.confirm(message)) {
unblock();
transition.retry();
} else {
location.current.pathname = window.location.pathname;
}
});
return unblock;
}, [when, location, message]);
}
function Prompt(_ref8) {
let {
message,
when,
children
} = _ref8;
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;
const baseSegments = parsePathname(currentLocation.pathname);
const routeSegments = parsePathname("" + ((_matchLocation$to = matchLocation.to) != null ? _matchLocation$to : '*'));
const params = {};
let isMatch = (() => {
for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
const baseSegment = baseSegments[i];
const routeSegment = routeSegments[i];
const isLastRouteSegment = i === routeSegments.length - 1;
const isLastBaseSegment = i === baseSegments.length - 1;
if (routeSegment) {
if (routeSegment.type === 'wildcard') {
if (baseSegment != null && baseSegment.value) {
params['*'] = joinPaths(baseSegments.slice(i).map(d => 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);
const segments = [];
if (pathname.slice(0, 1) === '/') {
pathname = pathname.substring(1);
segments.push({
type: 'pathname',
value: '/'
});
}
if (!pathname) {
return segments;
} // Remove empty segments and '.' segments
const split = pathname.split('/').filter(Boolean);
segments.push(...split.map(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: 'pathname',
value: '/'
});
}
return segments;
}
function resolvePath(basepath, base, to) {
base = base.replace(new RegExp("^" + basepath), '/');
to = to.replace(new RegExp("^" + basepath), '/');
let baseSegments = parsePathname(base);
const toSegments = parsePathname(to);
toSegments.forEach((toSegment, index) => {
if (toSegment.value === '/') {
if (!index) {
// Leading slash
baseSegments = [toSegment];
} else if (index === toSegments.length - 1) {
// Trailing Slash
baseSegments.push(toSegment);
} else ;
} else if (toSegment.value === '..') {
baseSegments.pop();
} else if (toSegment.value === '.') {
return;
} else {
baseSegments.push(toSegment);
}
});
const joined = joinPaths([basepath, ...baseSegments.map(d => d.value)]);
return cleanPath(joined);
}
function isCtrlEvent(e) {
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
}
function useLatestCallback(cb) {
const stableFnRef = React__namespace.useRef();
const cbRef = React__namespace.useRef(cb);
cbRef.current = cb;
if (!stableFnRef.current) {
stableFnRef.current = function () {
return cbRef.current(...arguments);
};
}
return stableFnRef.current;
}
/**
* This function returns `a` if `b` is deeply equal.
* If not, it will replace any deeply equal children of `b` with those of `a`.
* This can be used for structural sharing between JSON values for example.
*/
function replaceEqualDeep(prev, next) {
if (prev === next) {
return prev;
}
const array = Array.isArray(prev) && Array.isArray(next);
if (array || isPlainObject(prev) && isPlainObject(next)) {
const aSize = array ? prev.length : Object.keys(prev).length;
const bItems = array ? next : Object.keys(next);
const bSize = bItems.length;
const copy = array ? [] : {};
let equalItems = 0;
for (let i = 0; i < bSize; i++) {
const key = array ? i : bItems[i];
copy[key] = replaceEqualDeep(prev[key], next[key]);
if (copy[key] === prev[key]) {
equalItems++;
}
}
return aSize === bSize && equalItems === aSize ? prev : copy;
}
return next;
} // Copied from: https://github.com/jonschlinkert/is-plain-object
function isPlainObject(o) {
if (!hasObjectPrototype(o)) {
return false;
} // If has modified constructor
const ctor = o.constructor;
if (typeof ctor === 'undefined') {
return true;
} // If has modified prototype
const prot = ctor.prototype;
if (!hasObjectPrototype(prot)) {
return false;
} // If constructor does not have an Object-specific method
if (!prot.hasOwnProperty('isPrototypeOf')) {
return false;
} // Most likely a plain Object
return true;
}
function hasObjectPrototype(o) {
return Object.prototype.toString.call(o) === '[object Object]';
}
const defaultParseSearch = parseSearchWith(JSON.parse);
const defaultStringifySearch = stringifySearchWith(JSON.stringify);
function parseSearchWith(parser) {
return searchStr => {
if (searchStr.substring(0, 1) === '?') {
searchStr = searchStr.substring(1);
}
let query = decode(searchStr); // Try to parse any query params that might be json
for (let key in query) {
const value = query[key];
if (typeof value === 'string') {
try {
query[key] = parser(value);
} catch (err) {//
}
}
}
return query;
};
}
function stringifySearchWith(stringify) {
return search => {
search = _extends({}, search);
if (search) {
Object.keys(search).forEach(key => {
const val = search[key];
if (typeof val === 'undefined' || val === undefined) {
delete search[key];
} else if (val && typeof val === 'object' && val !== null) {
try {
search[key] = stringify(val);
} catch (err) {// silent
}
}
});
}
const searchStr = encode(search);
return searchStr ? "?" + searchStr : '';
};
}
Object.defineProperty(exports, 'createBrowserHistory', {
enumerable: true,
get: function () { return history.createBrowserHistory; }
});
Object.defineProperty(exports, 'createHashHistory', {
enumerable: true,
get: function () { return history.createHashHistory; }
});
Object.defineProperty(exports, 'createMemoryHistory', {
enumerable: true,
get: function () { return history.createMemoryHistory; }
});
exports.Link = Link;
exports.MatchRoute = MatchRoute;
exports.MatchesProvider = MatchesProvider;
exports.Navigate = Navigate;
exports.Outlet = Outlet;
exports.Prompt = Prompt;
exports.ReactLocation = ReactLocation;
exports.Router = Router;
exports.cleanPath = cleanPath;
exports.defaultParseSearch = defaultParseSearch;
exports.defaultStringifySearch = defaultStringifySearch;
exports.functionalUpdate = functionalUpdate;
exports.matchByPath = matchByPath;
exports.matchRoute = matchRoute;
exports.matchRoutes = matchRoutes;
exports.parsePathname = parsePathname;
exports.parseSearchWith = parseSearchWith;
exports.resolvePath = resolvePath;
exports.stringifySearchWith = stringifySearchWith;
exports.useLocation = useLocation;
exports.useMatch = useMatch;
exports.useMatchRoute = useMatchRoute;
exports.useMatches = useMatches;
exports.useNavigate = useNavigate;
exports.useParentMatches = useParentMatches;
exports.usePrompt = usePrompt;
exports.useResolvePath = useResolvePath;
exports.useRouter = useRouter;
exports.useSearch = useSearch;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=index.development.js.map