"use client"; import Link from "next/link"; import { bandCoverage, bandDenominator, type OperationBand, } from "yt-dlp-transcript-common/views/pipeline/band"; import { BandLegend, StateBand, } from "../../components/pipelines/StateBand"; import type { LaneState } from "yt-dlp-transcript-common/views/laneState"; import { LANE_DOT, LANE_TEXT, LANE_WORD } from "yt-dlp-transcript-common/views/laneState"; // A TYPE IMPORT AND IT HAS TO STAY ONE: syncRow.ts is a server module (it // reaches the job registry and the scheduler status payload). The row's own // label rides in on the value. import type { SyncRowView } from "../syncRow"; // What a rail row says about the lane that would do this operation's work, in // the vocabulary deriveLaneState already established: Running / Holding / Idle / // Off. "Holding" is the state this codebase already named for "sweep armed, // gate shut", and it is precisely what a crowded card was failing to say. export type RailLaneState = { state: LaneState; // Why it is not working, in words — idleReasonText for a runner, the gate for // a sweep. Null when it IS working, or when there is nothing to explain. note: string | null; }; // THE COMPARISON RAIL: every pipeline, one line each, always present. // // It IS the switcher — each row's name links to that operation's page — and it // is the context for whatever is below it, not decoration. On this corpus the // normal case is that a lane is idle BECAUSE another one is — // attribution-diarized is 99.9% blocked behind diarization, diarization is // 99.2% media-gone — and without the rail you would have to open one operation // at a time to discover that, which is exactly the question a console should // answer without being asked. // // EXACTLY ONE SATURATED COLOUR ON THE PAGE: `reachable`. Everything else is // texture on neutral. Glancing down four bands shows you WHERE THE COLOUR IS, // which is "where work can happen right now" — and that is the whole boldness // budget, in agreement with LaneCard's own note that a third tinted background // would be the accessory to remove. // // FILL PATTERN FIRST, HUE SECOND. Not a stylistic whim: report-to-video's claim // rail established here BY MEASUREMENT that no four-colour palette clears // all-pairs colour-blindness. Pattern (solid / hatched / dotted / hollow) // survives CVD, greyscale, and a dim laptop at 2am, which is when this console // is actually read. // // EACH BAND IS NORMALISED TO ITS OWN `eligible`, stated on its own row. Digest's // 79,681 is genuinely a different population from diarization's 78,019, and // quietly sharing one denominator to make the bars comparable would be a lie // about what is being compared. export function OperationRail({ bands, states, selectedId, sync, }: { bands: OperationBand[]; // operation id -> the state of the lane that dispatches it. Several // operations can share one lane (every backfill kind runs on one queue), and // that is exactly the fact the rail exists to make visible. states: Record; // The operation this page is about, highlighted so the rail says where you // are. Null on the board, which is about all of them. selectedId: string | null; // The sync row's figures, built on the server. Optional so a caller with no // scheduler payload still renders a rail rather than failing. sync?: SyncRowView; }) { return (

Pipelines

); } // THE ONE ROW THAT IS NOT A BAND. Sync is channel-scoped and cadence-triggered // (the descriptor says so: scope/trigger), so it has no reachable/blocked // population to draw and a StateBand here would be a hollow outline over a // fact that does not exist. Same anatomy as every other row — the name is the // link, the dot is aria-hidden, the state word stands alone — and its figures // are channels. First because it is upstream of everything else. RENDERED FROM // THE SSR PAYLOAD, not the 3-second poll: a cadence measured in minutes does // not need one, and a second poll would buy a spinner nobody asked for. function SyncRailRow({ sync, selected, }: { sync: SyncRowView; selected: boolean; }) { // The same four words the rail uses, and they mean the same things here. // "Holding" is the honest one for a channel that is due and has not been // picked up: the scheduler is not stopped and it is not working — the next // tick is what moves it. const state = !sync.enabled ? "unavailable" : sync.running > 0 ? "running" : sync.due > 0 ? "holding" : "idle"; const note = !sync.enabled ? "the scheduler is off — new videos are only noticed by a manual sync" : sync.heartbeatSeconds === 0 ? "no internal timer; ticks come from an external `pnpm sync:tick`" : sync.due > 0 ? "picked up on the next tick" : null; return (
  • ); } function RailRow({ band, lane, selected, }: { band: OperationBand; lane: RailLaneState; selected: boolean; }) { const denominator = bandDenominator(band); const coverage = bandCoverage(band); return (
  • {/* THE ROW'S NAME IS THE LINK, not the whole row. A link wrapping the row would take its accessible name from every figure in it — "Digest 1,204 reachable 79,681 …" — which is a name that changes on every poll and cannot be addressed. The dot is aria-hidden, so the link is named exactly the operation. */}
  • ); } // `population`, not "unit": the word beside the number names WHICH population // of the band this is (reachable, blocked, held), and "unit" already means one // item of dispatchable work everywhere the runner and the worker route use it. function Figure({ n, population, tone = "", }: { n: number; population: string; tone?: string; }) { return ( {n.toLocaleString()}{" "} {population} ); }