// The publish lane's LIVE state (release 18): what the runner is doing, held // in this process's memory so the status (publishState.ts) can say it without // importing the runner (which reads the status — a cycle). // // On globalThis, like the auto-queue runners' singleton, so a dev-server // module reload does not lose the running lane. The CLI never starts the // runner: there `known` is false — the lane is the editor's. import type { PublishLaneLive } from "./publishPlan"; export type PublishPassRecord = { runId: string; startedAt: number; endedAt: number | null; stages: { kind: string; target: string; jobId: string | null; status: string }[]; summary: string; }; export type PublishLaneMemory = { jobId: string | null; running: boolean; passRunning: boolean; lastCheckAt: number | null; nextCheckAt: number | null; lastPassAt: number | null; lastPass: PublishPassRecord | null; lastDecision: string | null; // The stage job the pass is waiting on, if any. currentJobId: string | null; }; const KEY = "__ytt_publish_lane__"; function fresh(): PublishLaneMemory { return { jobId: null, running: false, passRunning: false, lastCheckAt: null, nextCheckAt: null, lastPassAt: null, lastPass: null, lastDecision: null, currentJobId: null, }; } /** The lane's memory in this process (created on first ask). */ export function publishLaneMemory(): PublishLaneMemory { const g = globalThis as unknown as Record; return (g[KEY] ??= fresh()); } /** Forget everything (tests). */ export function resetPublishLaneMemory(): void { (globalThis as unknown as Record)[KEY] = fresh(); } /** The lane as the status reads it. `known`: this process runs editor lanes. */ export function publishLaneLive(known: boolean): PublishLaneLive { const m = publishLaneMemory(); return { known, running: m.running, jobId: m.jobId, passRunning: m.passRunning, lastCheckAt: m.lastCheckAt, nextCheckAt: m.nextCheckAt, lastPassAt: m.lastPassAt, lastPassSummary: m.lastPass?.summary ?? null, lastDecision: m.lastDecision, }; }