@roomkit/client
v1.3.1
Published
Client SDK for Gateway-Worker Framework - Colyseus-inspired TypeScript SDK
Maintainers
Readme
@roomkit/client
Client SDK for Gateway-Worker Framework - A TypeScript SDK inspired by Colyseus.
Features
- 🎯 Colyseus-inspired API - Familiar and intuitive for game developers
- 🔐 Type-safe - Full TypeScript support with generics
- 🔌 WebSocket-based - Real-time bidirectional communication
- 🔄 Auto-reconnection - Configurable reconnection strategy
- ❤️ Heartbeat - Automatic connection health monitoring
- 🎮 Room abstraction - Easy room management and state synchronization
- 📦 Lightweight - Minimal dependencies
Installation
pnpm add @roomkit/clientQuick Start
1. Create a Client
import { Client } from '@roomkit/client';
const client = new Client('ws://localhost:27100/ws', {
autoReconnect: true,
reconnectDelay: 1000,
maxReconnectAttempts: 10,
});2. Authenticate
await client.auth('your-auth-token');
console.log('Authenticated as:', client.userId);3. Join or Create a Room
interface GameState {
players: { [id: string]: PlayerData };
gameStatus: 'waiting' | 'playing' | 'finished';
}
const room = await client.joinOrCreate<GameState>('my-game', {
maxPlayers: 4,
});
console.log('Joined room:', room.id);4. Listen to State Changes
room.onStateChange((state) => {
console.log('State updated:', state);
// Update your UI based on new state
});5. Listen to Messages
// Listen to specific message types
room.onMessage('player_joined', (message) => {
console.log('New player:', message);
});
// Listen to game events
room.onMessage('game_started', (message) => {
console.log('Game started!');
});6. Send Messages
// Send game actions
room.send('player_action', {
type: 'move',
x: 100,
y: 200,
});
// Request with response
const result = await room.request('make_move', {
position: 5,
});
console.log('Move result:', result);7. Leave Room
await room.leave();API Reference
Client
Constructor
new Client(url: string, options?: ClientOptions)Options:
autoReconnect?: boolean- Auto-reconnect on disconnect (default:true)reconnectDelay?: number- Delay between reconnection attempts in ms (default:1000)maxReconnectAttempts?: number- Maximum reconnection attempts (default:10)requestTimeout?: number- Request timeout in ms (default:10000)heartbeatInterval?: number- Heartbeat interval in ms (default:20000)
Methods
async auth(token: string): Promise<void>
Authenticate with the server.
async create<State>(roomName: string, options?: RoomOptions): Promise<Room<State>>
Create a new room.
async join<State>(roomId: string, options?: RoomOptions): Promise<Room<State>>
Join an existing room.
async joinOrCreate<State>(roomName: string, options?: RoomOptions): Promise<Room<State>>
Join an existing room or create a new one (recommended).
async getAvailableRooms(roomName?: string): Promise<AvailableRoom[]>
Get list of available rooms.
disconnect(): void
Disconnect from the server.
Properties
state: ConnectionState- Current connection stateuserId: string | null- Current user ID (after auth)isConnected: boolean- Whether client is connectedisAuthenticated: boolean- Whether client is authenticated
Room
Properties
id: string- Room IDsessionId: string- Session IDname: string- Room namestate: State | null- Current room state
Methods
onStateChange(callback: (state: State) => void): () => void
Listen to state changes. Returns an unsubscribe function.
onJoin(callback: () => void): () => void
Listen to room join event.
onLeave(callback: (code: number) => void): () => void
Listen to room leave event.
onError(callback: (code: number, message: string) => void): () => void
Listen to error events.
onMessage<T>(type: number | string, callback: (message: T) => void): () => void
Listen to custom messages.
send(type: number | string, message?: any): void
Send a message to the room.
async request<T>(type: number | string, message?: any): Promise<T>
Send a request and wait for response.
async leave(consented?: boolean): Promise<void>
Leave the room.
Examples
Basic Game Client
import { Client } from '@roomkit/client';
class GameClient {
private client: Client;
private room: Room | null = null;
constructor() {
this.client = new Client('ws://localhost:27100/ws');
}
async connect(token: string) {
await this.client.auth(token);
}
async joinGame(gameType: string) {
this.room = await this.client.joinOrCreate(gameType);
this.room.onStateChange((state) => {
this.onStateUpdate(state);
});
this.room.onMessage('game_event', (event) => {
this.onGameEvent(event);
});
this.room.onLeave(() => {
console.log('Left room');
this.room = null;
});
}
async sendAction(action: any) {
if (this.room) {
this.room.send('player_action', action);
}
}
private onStateUpdate(state: any) {
// Update UI
}
private onGameEvent(event: any) {
// Handle game events
}
}Chat Client Example
See examples/simple-chat-client.ts for a complete example.
Type Safety
The SDK provides full TypeScript support:
interface MyGameState {
round: number;
players: {
id: string;
score: number;
ready: boolean;
}[];
}
const room = await client.joinOrCreate<MyGameState>('my-game');
// state is typed as MyGameState
room.onStateChange((state) => {
console.log(state.round); // TypeScript knows this exists
console.log(state.players); // Fully typed
});Advanced Usage
Custom Message IDs
import { MessageId } from '@roomkit/client';
// Use predefined message IDs
room.send(MessageId.PLAYER_READY, { ready: true });
// Or use custom string types (auto-hashed)
room.send('my_custom_action', { data: 'value' });Connection State Monitoring
client.onStateChange((state) => {
console.log('Connection state:', state);
// 'disconnected' | 'connecting' | 'connected' | 'authenticated'
});Error Handling
room.onError((code, message) => {
console.error(`Room error ${code}:`, message);
});
try {
await room.leave();
} catch (error) {
console.error('Failed to leave room:', error);
}License
MIT
