presentation/selectors/section.selector.ts

presentation/selectors/section.selector.ts is a file in Bane's Lab Site. 51 lines of code and 8 definitions.

import { rowCount, rowWeights } from "#presentation/renderers/ontology.renderer";
import type { SectionSeed } from "#types/page.types";
import type { Tab } from "#types/document.types";
import { hasSectionPages } from "#presentation/renderers/tab.renderer";
import { loadedPage } from "#domain/registries/page.registry";
import { recordPageOf } from "#domain/converters/ontology.converter";
import { tabPath } from "#core/assets/link.assets";

export const rowRanges = function rowRanges(weights: readonly number[], budget: number): readonly (readonly [number, number])[] {
    const ranges: (readonly [number, number])[] = [];
    let start = 0;
    let held = 0;
    weights.forEach((weight, index) => {
        if (index > start && held + weight > budget) {
            ranges.push([start, index]);
            start = index;
            held = 0;
        }
        held += weight;
    });
    ranges.push([start, weights.length]);
    return ranges;
};

const seedsOfTab = function seedsOfTab(page: string, tabs: readonly Tab[], tab: Tab, budget: number): readonly SectionSeed[] {
    return tab.sections
        .filter((section) => rowCount(section) > 0 && recordPageOf(section.id) === null)
        .flatMap((section) => {
            const ranges = rowRanges(rowWeights(section), budget);
            return ranges.map((rows, index) => ({
                intro: section.intro ?? null,
                kind: section.kind ?? null,
                name: section.title,
                page,
                part: index + 1,
                parts: ranges.length,
                records: rowCount(section),
                rows,
                section: section.id,
                tab: tab.id,
                tabPath: tabPath(page, tabs, tab.id),
                tabTitle: tab.label,
            }));
        });
};

export const sectionSeedsOf = function sectionSeedsOf(page: string, budget: number): readonly SectionSeed[] {
    const definition = loadedPage(page);
    if (definition?.content.kind !== "tabbed") {
        return [];
    }
    const { layout, tabs } = definition.content;
    return tabs.filter((tab) => hasSectionPages(layout, tab)).flatMap((tab) => seedsOfTab(page, tabs, tab, budget));
};