Skip to content
File

Blob: worker/src/client/radio/session-state.ts

typescript55 lines
1import type { RGB, Telemetry } from '@/shared/contracts/robot.ts';
2import type { RoomStatus } from '@/shared/contracts/signaling.ts';
3import type { NowPlaying } from '@/shared/contracts/track.ts';
4import type { SpectrumFrame } from './protocol.ts';
5 
6export type SignalBuffer = { frame?: SpectrumFrame; at: number; count: number };
7export type ConnectionPhase = 'idle' | 'connecting' | 'connected';
8export type AccessState = 'checking' | 'required' | 'ready';
9export type IssueSource = 'status' | 'heartbeat' | 'connection' | 'control';
10export type CommandAck = {
11 state: 'idle' | 'pending' | 'confirmed' | 'error';
12 text: string;
13 at: number;
14 rtt?: number;
15};
16export type SessionState = {
17 phase: ConnectionPhase;
18 auth: AccessState;
19 room: RoomStatus;
20 viewerId?: string;
21 telemetry?: Telemetry;
22 led?: RGB;
23 nowPlaying?: NowPlaying;
24 paused?: boolean;
25 message: string;
26 issues: Partial<Record<IssueSource, string>>;
27 busy: boolean;
28 ack: CommandAck;
29 muted: boolean;
30 volume: number;
31 audioBlocked: boolean;
32 now: number;
33 telemetryAt: number;
34 received: number;
35 spectrumCount: number;
36 audio: { packets: number; bytes: number; kbps: number; lost: number; at: number };
37};
38export const initialState = (): SessionState => ({
39 phase: 'idle',
40 auth: 'checking',
41 room: { online: false, viewers: 0, controller: null, generation: null },
42 message: 'Checking the board…',
43 issues: {},
44 busy: false,
45 ack: { state: 'idle', text: '', at: 0 },
46 muted: false,
47 volume: 0.45,
48 audioBlocked: false,
49 now: 0,
50 telemetryAt: 0,
51 received: 0,
52 spectrumCount: 0,
53 audio: { packets: 0, bytes: 0, kbps: 0, lost: 0, at: 0 },
54});