client/app/services/routes.js (35 lines of code) (raw):
import { isString, isObject, filter, sortBy } from "lodash";
import pathToRegexp from "path-to-regexp";
function getRouteParamsCount(path) {
const tokens = pathToRegexp.parse(path);
return filter(tokens, isObject).length;
}
class Routes {
_items = [];
_sorted = false;
get items() {
if (!this._sorted) {
this._items = sortBy(this._items, [
item => getRouteParamsCount(item.path), // simple definitions first, with more params - last
item => -item.path.length, // longer first
item => item.path, // if same type and length - sort alphabetically
]);
this._sorted = true;
}
return this._items;
}
register(id, route) {
id = isString(id) ? id : null;
this.unregister(id);
if (isObject(route)) {
this._items = [...this._items, { ...route, id }];
this._sorted = false;
}
}
unregister(id) {
if (isString(id)) {
// removing item does not break their order (if already sorted)
this._items = filter(this._items, item => item.id !== id);
}
}
}
export default new Routes();