Skip to content
File

Blob: worker/src/shared/contracts/signaling.ts

typescript56 lines
1import { z } from 'zod';
2import { nowPlayingSchema, trackSchema } from './track.ts';
3 
4const count = z.number().int().nonnegative();
5export const descriptionSchema = z.object({
6 type: z.enum(['offer', 'answer']),
7 sdp: z.string().max(16000).startsWith('v=0'),
8});
9export const offerSchema = descriptionSchema.extend({ type: z.literal('offer') });
10export const answerSchema = descriptionSchema.extend({ type: z.literal('answer') });
11export const deviceStartSchema = z
12 .object({
13 sessionDescription: offerSchema,
14 track: trackSchema.nullish(),
15 nowPlaying: nowPlayingSchema.optional(),
16 bootId: z
17 .string()
18 .regex(/^[a-f0-9]{32}$/)
19 .optional(),
20 })
21 .strict();
22export const generationSchema = z.object({ generation: z.uuid() }).strict();
23export const deviceHeartbeatSchema = generationSchema.extend({
24 nowPlaying: nowPlayingSchema.optional(),
25});
26export const loginSchema = z.object({ password: z.string().min(1).max(256) }).strict();
27export const emptySchema = z.object({}).strict();
28export const answerInputSchema = z.object({ sessionDescription: answerSchema }).strict();
29export const leaveSchema = z.object({ viewerToken: z.uuid().optional() }).strict();
30export const viewerKeySchema = z.object({ id: z.uuid(), token: z.uuid() });
31export const statusSchema = z.object({
32 online: z.boolean(),
33 viewers: count,
34 controller: z.string().nullable(),
35 generation: z.string().nullable(),
36 track: trackSchema.nullish(),
37 nowPlaying: nowPlayingSchema.nullish(),
38});
39export const joinedSchema = z.object({
40 id: z.uuid(),
41 viewerToken: z.uuid(),
42 generation: z.uuid(),
43 sessionDescription: offerSchema,
44});
45export const controllerSchema = z.object({ controller: z.string().nullable() });
46export const okSchema = z.object({ ok: z.literal(true) });
47export const audioResponseSchema = z.object({ sessionDescription: offerSchema });
48 
49export type Description = z.infer<typeof descriptionSchema>;
50export type DeviceStart = z.infer<typeof deviceStartSchema>;
51export type ViewerKey = z.infer<typeof viewerKeySchema>;
52export type Joined = z.infer<typeof joinedSchema>;
53export type RoomStatus = z.infer<typeof statusSchema>;
54export type Answer = z.infer<typeof answerSchema>;
55export type ViewerCredentials = Pick<Joined, 'id' | 'viewerToken'>;