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.
 
ts-puzzles/sitemap-parser/src/resolveByPath.ts

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;
};