@eolme/vma-router
Version:
Router for VK Mini Apps
100 lines (99 loc) • 2.68 kB
JavaScript
import * as qs from 'querystring';
import { parse as parseToTokens, tokensToRegexp, tokensToFunction } from 'path-to-regexp';
const PATH_CONFIG = {
delimiter: '/',
end: false,
strict: false,
sensitive: false
};
const cachedPaths = new Map();
const cachedConverts = new Map();
const cacheLimit = 512;
let cacheCount = 0;
export function parsePage(page) {
const cached = cachedPaths.get(page);
if (cached) {
return cached;
}
const tokens = parseToTokens(page, PATH_CONFIG);
const generator = tokensToFunction(tokens, PATH_CONFIG);
if (cacheCount < cacheLimit) {
cachedPaths.set(page, [generator, tokens]);
cacheCount++;
}
return [generator, tokens];
}
export function buildPage(page, params = {}) {
if (page === '/') {
return page;
}
const [generatePath, tokens] = parsePage(page);
const path = generatePath(params);
const query = { ...params };
tokens.forEach((token) => {
if (typeof token === 'object') {
delete query[token.name];
}
});
return path + '?' + qs.stringify(query);
}
export function convertPage(page) {
const cached = cachedConverts.get(page);
if (cached) {
return cached;
}
const tokens = parseToTokens(page, PATH_CONFIG);
const keys = [];
const regexp = tokensToRegexp(tokens, keys, PATH_CONFIG);
const result = { regexp, keys };
if (cacheCount < cacheLimit) {
cachedConverts.set(page, result);
cacheCount++;
}
return result;
}
export function matchPage(page, path) {
const { regexp, keys } = convertPage(page);
const match = regexp.exec(path);
if (!match) {
return null;
}
const [url, ...values] = match;
const params = keys.reduce((acc, key, index) => {
if (typeof key === 'object') {
acc[key.name] = values[index];
}
return acc;
}, {});
const uri = page === '/' && url === '' ? '/' : url;
const exact = path === url;
return {
uri,
exact,
params
};
}
export function parsePath(path) {
if (!path.includes('?')) {
return {
url: path,
params: {}
};
}
const [url, query] = path.split('?', 2);
if (!query) {
return {
url,
params: {}
};
}
return {
url,
params: qs.parse(query)
};
}
export function preventScrollRestoration() {
if (window.history.scrollRestoration) {
window.history.scrollRestoration = 'manual';
}
}