react-view-router
Version:
react-view-router
85 lines • 2.07 kB
JavaScript
import "core-js/modules/web.dom.iterable.js";
import { pathToRegexp } from 'path-to-regexp';
const cache = {};
const cacheLimit = 10000;
let cacheCount = 0;
function compilePath(path, options) {
const cacheKey = `${options.end}${options.strict}${options.sensitive}`;
const pathCache = cache[cacheKey] || (cache[cacheKey] = {});
if (pathCache[path]) return pathCache[path];
const keys = [];
const regx = pathToRegexp(path, keys, options);
const result = {
regx,
keys
};
if (cacheCount < cacheLimit) {
pathCache[path] = result;
cacheCount++;
}
return result;
}
/**
* Public API for matching a URL pathname to a path.
*/
function matchPath(pathname, options = {}) {
if (typeof options === 'string' || Array.isArray(options)) {
options = {
path: options
};
}
const {
subpath,
exact = false,
strict = false,
sensitive = false
} = options;
let {
path = ''
} = options;
if (subpath === '*') {
path = path.replace(/\*$/, ':fallback([^\\/]*)');
}
const paths = [].concat(path || []);
return paths.reduce((matched, path) => {
if (!path && path !== '') return null;
if (matched) return matched;
const {
regx,
keys
} = compilePath(path, {
end: exact,
strict,
sensitive
});
const match = regx.exec(pathname);
if (!match) return null;
const [url, ...values] = match;
const isExact = pathname === url;
if (exact && !isExact) return null;
return {
path,
// the path used to match
url: path === '/' && url === '' ? '/' : url,
// the matched portion of the URL
isExact,
// whether or not we matched exactly
regx,
params: keys.reduce((memo, key, index) => {
memo[key.name] = values[index];
return memo;
}, {})
};
}, null);
}
export function computeRootMatch(pathname = '/') {
return {
path: '/',
url: '/',
params: {},
regx: compilePath('/', {}),
isExact: pathname === '/',
isNull: true
};
}
export default matchPath;