@comm-baas/client-sdk
Browser SDK for the EthioConnect platform. Provides authenticated HTTP access to the platform REST API and a WebSocket signaling connection with automatic session resume.
Installation
npm install @comm-baas/client-sdk livekit-client
livekit-client is an optional peer dependency — install it when you need the media layer (audio/video via LiveKit).
Quick Start
Initialize the client
import { CommBaasClient } from '@comm-baas/client-sdk';
// Static token
const client = new CommBaasClient({
baseUrl: 'https://api.comm-baas.example.com/v1',
token: accessToken,
});
// Or use a token provider for automatic refresh
const client = new CommBaasClient({
baseUrl: 'https://api.comm-baas.example.com/v1',
token: async () => {
const res = await fetch('/api/token');
const { access_token } = await res.json();
return access_token;
},
});
Join a room
import { SignalingConnection } from '@comm-baas/client-sdk';
const http = client.getHttpClient();
const join = await http.post('/rooms/room_abc/join');
const signaling = new SignalingConnection(join.signal_url, join.signal_ticket);
signaling.on('hello', (msg) => {
console.log('Session established:', msg.session_id);
});
signaling.on('roster_snapshot', (msg) => {
console.log('Roster:', msg.participants);
});
signaling.on('room_event', (msg) => {
console.log('Room event:', msg);
});
signaling.connect();
Leave a room
signaling.disconnect(); // Graceful disconnect
signaling.destroy(); // Full cleanup
Configuration
| Option | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Base URL of the API. |
token | string | () => Promise<string> | Yes | Static JWT or async token provider. |
Events Reference
| Event | Payload | Description |
|---|---|---|
hello | HelloMessage | Fired once after connection. Contains session_id, server_time, heartbeat_interval_ms. |
roster_snapshot | RosterSnapshotMessage | Full participant list. Sent on connect and on requestRoster(). |
room_event | RoomEventMessage | Incremental room events (join/leave, mute, role change). Carries monotonic seq number. |
resumed | ResumedMessage | Fired after successful session resume. Missed events replayed before this. |
stateChanged | SignalingState | Every state transition: disconnected, connecting, connected, resuming. |
error | Error | WebSocket errors. |
Signaling Reconnection
The signaling connection implements automatic session resume:
disconnected ──connect()──> connecting ──hello──> connected
^ |
| (ws close)
| |
└──(max retries)── resuming <──(has sessionId)───┘
|
(resumed msg)
v
connected
- On unexpected WebSocket close, the client enters
resumingif it has asession_id. - Reconnects with exponential backoff (1s, 2s, 4s) for up to 3 attempts.
- Sends a
resumeframe withsession_idandlast_seq. - Server replays missed events and sends a
resumedmessage. - If all retries exhausted, moves to
disconnected.
Intentional disconnects (calling disconnect()) and normal closures (code 1000) do not trigger reconnection.
Heartbeat
After the hello handshake, the client sends periodic ping frames at the server-specified interval (default 15s). The server responds with pong frames.
Moderation API
const http = client.getHttpClient();
await http.post(`/rooms/${roomId}/participants/${userId}/mute`, { track: 'audio' });
await http.post(`/rooms/${roomId}/participants/${userId}/kick`, { reason: 'Disruptive' });
await http.post(`/rooms/${roomId}/participants/${userId}/ban`, { reason: 'Violations' });
await http.post(`/rooms/${roomId}/participants/${userId}/unban`);
await http.post(`/rooms/${roomId}/participants/${userId}/role`, { role: 'moderator' });
LiveKit Escape Hatch
When livekit-client is installed, use the LiveKit token from the join response for direct media control:
import { Room } from 'livekit-client';
const lkRoom = new Room();
await lkRoom.connect(joinResponse.livekit_url, joinResponse.livekit_token);
// Full LiveKit API: screen share, video, simulcast, etc.
Error Handling
| Error Class | HTTP Status | When |
|---|---|---|
AuthenticationError | 401 | Token missing, invalid, or expired. |
AuthorizationError | 403 | Insufficient permissions. |
NotFoundError | 404 | Resource not found. |
ValidationError | 422 | Validation failed. |
RateLimitError | 429 | Rate limit exceeded. |
NetworkError | -- | Network failure. |
CommBaasError | Other | Base class. |