Client API
Complete API reference for the WebSocket client.
createClient()
Create a typed WebSocket client instance.
import { createClient } from '@mdrv/wsx/client'
const client = createClient(url, events, options?)
Parameters
url: string
WebSocket server URL.
const client = createClient('ws://localhost:3000/ws', events)
events: EventDefinitions
Event schema defined with defineEvents(). See Event Definition Guide.
import { defineEvents } from '@mdrv/wsx/shared'
import { z } from 'zod'
const events = defineEvents({
ping: {
request: z.object({ timestamp: z.number() }),
response: z.object({ pong: z.string() }),
},
})
options?: ClientOptions
Optional configuration object:
interface ClientOptions {
// Validation
validate?: boolean // Enable Zod validation (default: true)
serializer?: Serializer // Custom serializer (default: CBOR)
// Request settings
requestTimeout?: number // Default timeout in ms (default: 30000)
debug?: boolean // Enable debug logging (default: false)
// Reconnection settings
maxReconnectionDelay?: number // Max delay between retries (default: 30000)
minReconnectionDelay?: number // Min delay between retries (default: 1000)
reconnectionDelayGrowFactor?: number // Delay growth factor (default: 1.3)
maxRetries?: number // Max retry attempts (default: Infinity)
startClosed?: boolean // Don't auto-connect (default: false)
}
Returns
Returns a TypedClient instance with the following methods and properties.
Connection Methods
connect()
Open the WebSocket connection.
client.connect()
If startClosed: true was set in options, you must call this manually. Otherwise, connection starts automatically.
close(code?, reason?)
Close the WebSocket connection.
client.close()
client.close(1000, 'Normal closure')
Parameters:
code?: number- WebSocket close code (default: 1000)reason?: string- Close reason
Messaging Methods
send(event, payload?)
Send a one-way message to the server (no response expected).
client.send('notify', { message: 'Hello!' })
Parameters:
event: string- Event name (must be defined in events schema)payload?: T- Event payload (validated against schema if validation enabled)
Type Safety:
// ✅ TypeScript knows the payload type
client.send('notify', { message: 'Hello' })
// ❌ TypeScript error: wrong payload type
client.send('notify', { wrong: 'field' })
request(event, payload?, options?)
Send a request and wait for a response.
const response = await client.request('getData', { id: '123' })
Parameters:
event: string- Event namepayload?: T- Request payloadoptions?: RequestOptions- Optional request settings
interface RequestOptions {
timeout?: number // Request timeout in ms (overrides default)
}
Returns: Promise<ResponseType>
Type Safety:
const events = defineEvents({
getData: {
request: z.object({ id: z.string() }),
response: z.object({ name: z.string(), age: z.number() }),
},
})
// ✅ TypeScript knows response.name is string, response.age is number
const response = await client.request('getData', { id: '123' })
console.log(response.name, response.age)
Error Handling:
try {
const response = await client.request('getData', { id: '123' })
} catch (error) {
if (error.message === 'Request timeout') {
// Timeout occurred
} else if (error.cause) {
// Server responded with error
console.error('Server error:', error.message, error.cause)
}
}
Event Listeners
on(event, handler)
Listen for messages from the server.
client.on('notification', (payload) => {
console.log('Received:', payload.message)
})
Parameters:
event: string- Event namehandler: (payload: T) => void- Handler function
Type Safety:
// ✅ TypeScript knows payload type
client.on('notification', (payload) => {
console.log(payload.message) // payload is typed!
})
off(event, handler)
Remove an event listener.
const handler = (payload) => console.log(payload)
client.on('notification', handler)
client.off('notification', handler)
onOpen(handler)
Called when connection is established.
client.onOpen(() => {
console.log('Connected!')
})
onClose(handler)
Called when connection is closed.
client.onClose((event) => {
console.log('Disconnected:', event.code, event.reason)
})
Handler receives: CloseEvent
onError(handler)
Called on connection error.
client.onError((error) => {
console.error('Connection error:', error)
})
Properties
readyState
Current connection state.
const state = client.readyState
// 0 = CONNECTING
// 1 = OPEN
// 2 = CLOSING
// 3 = CLOSED
Complete Example
import { createClient } from '@mdrv/wsx/client'
import { defineEvents } from '@mdrv/wsx/shared'
import { z } from 'zod'
// Define events
const events = defineEvents({
ping: {
request: z.object({ timestamp: z.number() }),
response: z.object({ pong: z.string() }),
},
notify: {
request: z.object({ message: z.string() }),
},
serverMessage: {
request: z.object({ text: z.string() }),
},
})
// Create client
const client = createClient('ws://localhost:3000/ws', events, {
validate: true,
debug: true,
requestTimeout: 5000,
maxRetries: 10,
minReconnectionDelay: 1000,
maxReconnectionDelay: 30000,
})
// Connection events
client.onOpen(async () => {
console.log('Connected!')
// Send request/response
try {
const result = await client.request('ping', {
timestamp: Date.now()
})
console.log('Response:', result.pong)
} catch (error) {
console.error('Request failed:', error)
}
// Send one-way message
client.send('notify', { message: 'Hello from client!' })
})
client.onClose((event) => {
console.log('Disconnected:', event.code, event.reason)
})
client.onError((error) => {
console.error('Error:', error)
})
// Listen for server messages
client.on('serverMessage', (payload) => {
console.log('Server says:', payload.text)
})
// Start connection
client.connect()