export type PlayRunLifecycleStatus = | 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled' | 'terminated' | 'timed_out' | 'unknown'; /** The only lifecycle states exposed by the API, SDK, CLI, and UI. */ export type PlayRunPublicStatus = | 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled'; const TERMINAL_PLAY_RUN_STATUSES = new Set([ 'completed', 'failed', 'cancelled', 'terminated', 'timed_out', ]); const RECOVERABLE_DATASET_ROW_STATUSES = new Set([ 'failed', 'cancelled', 'terminated', 'timed_out', ]); export function normalizePlayRunLifecycleStatus( value: unknown, ): PlayRunLifecycleStatus { const normalized = String(value ?? '') .trim() .toLowerCase(); switch (normalized) { case 'queued': case 'pending': return 'queued'; case 'running': case 'started': return 'running'; case 'waiting': return 'waiting'; case 'completed': case 'complete': case 'succeeded': return 'completed'; case 'failed': case 'error': return 'failed'; case 'cancelled': case 'canceled': return 'cancelled'; case 'terminated': return 'terminated'; case 'timed_out': case 'timeout': return 'timed_out'; default: return 'unknown'; } } export function isTerminalPlayRunLifecycleStatus(status: unknown): boolean { return TERMINAL_PLAY_RUN_STATUSES.has( normalizePlayRunLifecycleStatus(status), ); } export function isActivePlayRunLifecycleStatus(status: unknown): boolean { const normalized = normalizePlayRunLifecycleStatus(status); return ( normalized === 'queued' || normalized === 'running' || normalized === 'waiting' ); } /** * Decode a public lifecycle value without inventing progress. Internal * termination reasons intentionally collapse to the one public cancellation * outcome at this Adapter boundary. Unknown/missing values are invalid. */ export function decodePlayRunPublicStatus( value: unknown, ): PlayRunPublicStatus | null { const status = normalizePlayRunLifecycleStatus(value); switch (status) { case 'queued': case 'running': case 'waiting': case 'completed': case 'failed': case 'cancelled': return status; case 'terminated': case 'timed_out': return 'cancelled'; case 'unknown': return null; } } export function isRecoverableDatasetRowStatus(status: unknown): boolean { return RECOVERABLE_DATASET_ROW_STATUSES.has( normalizePlayRunLifecycleStatus(status), ); } export function datasetSummaryRowModeForRunStatus( status: unknown, ): 'output' | 'all' { return isRecoverableDatasetRowStatus(status) ? 'all' : 'output'; }