tools/core/transformers/agenda.transformer.ts

tools/core/transformers/agenda.transformer.ts is a file in Coordination Surface. 45 lines of code and 11 definitions.

import { SCHEDULE_HEADER } from "../constants/agenda.constants.ts";
import type { ScheduleReading } from "../types/agenda.types.ts";
import { renderSchedule } from "../formatters/agenda.formatter.ts";
import { sameRow } from "../normalizers/document.normalizer.ts";

const ROW_MARKER = "|";

interface TableBounds {
    readonly from: number;
    readonly to: number;
}

export const scheduleBounds = function scheduleBounds(lines: readonly string[]): TableBounds | null {
    const from = lines.findIndex((line) => sameRow(line, SCHEDULE_HEADER));
    if (from === -1) {
        return null;
    }

    let to = from;
    while (to + 1 < lines.length && (lines[to + 1] ?? "").trim().startsWith(ROW_MARKER)) {
        to += 1;
    }

    return { from, to };
};

export const healSchedule = function healSchedule(source: string, rendered: readonly string[]): string | null {
    const lines = source.split("\n");
    const bounds = scheduleBounds(lines);
    if (bounds === null) {
        return null;
    }

    const held = lines.slice(bounds.from, bounds.to + 1);
    if (held.length === rendered.length && held.every((line, index) => sameRow(line, rendered[index] ?? ""))) {
        return null;
    }

    return [...lines.slice(0, bounds.from), ...rendered, ...lines.slice(bounds.to + 1)].join("\n");
};

export const driftedRows = function driftedRows(
    lines: readonly string[],
    readings: readonly ScheduleReading[],
): ScheduleReading[] {
    const bounds = scheduleBounds(lines);
    if (bounds === null) {
        return [];
    }

    const rendered = renderSchedule(readings);
    return readings.filter(
        (_reading, index) => !sameRow(lines[bounds.from + 2 + index] ?? "", rendered[index + 2] ?? ""),
    );
};