My App
BoardKitCore

Collaboration Protocol

Typed WebSocket messages for realtime collaboration

The collaboration protocol defines all Socket.IO messages exchanged between client and server. All message types are exported from @hfu.digital/boardkit-core and used by both @hfu.digital/boardkit-nestjs (server) and @hfu.digital/boardkit-react (client).

import { PROTOCOL_VERSION } from '@hfu.digital/boardkit-core';
// PROTOCOL_VERSION = 1

Client Messages (Client → Server)

type ClientMessage =
    | JoinMessage
    | LeaveMessage
    | MutateMessage
    | CursorMessage
    | PageSwitchMessage
    | PingMessage;

JoinMessage

Sent when a client connects to a board session.

interface JoinMessage {
    type: 'join';
    boardId: string;
    token: string;
    lastSequence?: number;  // for reconnection delta sync
}

LeaveMessage

interface LeaveMessage {
    type: 'leave';
}

MutateMessage

Sends element mutations to the server.

interface MutateMessage {
    type: 'mutate';
    mutations: ElementMutation[];
    requestId: string;  // for matching ack responses
}

CursorMessage

Broadcasts cursor position to other participants.

interface CursorMessage {
    type: 'cursor';
    position: Point;
    pageId: string;
}

PageSwitchMessage

interface PageSwitchMessage {
    type: 'pageSwitch';
    pageId: string;
}

PingMessage

interface PingMessage {
    type: 'ping';
    timestamp: number;
}

Server Messages (Server → Client)

type ServerMessage =
    | JoinedMessage
    | SyncDeltaMessage
    | SyncFullMessage
    | MutationAckMessage
    | MutationBroadcastMessage
    | CursorBroadcastMessage
    | ParticipantJoinedMessage
    | ParticipantLeftMessage
    | RateLimitedMessage
    | ErrorMessage
    | PongMessage;

JoinedMessage

Confirms successful join with the current participant list.

interface JoinedMessage {
    type: 'joined';
    userId: string;
    boardId: string;
    participants: Array<{
        userId: string;
        displayName: string;
        color: string;
    }>;
    currentSequence: number;
}

SyncDeltaMessage

Delivers missed mutations since the client's lastSequence (used for reconnection).

interface SyncDeltaMessage {
    type: 'sync:delta';
    mutations: ElementMutation[];
    fromSequence: number;
    toSequence: number;
}

SyncFullMessage

Delivers the complete board state (used when delta sync is not possible or on first join).

interface SyncFullMessage {
    type: 'sync:full';
    boardData: Record<string, unknown>;
    currentSequence: number;
}

MutationAckMessage

Acknowledges a client's mutation request.

interface MutationAckMessage {
    type: 'mutation:ack';
    requestId: string;
    sequence: number;
}

MutationBroadcastMessage

Broadcasts another client's mutations to all other participants.

interface MutationBroadcastMessage {
    type: 'mutation:broadcast';
    userId: string;
    mutations: ElementMutation[];
    sequence: number;
}

CursorBroadcastMessage

interface CursorBroadcastMessage {
    type: 'cursor:broadcast';
    userId: string;
    position: Point;
    pageId: string;
}

ParticipantJoinedMessage / ParticipantLeftMessage

interface ParticipantJoinedMessage {
    type: 'participant:joined';
    userId: string;
    displayName: string;
    color: string;
}

interface ParticipantLeftMessage {
    type: 'participant:left';
    userId: string;
}

RateLimitedMessage

interface RateLimitedMessage {
    type: 'rate-limited';
    retryAfterMs: number;
}

ErrorMessage

interface ErrorMessage {
    type: 'error';
    code: string;
    message: string;
}

Common error codes: AUTH_FAILED, FORBIDDEN, SESSION_MISMATCH.

PongMessage

interface PongMessage {
    type: 'pong';
    timestamp: number;
    serverTime: number;
}

Message Flow Diagram

Client A                  Server                  Client B
   │                        │                        │
   ├── join ────────────────►                        │
   │                        ├── joined ──────────────►
   ◄── joined ──────────────┤                        │
   ◄── sync:full ───────────┤                        │
   │                        │                        │
   ├── mutate ──────────────►                        │
   ◄── mutation:ack ────────┤                        │
   │                        ├── mutation:broadcast ──►
   │                        │                        │
   ├── cursor ──────────────►                        │
   │                        ├── cursor:broadcast ────►
   │                        │                        │

On this page