You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
1.5 KiB
37 lines
1.5 KiB
import { Sitemap } from './types';
|
|
|
|
// First implementation, parsing paths and walking through the entire tree every time
|
|
/*export const createPathResolver =
|
|
(sitemap: Sitemap | null) => (path: string) => {
|
|
// TODO: use something to parse paths rather than just splitting it here by `'/'` (which might cause all kinds of problems for complicated paths).
|
|
// TODO2: Should probably also handle urlencode somehow, e.g. for `path === '/root/page%2fwith%2fslash/etc'`
|
|
const parts = path.split('/').filter((part) => part.length);
|
|
|
|
return (
|
|
parts.reduce<Sitemap | null | undefined>(
|
|
(node, part) =>
|
|
node?.children.find(({ name }) => name === part),
|
|
sitemap,
|
|
)?.id ?? null
|
|
);
|
|
};*/
|
|
|
|
const createPaths = (node: Sitemap): Readonly<[string, number]>[] => [
|
|
['', node.id],
|
|
...node.children.flatMap((childNode) =>
|
|
createPaths(childNode).map(
|
|
([path, id]) => [`/${childNode.name}${path}`, id] as const,
|
|
),
|
|
),
|
|
];
|
|
|
|
// Second, improved implementation, where we build a static hashmap from complete paths to IDs once,
|
|
// and then use it as a single lookup table.
|
|
export const createPathResolver = (sitemap: Sitemap | null) => {
|
|
const rawPathsData = sitemap ? createPaths(sitemap) : [];
|
|
const pathsMap = new Map(
|
|
rawPathsData.map(([path, id]) => [path.length ? path : '/', id]),
|
|
);
|
|
|
|
return (path: string) => pathsMap.get(path) ?? null;
|
|
};
|
|
|