/** * src/extension/widget-refresh.ts — anti-flicker widget plumbing (cycle 4). * * Two defects fixed here: * 1. TWO independent 2s timers (HUD + FleetView) each repainting * unconditionally at every tick — replaced by ONE shared ticker all * widgets subscribe to (created lazily on the first subscriber, stopped * when the last one detaches). * 2. Unconditional setWidget/setStatus calls (flicker): WidgetPainter * diffs the rendered content and SKIPS the host call when nothing * changed — an idle session performs ZERO repaints. * * Zero @earendil-works/* imports. */ import type { SessionContext, WidgetContent } from "./pi-types.js"; /** Shared refresh period (safety-net polling; event bus drives immediate refreshes). */ export declare const WIDGET_REFRESH_MS = 2000; /** Minimal subscription surface (injectable for tests). */ export interface WidgetTicker { subscribe(refresh: () => void): () => void; } /** * One shared interval for every widget owner. The timer starts when the first * listener subscribes and stops when the last one leaves — a single 2s tick * for HUD + FleetView instead of two independent timers. */ export declare class SharedIntervalTicker implements WidgetTicker { private readonly intervalMs; private timer?; private readonly listeners; constructor(intervalMs?: number); subscribe(refresh: () => void): () => void; private fire; } /** Process-wide shared widget ticker (HUD + FleetView ride the same timer). */ export declare const widgetTicker: WidgetTicker; /** True when two widget contents render identically (deep string-array equal). */ export declare function sameWidgetContent(a: WidgetContent, b: WidgetContent): boolean; /** * Diffing painter for one footer widget + its status line: setWidget / * setStatus are called ONLY when the rendered content actually changed, so an * unchanged render is a zero-op (no flicker). `clear()` always forces the * host calls (detach path). */ export declare class WidgetPainter { private readonly ctx; private readonly widgetId; private readonly statusId; private lastWidget; private widgetPainted; private lastStatus; private statusPainted; constructor(ctx: SessionContext, widgetId: string, statusId: string); /** Paint the widget content unless it renders identically to the last paint. */ paintWidget(content: WidgetContent): void; /** Paint the status text unless it is identical to the last paint. */ paintStatus(text: string | undefined): void; /** Force-clear the widget + status and reset the diff state (detach). */ clear(): void; }