Files
familienarchiv/frontend/src/lib/timeline/timelineMeta.ts
Marcel 0bd6790b1f refactor(timeline): count timelineMeta totals in a single pass
Replace the flatMap intermediate array plus two filter passes with one
walk over the year bands and the undated bucket. Same counts, no
throwaway allocation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 12:19:40 +02:00

39 lines
1.4 KiB
TypeScript

import type { components } from '$lib/generated/api';
type TimelineDTO = components['schemas']['TimelineDTO'];
export interface TimelineMeta {
/** First year band's year, or `null` when there are no bands. */
firstYear: number | null;
/** Last year band's year, or `null` when there are no bands. */
lastYear: number | null;
/** Every `LETTER` entry across all year bands plus the undated bucket. */
letterCount: number;
/** Every `EVENT` entry (derived, curated, and historical) across all bands plus undated. */
eventCount: number;
}
/**
* Derives the header meta-line figures from a loaded `TimelineDTO` (REQ-002):
* the year range (first/last band) and the letter/event totals across every
* year band plus the undated bucket. Pure and the single place these counts
* live — the route renders them; `TimelineView` never recomputes them.
*/
export function timelineMeta(timeline: TimelineDTO): TimelineMeta {
const years = timeline.years;
let letterCount = 0;
let eventCount = 0;
const tally = (e: TimelineDTO['undated'][number]) => {
if (e.kind === 'LETTER') letterCount += 1;
else if (e.kind === 'EVENT') eventCount += 1;
};
for (const y of years) for (const e of y.entries) tally(e);
for (const e of timeline.undated) tally(e);
return {
firstYear: years.length ? years[0].year : null,
lastYear: years.length ? years[years.length - 1].year : null,
letterCount,
eventCount
};
}