This commit is contained in:
commit
bd774932d5
614 files changed
+77116
No files matched your search
@@ -0,0 +1,57 @@
|
||||
export type SignalTone = 'healthy' | 'attention' | 'critical' | 'stale' | 'unknown';
|
||||
|
||||
export type SignalSource = {
|
||||
state?: string;
|
||||
freshness?: string;
|
||||
};
|
||||
|
||||
export type SignalContainer = {
|
||||
state?: string;
|
||||
health?: string;
|
||||
intentionalStop?: boolean;
|
||||
};
|
||||
|
||||
export const signalToneRank: Record<SignalTone, number> = {
|
||||
critical: 0,
|
||||
attention: 1,
|
||||
stale: 2,
|
||||
unknown: 3,
|
||||
healthy: 4,
|
||||
};
|
||||
|
||||
export function signalToneFromState(state: string | undefined): SignalTone {
|
||||
const normalized = state?.trim().toLowerCase();
|
||||
if (normalized === 'critical' || normalized === 'faulted' || normalized === 'down' || normalized === 'failed' || normalized === 'error') return 'critical';
|
||||
if (normalized === 'attention' || normalized === 'degraded' || normalized === 'warning' || normalized === 'restarting' || normalized === 'paused' || normalized === 'removing') return 'attention';
|
||||
if (normalized === 'stale') return 'stale';
|
||||
if (normalized === 'healthy' || normalized === 'normal' || normalized === 'up' || normalized === 'running' || normalized === 'fresh') return 'healthy';
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
export function worstSignalTone(tones: SignalTone[]): SignalTone {
|
||||
if (tones.length === 0) return 'unknown';
|
||||
return tones.reduce<SignalTone>((worst, tone) => signalToneRank[tone] < signalToneRank[worst] ? tone : worst, 'healthy');
|
||||
}
|
||||
|
||||
/** A successful HTTP response is not healthy when its provenance is stale or unknown. */
|
||||
export function sourceSignalTone(source: SignalSource | undefined): SignalTone {
|
||||
if (!source) return 'unknown';
|
||||
const freshness = source.freshness?.trim().toLowerCase();
|
||||
if (freshness === 'stale') return 'stale';
|
||||
if (freshness !== 'fresh') return 'unknown';
|
||||
return signalToneFromState(source.state);
|
||||
}
|
||||
|
||||
/** Mirrors the backend application-state projection without treating an intentional stop as a failure. */
|
||||
export function containerSignalTone(container: SignalContainer): SignalTone {
|
||||
const state = container.state?.trim().toLowerCase();
|
||||
const health = container.health?.trim().toLowerCase();
|
||||
if (state === 'running') {
|
||||
if (health === 'healthy') return 'healthy';
|
||||
if (health === 'unhealthy') return 'attention';
|
||||
return 'unknown';
|
||||
}
|
||||
if (state === 'restarting' || state === 'paused' || state === 'removing') return 'attention';
|
||||
if (state === 'exited' || state === 'dead' || state === 'stopped') return container.intentionalStop ? 'unknown' : 'critical';
|
||||
return 'unknown';
|
||||
}
|
||||
Reference in new issue
Block a user