domain/converters/search.fragment.converter.ts
domain/converters/search.fragment.converter.ts is a file in Bane's Lab Site. 68 lines of code and 12 definitions.
import type { Section, Subsection } from "#types/document.types";
import { isGlossary, textsOf } from "#core/analyzers/search.analyzer";
import { markupWords, matchesAll } from "#core/matchers/search.matcher";
import type { Block } from "#types/block.types";
const heldWords = new WeakMap<object, readonly string[]>();
const wordsIn = function wordsIn(value: object): readonly string[] {
const held = heldWords.get(value);
if (held !== undefined) {
return held;
}
const words = textsOf(value).flatMap(markupWords);
heldWords.set(value, words);
return words;
};
const proseWords = function proseWords(
parts: readonly (string | undefined)[],
blocks: readonly Block[],
): readonly string[] {
return [
...parts.flatMap((part) => (part === undefined ? [] : markupWords(part))),
...blocks.filter((block) => !isGlossary(block)).flatMap(wordsIn),
];
};
const narrowGlossaries = function narrowGlossaries(terms: readonly string[], blocks: readonly Block[]): Block[] {
return blocks.filter(isGlossary).flatMap((block) => {
const entries = block.entries.filter((entry) => matchesAll(terms, wordsIn(entry)));
return entries.length === 0 ? [] : [{ ...block, entries }];
});
};
export const narrowSubsection = function narrowSubsection(
terms: readonly string[],
sub: Subsection,
): Subsection | null {
if (matchesAll(terms, proseWords([sub.title, sub.content], sub.blocks ?? []))) {
return sub;
}
const blocks = narrowGlossaries(terms, sub.blocks ?? []);
if (blocks.length === 0) {
return null;
}
return {
blocks,
title: sub.title,
...(sub.id === undefined ? {} : { id: sub.id }),
...(sub.layout === undefined ? {} : { layout: sub.layout }),
};
};
export const narrowSection = function narrowSection(terms: readonly string[], section: Section): Section | null {
if (matchesAll(terms, proseWords([section.title, section.intro], section.blocks ?? []))) {
return section;
}
const subsections = section.subsections.flatMap((sub) => {
const narrowed = narrowSubsection(terms, sub);
return narrowed === null ? [] : [narrowed];
});
const blocks = narrowGlossaries(terms, section.blocks ?? []);
if (subsections.length === 0 && blocks.length === 0) {
return null;
}
return {
icon: section.icon,
id: section.id,
subsections,
title: section.title,
...(blocks.length === 0 ? {} : { blocks }),
...(section.layout === undefined ? {} : { layout: section.layout }),
};
};