Skip to content
File

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

typescript40 lines
1import { z } from 'zod';
2 
3export const CHANNEL_PROFILES = [
4 { dataChannelName: 'robot', ordered: true },
5 { dataChannelName: 'spectrum', ordered: false, maxRetransmits: 0 },
6] as const;
7// The SFU may return only id/name. Reliability is our requested configuration,
8// not a mandatory echo in its response. Reject an explicit conflicting setting.
9export const channelSchema = z
10 .object({
11 id: z.number().int().min(0).max(65534),
12 dataChannelName: z.enum(['robot', 'spectrum']),
13 ordered: z.boolean().optional(),
14 maxRetransmits: z.number().int().nonnegative().optional(),
15 })
16 .refine(
17 (channel) =>
18 channel.ordered === undefined || channel.ordered === (channel.dataChannelName === 'robot'),
19 )
20 .refine(
21 (channel) =>
22 channel.maxRetransmits === undefined ||
23 (channel.dataChannelName === 'spectrum' && channel.maxRetransmits === 0),
24 )
25 .transform((channel) => ({
26 id: channel.id,
27 ...CHANNEL_PROFILES.find((profile) => profile.dataChannelName === channel.dataChannelName)!,
28 }));
29export const channelListSchema = z
30 .array(channelSchema)
31 .length(2)
32 .refine(
33 (channels) =>
34 new Set(channels.map((channel) => channel.id)).size === 2 &&
35 new Set(channels.map((channel) => channel.dataChannelName)).size === 2,
36 );
37export const channelsSchema = z.object({ channels: channelListSchema });
38 
39export type Channel = z.infer<typeof channelSchema>;