Capture the current unreleased K1 connection, recovery, lifecycle, viewer, and test work as a single known-bad baseline for subsequent fixes.
80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
import type { StatusTone } from "@nodedc/ui-react";
|
|
|
|
import type {
|
|
BackendStatus,
|
|
RuntimePhase,
|
|
SourceMode,
|
|
StreamMetrics,
|
|
} from "./core/runtime/contracts";
|
|
|
|
const phaseLabels: Record<RuntimePhase, string> = {
|
|
unconfigured: "Модель не выбрана",
|
|
idle: "Ожидание",
|
|
configuring: "Настройка устройства",
|
|
connected: "Устройство подключено",
|
|
starting: "Запуск потока",
|
|
streaming: "Поток в реальном времени",
|
|
replaying: "Повтор записи",
|
|
stopping: "Остановка",
|
|
error: "Ошибка",
|
|
};
|
|
|
|
export function phaseLabel(phase: RuntimePhase | null | undefined): string {
|
|
return phase ? phaseLabels[phase] : "Нет состояния";
|
|
}
|
|
|
|
export function localConnectionPhaseLabel(
|
|
phase: RuntimePhase | null | undefined,
|
|
): string {
|
|
if (phase === "configuring") return "Подключение";
|
|
if (phase === "connected") return "Подключение установлено";
|
|
return phaseLabel(phase);
|
|
}
|
|
|
|
export function phaseTone(phase: RuntimePhase | null | undefined): StatusTone {
|
|
if (!phase || phase === "unconfigured" || phase === "idle") return "neutral";
|
|
if (phase === "error") return "danger";
|
|
if (["connected", "streaming", "replaying"].includes(phase)) return "success";
|
|
return "accent";
|
|
}
|
|
|
|
export function backendLabel(status: BackendStatus): string {
|
|
return {
|
|
unconfigured: "Модель не выбрана",
|
|
checking: "Проверка контура",
|
|
online: "Контур доступен",
|
|
degraded: "Контур ограничен",
|
|
offline: "Контур недоступен",
|
|
}[status];
|
|
}
|
|
|
|
export function backendTone(status: BackendStatus): StatusTone {
|
|
if (status === "online") return "success";
|
|
if (status === "degraded" || status === "checking") return "warning";
|
|
if (status === "unconfigured") return "neutral";
|
|
return "danger";
|
|
}
|
|
|
|
export function finiteMetric(value: number | null | undefined): number | null {
|
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
}
|
|
|
|
export function pipelineLatency(metrics: StreamMetrics | undefined): number | null {
|
|
return finiteMetric(metrics?.latencyMs);
|
|
}
|
|
|
|
export function formatNumber(value: number | null, digits = 1): string {
|
|
if (value === null) return "—";
|
|
return value.toLocaleString("ru-RU", {
|
|
maximumFractionDigits: digits,
|
|
minimumFractionDigits: digits,
|
|
});
|
|
}
|
|
|
|
export function sourceModeLabel(mode: SourceMode | null | undefined): string {
|
|
if (mode === "live") return "Реальное время";
|
|
if (mode === "replay") return "Повтор записи";
|
|
if (mode === "idle") return "Ожидание";
|
|
return "Неизвестно";
|
|
}
|