Shared Types Reference
Complete type reference for sockr-shared. Imported by both sockr-server and sockr-client — zero runtime dependencies.
SocketEvent enum and EventPayloads interface define the entire Sockr protocol. Importing from sockr-shared ensures your server and client never drift out of sync.
SocketEvent Enum
All 63 event strings used across the Sockr protocol. Import and use these everywhere instead of raw strings.
import { SocketEvent } from 'sockr-shared';
Connection
Authentication
Presence
Direct Messaging
Group Management
Group Messaging
Voice Calling (P2P)
Group Conference Calling (SFU)
EventPayloads Interface
Maps every SocketEvent to its typed payload. Used internally by SocketClient and SocketServer for type-safe emit/listen.
import { EventPayloads, SocketEvent } from 'sockr-shared';
// Example: type-safe event handler
const handler = (data: EventPayloads[SocketEvent.RECEIVE_MESSAGE]) => {
console.log(data.from, data.content, data.timestamp);
};
interface EventPayloads {
// Auth
authenticate: { token: string };
authenticated: { userId: string; socketId: string };
auth_error: { message: string };
// Presence
user_online: { userId: string };
user_offline: { userId: string };
get_online_status: { userIds: string[] };
online_status: { statuses: Record<string, boolean> };
// Direct messaging
send_message: { to: string; content: string; metadata?: Record<string, any> };
receive_message: { from: string; content: string; timestamp: number; messageId: string; metadata?: Record<string, any> };
message_delivered: { messageId: string };
message_read: { messageId: string; from?: string };
message_error: { messageId: string; error: string };
typing_start: { from: string };
typing_stop: { from: string };
get_message_history: { with: string; limit?: number; before?: number };
message_history: { conversationId: string; messages: PersistedMessage[] };
// Group management
group_create: { name: string; members?: string[]; metadata?: Record<string, any> };
group_created: { group: Group };
group_create_error: { error: string };
group_join: { groupId: string };
group_joined: { groupId: string; group: Group; queuedMessages?: PersistedMessage[] };
group_join_error: { groupId: string; error: string };
group_leave: { groupId: string };
group_left: { groupId: string };
group_member_joined: { groupId: string; member: GroupMember };
group_member_left: { groupId: string; userId: string };
get_group_members: { groupId: string };
group_members: { groupId: string; members: GroupMember[] };
get_user_groups: Record<string, never>;
user_groups: { groups: Group[] };
// Group messaging
group_send_message: { groupId: string; content: string; metadata?: Record<string, any> };
group_receive_message: { groupId: string; messageId: string; from: string; content: string; timestamp: number; metadata?: Record<string, any> };
group_message_delivered: { groupId: string; messageId: string };
group_message_read: { groupId: string; messageId: string };
group_message_error: { groupId: string; messageId?: string; error: string };
group_typing_start: { groupId: string; from: string };
group_typing_stop: { groupId: string; from: string };
get_group_message_history: { groupId: string; limit?: number; before?: number };
group_message_history: { groupId: string; messages: PersistedMessage[] };
// Voice calling (P2P)
call_get_ice_servers: Record<string, never>;
call_ice_servers: { iceServers: IceServer[] };
call_initiate: { to: string; sdpOffer: string };
call_incoming: { callId: string; from: string; sdpOffer: string; iceServers: IceServer[] };
call_ringing: { callId: string };
call_answer: { callId: string; sdpAnswer: string };
call_answered: { callId: string; sdpAnswer: string };
call_reject: { callId: string };
call_rejected: { callId: string };
call_hangup: { callId: string };
call_ended: { callId: string };
call_busy: { callId: string };
call_ice_candidate: { callId: string; candidate: IceCandidateInit };
// Group conference calling (SFU)
conference_join: { groupId: string };
conference_leave: { groupId: string };
conference_token: { groupId: string; sfuUrl: string; token: string };
conference_started: { groupId: string; startedBy: string; participantCount: number };
conference_ended: { groupId: string };
conference_participant_joined: { groupId: string; userId: string; participantCount: number };
conference_participant_left: { groupId: string; userId: string; participantCount: number };
conference_error: { groupId: string; error: string };
}
User & UserConnection
User
Represents an authenticated connected user. Used internally by ConnectionManager.
interface User {
id: string; // The authenticated userId (from AuthHandler)
socketId: string; // Socket.IO socket ID for this connection
connectedAt: number; // Unix timestamp (ms) when connected
metadata?: Record<string, any>;
}
UserConnection
A lightweight snapshot of a user's connection state.
interface UserConnection {
userId: string;
socketId: string;
isOnline: boolean;
}
Message Types
Message
In-flight message shape (before persistence).
interface Message {
id: string;
from: string; // sender userId
to: string; // recipient userId
content: string;
timestamp: number; // Unix timestamp (ms)
delivered: boolean;
metadata?: Record<string, any>;
}
PersistedMessage
The unified persisted message shape used by IMessageStore. Handles both 1:1 and group messages.
interface PersistedMessage {
id: string;
conversationId: string; // "${userA}:${userB}" (sorted) for 1:1
// groupId for group messages
from: string;
to?: string; // set for 1:1 messages
groupId?: string; // set for group messages
content: string;
timestamp: number; // Unix timestamp (ms)
metadata?: Record<string, any>;
deliveredTo: string[]; // userIds message was delivered to
readBy: string[]; // userIds who have read the message
}
MessageOptions
interface MessageOptions {
requireAcknowledgment?: boolean;
timeout?: number; // ms
}
PaginationOpts
Used by IMessageStore.getMessages() and passed through get_message_history / get_group_message_history events.
interface PaginationOpts {
limit: number;
before?: number; // Unix timestamp — fetch messages before this time
after?: number; // Unix timestamp — fetch messages after this time
}
Group Types
Group
interface Group {
id: string;
name: string;
createdBy: string; // userId of the creator
createdAt: number; // Unix timestamp (ms)
members: string[]; // array of userIds
metadata?: Record<string, any>;
}
GroupMember
type GroupMemberRole = 'admin' | 'member';
interface GroupMember {
userId: string;
role: GroupMemberRole; // 'admin' | 'member'
joinedAt: number; // Unix timestamp (ms)
}
GroupMessage
interface GroupMessage {
id: string;
groupId: string;
from: string; // sender userId
content: string;
timestamp: number; // Unix timestamp (ms)
metadata?: Record<string, any>;
deliveredTo: string[]; // userIds message was delivered to
readBy: string[]; // userIds who have read the message
}
Voice Call Types
CallStatus
type CallStatus = 'initiating' | 'ringing' | 'active' | 'ended' | 'rejected' | 'busy';
IceServer
Mirrors RTCIceServer — safe to cast directly on the client. Used in call_incoming and call_ice_servers payloads.
interface IceServer {
urls: string | string[];
username?: string;
credential?: string;
}
IceCandidateInit
Serialisable form of RTCIceCandidateInit — safe to transmit over a socket.
interface IceCandidateInit {
candidate?: string;
sdpMid?: string | null;
sdpMLineIndex?: number | null;
usernameFragment?: string | null;
}
ActiveCall
Server-side representation of an in-flight call, keyed by callId.
interface ActiveCall {
callId: string;
callerId: string;
calleeId: string;
status: CallStatus;
startedAt: number; // Unix timestamp (ms)
}
Conference Types
ConferenceParticipant
interface ConferenceParticipant {
userId: string;
joinedAt: number; // Unix timestamp (ms)
}
ConferenceRoom
Server-side representation of an active conference room, keyed by groupId.
interface ConferenceRoom {
groupId: string;
participants: ConferenceParticipant[];
startedAt: number;
startedBy: string;
}
SFU Provider Types
ISFUProvider (server-side)
Implement this interface to connect Sockr's ConferencePlugin to any SFU. Sockr ships LiveKitSFUProvider as the reference implementation.
interface ISFUProvider {
connect?(): Promise<void>;
disconnect?(): Promise<void>;
generateToken(roomName: string, participantIdentity: string, opts?: TokenOptions): Promise<string>;
createRoom?(roomName: string, opts?: RoomOptions): Promise<void>;
deleteRoom?(roomName: string): Promise<void>;
}
TokenOptions
interface TokenOptions {
ttl?: number; // Credential lifetime in seconds. Defaults to 3600.
canPublish?: boolean; // Whether participant can publish audio/video. Defaults to true.
canSubscribe?: boolean; // Whether participant can subscribe. Defaults to true.
}
RoomOptions
interface RoomOptions {
emptyTimeout?: number; // Seconds before an empty room is auto-deleted. Defaults to 300.
}
ISFUClientAdapter (client-side)
Client-side SFU abstraction used by useConferenceCall(). Sockr ships LiveKitClientAdapter as the reference implementation.
interface ISFUClientAdapter {
connect(sfuUrl: string, token: string, opts?: SFUConnectOptions): Promise<void>;
disconnect(): Promise<void>;
publishTracks(opts?: SFUPublishOptions): Promise<void>;
onTrackSubscribed(handler: (track: MediaStreamTrack, participantId: string) => void): void;
onTrackUnsubscribed(handler: (track: MediaStreamTrack, participantId: string) => void): void;
onParticipantConnected(handler: (participantId: string) => void): void;
onParticipantDisconnected(handler: (participantId: string) => void): void;
onDisconnected(handler: () => void): void;
}
interface SFUConnectOptions {
audio?: boolean; // Publish audio immediately. Default: true.
video?: boolean; // Publish video immediately. Default: false.
}
interface SFUPublishOptions {
audio?: boolean;
video?: boolean;
}
Config Types
ServerConfig
interface ServerConfig {
port?: number;
cors?: {
origin: string | string[];
credentials?: boolean;
};
pingTimeout?: number;
pingInterval?: number;
transports?: ('websocket' | 'polling')[];
providers?: {
messageStore?: IMessageStore;
queue?: IQueueProvider;
cache?: ICacheProvider;
};
/** Voice calling configuration. Required to enable the VoicePlugin. */
voice?: VoiceConfig;
}
VoiceConfig
interface VoiceConfig {
/** Static ICE servers (e.g. a public STUN). Always included as-is. */
iceServers?: IceServer[];
/** Coturn TURN config. When provided, Sockr generates short-lived HMAC-SHA1 credentials per user. The secret never reaches the client. */
turn?: TurnConfig;
}
interface TurnConfig {
urls: string | string[]; // TURN server URL(s), e.g. "turn:turn.example.com:3478"
secret: string; // static-auth-secret from turnserver.conf
ttl?: number; // Credential lifetime in seconds. Defaults to 3600.
}
ClientConfig
interface ClientConfig {
url: string;
autoConnect?: boolean;
reconnection?: boolean;
reconnectionAttempts?: number;
reconnectionDelay?: number;
timeout?: number;
transports?: ('websocket' | 'polling')[];
}
IMessageStore
Persistence contract for all messages and group metadata. Implement this interface to use any database with Sockr.
import type { IMessageStore } from 'sockr-shared';
class MyStore implements IMessageStore {
// implement all methods
}
new SocketServer({
providers: { messageStore: new MyStore() }
});
interface IMessageStore {
// ── Messages ──────────────────────────────────────────────
/** Persist a message. Called before delivery is attempted. */
saveMessage(message: PersistedMessage): Promise<PersistedMessage>;
/** Retrieve a single message by ID. */
getMessage(messageId: string): Promise<PersistedMessage | null>;
/**
* Paginated message history for a conversation.
* conversationId is "${userA}:${userB}" (sorted) for 1:1,
* or the groupId for group conversations.
*/
getMessages(
conversationId: string,
opts: PaginationOpts
): Promise<PersistedMessage[]>;
/** Return messages not yet delivered to the given userId. */
getUndeliveredMessages(userId: string): Promise<PersistedMessage[]>;
/** Mark a message as delivered to a specific user. */
markDelivered(messageId: string, userId: string): Promise<void>;
/** Mark a message as read by a specific user. */
markRead(messageId: string, userId: string): Promise<void>;
// ── Groups ────────────────────────────────────────────────
saveGroup(group: Group): Promise<Group>;
getGroup(groupId: string): Promise<Group | null>;
updateGroup(
groupId: string,
updates: Partial<Pick<Group, 'name' | 'metadata'>>
): Promise<Group>;
deleteGroup(groupId: string): Promise<void>;
addGroupMember(groupId: string, member: GroupMember): Promise<void>;
removeGroupMember(groupId: string, userId: string): Promise<void>;
getGroupMembers(groupId: string): Promise<GroupMember[]>;
getUserGroups(userId: string): Promise<Group[]>;
}
IQueueProvider
Offline message queue contract. Used to enqueue messages for offline users and flush them on reconnect.
interface IQueueProvider {
/** Enqueue a message for an offline user. */
enqueue(userId: string, message: PersistedMessage): Promise<void>;
/** Dequeue and return all pending messages for a user. */
dequeue(userId: string): Promise<PersistedMessage[]>;
/** Optional: called by Sockr to open a connection (e.g. Redis). */
connect?(): Promise<void>;
/** Optional: called by Sockr to close the connection. */
disconnect?(): Promise<void>;
}
ICacheProvider
General-purpose cache contract. Implement for any key-value store.
interface ICacheProvider {
/** Retrieve a cached value by key. Returns null if not found. */
get(key: string): Promise<string | null>;
/** Store a value. Optional TTL in seconds. */
set(key: string, value: string, ttl?: number): Promise<void>;
/** Delete a cached value. */
delete(key: string): Promise<void>;
/** Optional: called by Sockr to open a connection. */
connect?(): Promise<void>;
/** Optional: called by Sockr to close the connection. */
disconnect?(): Promise<void>;
}
connect() and disconnect() methods are called automatically by SocketServer during listen() / initialize() and close(). In-memory implementations can safely omit them.