callskit
Version:
A toolkit for building call experience using Cloudflare Realtime
336 lines (322 loc) • 10.8 kB
text/typescript
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
interface LoggerOptions {
level?: LogLevel;
prefix?: string;
enabled?: boolean;
}
declare class Logger {
private level;
private prefix;
private enabled;
private static levels;
constructor(options?: LoggerOptions);
private shouldLog;
private formatMessage;
debug(...args: any[]): void;
info(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
setLevel(level: LogLevel): void;
enable(): void;
disable(): void;
}
/** A function type that accepts any number of arguments and returns no value. */
type Callback = (...args: any[]) => void;
type BaseEventsMap = {
[event: string]: Callback;
};
declare class EventsHandler<TEventsMap extends BaseEventsMap = BaseEventsMap> {
#private;
constructor();
emit<K extends keyof TEventsMap>(event: K extends string ? K : never, ...args: Parameters<TEventsMap[K]>): void;
addEventListener<K extends keyof TEventsMap>(event: K extends string ? K : never, callback: TEventsMap[K]): void;
removeEventListener<K extends keyof TEventsMap>(event: K extends string ? K : never, callback: TEventsMap[K]): void;
subscribe<K extends keyof TEventsMap>(event: K extends string ? K : never, callback: TEventsMap[K]): () => void;
subscribeAll<K extends keyof TEventsMap>(callback: (event: K, ...args: Parameters<TEventsMap[K]>) => void): () => void;
unsubscribeAll<K extends keyof TEventsMap>(callback: TEventsMap[K]): void;
once<K extends keyof TEventsMap>(event: K extends string ? K : never, callback: TEventsMap[K]): () => void;
clearAll(): void;
}
type CallChatEvents = {
loaded: (messages: ChatMessage[]) => void;
message: (message: ChatMessage) => void;
};
type ChatMessagePayload = {
type: 'text';
message: string;
} | {
type: 'image' | 'file';
name: string;
url: string;
size: number;
};
type ChatBaseMessage = {
id: string;
user_id: string;
display_name: string;
created_at: Date;
};
type ChatTextMessage = ChatBaseMessage & ChatMessagePayload;
type ChatImageMessage = ChatBaseMessage & {
type: 'image';
url: string;
size: number;
};
type ChatMessage = ChatTextMessage | ChatImageMessage;
declare class CallChat extends EventsHandler<CallChatEvents> {
#private;
messages: ChatMessage[];
constructor();
sendTextMessage(message: string): void;
addMessage(message: ChatMessage): void;
addMessagesInBulk(messages: ChatMessage[]): void;
}
interface SerializedUser {
id: string;
name: string;
micEnabled: boolean;
micTrackId?: string;
cameraEnabled: boolean;
cameraTrackId?: string;
screenshareEnabled: boolean;
screenshareVideoTrackId?: string;
screenshareAudioTrackId?: string;
}
type ParticipantMediaEvents = {
micUpdate: (data: {
micEnabled: true;
micTrack: MediaStreamTrack;
} | {
micEnabled: false;
}) => void;
cameraUpdate: (data: {
cameraEnabled: true;
cameraTrack: MediaStreamTrack;
} | {
cameraEnabled: false;
}) => void;
screenshareUpdate: (data: {
screenshareEnabled: true;
screenshareVideoTrack?: MediaStreamTrack;
screenshareAudioTrack?: MediaStreamTrack;
} | {
screenshareEnabled: false;
}) => void;
volumeChange: (volume: number, lastVolume: number) => void;
nameChange: (name: string, oldName: string) => void;
devicesUpdate: (devices: MediaDeviceInfo[]) => void;
activeDeviceUpdate: (type: 'mic' | 'camera', device: MediaDeviceInfo) => void;
};
type CallSelfEvents = ParticipantMediaEvents;
type CallSelfOptions = {
name: string;
defaults: CallClientOptions['defaults'];
};
/** Camera Quality Code
* - `a` is High Quality
* - `b` is Data Saver
*/
type VideoEncodingRid = 'a' | 'b';
declare class CallSelf extends EventsHandler<CallSelfEvents> {
#private;
id: string;
name: string;
constructor(options: CallSelfOptions);
startMic(): void;
stopMic(): void;
startCamera(): void;
stopCamera(): void;
startScreenshare(): void;
stopScreenshare(): void;
setCameraDevice(deviceId: string): Promise<void>;
setMicDevice(deviceId: string): Promise<void>;
get micEnabled(): boolean;
get micTrack(): MediaStreamTrack | undefined;
get cameraEnabled(): boolean;
get cameraTrack(): MediaStreamTrack | undefined;
get screenshareEnabled(): boolean;
get screenshareTracks(): {
video: MediaStreamTrack | undefined;
audio: MediaStreamTrack | undefined;
} | undefined;
get devices(): MediaDeviceInfo[] | undefined;
get activeDevices(): {
mic: MediaDeviceInfo | undefined;
camera: MediaDeviceInfo | undefined;
};
setName(name: string): void;
toJSON(): SerializedUser;
toString(): string;
}
type NetworkQuality = 'excellent' | 'good' | 'fair' | 'poor';
interface NetworkStats {
rtt: number;
packetLoss: number;
jitter: number;
bandwidth: number;
quality: NetworkQuality;
timestamp: number;
}
interface NetworkQualityConfig {
monitoringInterval: number;
adaptiveQualityEnabled: boolean;
qualityThresholds: {
excellent: {
minBandwidth: number;
maxRtt: number;
maxPacketLoss: number;
};
good: {
minBandwidth: number;
maxRtt: number;
maxPacketLoss: number;
};
fair: {
minBandwidth: number;
maxRtt: number;
maxPacketLoss: number;
};
};
qualityChangeDebounce: number;
}
type CallParticipantEvents = ParticipantMediaEvents;
interface CallParticipantOptions extends Partial<SerializedUser> {
id: string;
name: string;
micEnabled?: boolean;
micTrackId?: string;
cameraEnabled?: boolean;
cameraTrackId?: string;
screenshareEnabled?: boolean;
screenshareVideoTrackId?: string;
screenshareAudioTrackId?: string;
}
declare class CallParticipant extends EventsHandler<CallParticipantEvents> {
#private;
id: string;
name: string;
constructor(options: CallParticipantOptions);
updateMicState(updates: {
micEnabled: boolean;
micTrackId?: string;
}): void;
updateCameraState(updates: {
cameraEnabled: boolean;
cameraTrackId?: string;
}): void;
updateScreenshareState(updates: {
screenshareEnabled: boolean;
screenshareVideoTrackId?: string;
screenshareAudioTrackId?: string;
}): void;
get micEnabled(): boolean;
get micTrack(): MediaStreamTrack | undefined;
get cameraEnabled(): boolean;
get cameraTrack(): MediaStreamTrack | undefined;
get screenshareEnabled(): boolean;
get screenshareTracks(): {
video: MediaStreamTrack;
audio: MediaStreamTrack | undefined;
} | undefined;
toString(): string;
static fromJSON(obj: SerializedUser): CallParticipant;
}
type ParticipantMapEvents = {
added: (participant: CallParticipant) => void;
updated: (participant: CallParticipant) => void;
removed: (participant: CallParticipant) => void;
cleared: () => void;
micUpdate: (participant: CallParticipant) => void;
cameraUpdate: (participant: CallParticipant) => void;
screenshareUpdate: (participant: CallParticipant) => void;
};
declare class CallParticipantMap extends EventsHandler<ParticipantMapEvents> implements Map<string, CallParticipant> {
#private;
constructor();
get(id: string): CallParticipant | undefined;
set(id: string, participant: CallParticipant): this;
delete(id: string): boolean;
has(id: string): boolean;
values(): MapIterator<CallParticipant>;
keys(): MapIterator<string>;
entries(): MapIterator<[string, CallParticipant]>;
forEach(callbackfn: (value: CallParticipant, key: string, map: Map<string, CallParticipant>) => void, thisArg?: any): void;
get size(): number;
clear(): void;
toArray(): CallParticipant[];
[Symbol.iterator](): MapIterator<[string, CallParticipant]>;
get [Symbol.toStringTag](): string;
}
type ParticipantControllerEvents = {
added: (participant: CallParticipant) => void;
updated: (participant: CallParticipant) => void;
removed: (participant: CallParticipant) => void;
micUpdate: (participant: CallParticipant) => void;
cameraUpdate: (participant: CallParticipant) => void;
screenshareUpdate: (participant: CallParticipant) => void;
};
declare class ParticipantsController extends EventsHandler<ParticipantControllerEvents> {
joined: CallParticipantMap;
constructor();
addParticipant(participant: CallParticipant): void;
removeParticipantById(participantId: string): void;
}
type CallEvents = {
connected: () => void;
joined: () => void;
left: () => void;
mediaConnected: () => void;
cameraQualityChanged: (newQuality: VideoEncodingRid, oldQuality: VideoEncodingRid) => void;
adaptiveQualityChanged: (newQuality: VideoEncodingRid, oldQuality: VideoEncodingRid) => void;
};
type CallClientEvents = CallEvents;
type CallClientOptions = {
room: string;
displayName: string;
socketBaseUrl: string;
apiBaseUrl: string;
apiHeaders?: Headers;
defaults?: {
audio?: boolean;
video?: boolean;
};
autoJoin?: boolean;
config?: {
preferredCameraQuality?: VideoEncodingRid;
networkQuality?: Partial<NetworkQualityConfig>;
};
onError?: (error: Error) => void;
logLevel?: LogLevel;
};
declare class CallClient extends EventsHandler<CallClientEvents> {
#private;
room: string;
state: undefined | 'connected' | 'joined' | 'left';
started_at: Date;
self: CallSelf;
participants: ParticipantsController;
chat: CallChat;
constructor(options: CallClientOptions);
join(): void;
leave(): void;
get cameraTrackQuality(): VideoEncodingRid;
/**
* Set the remote camera track quality.
* - `a` - high quality
* - `b` - lower quality
*/
setRemoteCameraTrackQuality(quality: VideoEncodingRid): void;
/**
* Enable or disable adaptive camera quality based on network conditions
*/
setAdaptiveQualityEnabled(enabled: boolean): void;
/**
* Get current network quality information
*/
getNetworkQuality(): {
quality: NetworkQuality;
stats: NetworkStats | null;
recommendedCameraQuality: VideoEncodingRid;
};
}
export { type ChatMessage as C, Logger as L, type SerializedUser as S, type VideoEncodingRid as V, type ChatMessagePayload as a, type CallClientOptions as b, CallClient as c, type CallSelfOptions as d, CallSelf as e, CallParticipant as f, type CallChatEvents as g, CallChat as h };