ObjectStackObjectStack

Websocket

Websocket protocol schemas

WebSocket Event Protocol

Defines the schema for WebSocket-based real-time communication in ObjectStack. Supports event subscriptions, filtering, presence tracking, and collaborative editing.

Industry alignment: Firebase Realtime Database, Socket.IO, Pusher

⚠️ NOT YET SERVED — this protocol is declared but no WebSocket server is mounted anywhere in the runtime (#2462, #3197): IRealtimeService.handleUpgrade is deliberately unimplemented and discovery advertises websockets: false. These schemas define the future wire contract; nothing consumes them at runtime today.

Source: packages/spec/src/api/websocket.zod.ts

TypeScript Usage

import { AckMessageSchema, CursorMessageSchema, CursorPositionSchema, DocumentStateSchema, EditMessageSchema, EditOperationSchema, EditOperationType, ErrorMessageSchema, EventMessageSchema, EventPatternSchema, EventSubscriptionSchema, PingMessageSchema, PongMessageSchema, PresenceMessageSchema, PresenceStateSchema, PresenceUpdateSchema, SimpleCursorPositionSchema, SimplePresenceStateSchema, SubscribeMessageSchema, UnsubscribeMessageSchema, UnsubscribeRequestSchema, WebSocketConfigSchema, WebSocketEventSchema, WebSocketMessageSchema, WebSocketMessageType, WebSocketPresenceStatus, WebSocketServerConfigSchema } from '@objectstack/spec/api';
import type { AckMessage, CursorMessage, CursorPosition, DocumentState, EditMessage, EditOperation, EditOperationType, ErrorMessage, EventMessage, EventPattern, EventSubscription, PingMessage, PongMessage, PresenceMessage, PresenceState, PresenceUpdate, SimpleCursorPosition, SimplePresenceState, SubscribeMessage, UnsubscribeMessage, UnsubscribeRequest, WebSocketConfig, WebSocketEvent, WebSocketMessage, WebSocketMessageType, WebSocketPresenceStatus, WebSocketServerConfig } from '@objectstack/spec/api';

// Validate data
const result = AckMessageSchema.parse(data);

AckMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'ack'
timestampstringISO 8601 datetime when message was sent
ackMessageIdstringID of the message being acknowledged
successbooleanWhether the operation was successful
errorstringoptionalError message if operation failed

CursorMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'cursor'
timestampstringISO 8601 datetime when message was sent
cursor{ userId: string; sessionId: string; documentId: string; position?: object; … }Cursor position

CursorPosition

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
documentIdstringDocument identifier being edited
position{ line: integer; column: integer }optionalCursor position in document
selection{ start: object; end: object }optionalSelection range (if text is selected)
colorstringoptionalCursor color for visual representation
userNamestringoptionalDisplay name of user
lastUpdatestringISO 8601 datetime of last cursor update

DocumentState

Properties

PropertyTypeRequiredDescription
documentIdstringDocument identifier
versionintegerCurrent document version
contentstringCurrent document content
lastModifiedstringISO 8601 datetime of last modification
activeSessionsstring[]Active editing session IDs
checksumstringoptionalContent checksum for integrity verification

EditMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'edit'
timestampstringISO 8601 datetime when message was sent
operation{ operationId: string; documentId: string; userId: string; sessionId: string; … }Edit operation

EditOperation

Properties

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
documentIdstringDocument identifier
userIdstringUser who performed the edit
sessionIdstringSession identifier
typeEnum<'insert' | 'delete' | 'replace'>Type of edit operation
position{ line: integer; column: integer }Starting position of the operation
endPosition{ line: integer; column: integer }optionalEnding position (for delete/replace operations)
contentstringoptionalContent to insert/replace
versionintegerDocument version before this operation
timestampstringISO 8601 datetime when operation was created
baseOperationIdstringoptionalPrevious operation ID this builds upon (for OT)

EditOperationType

Allowed Values

  • insert
  • delete
  • replace

ErrorMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'error'
timestampstringISO 8601 datetime when message was sent
codestringError code
messagestringError message
detailsanyoptionalAdditional error details

EventMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'event'
timestampstringISO 8601 datetime when message was sent
subscriptionIdstringSubscription ID this event belongs to
eventNamestringEvent name
objectstringoptionalObject name the event relates to
payloadanyEvent payload data
userIdstringoptionalUser who triggered the event

EventPattern

Event pattern (supports wildcards like "record." or ".created")

Type: string


EventSubscription

Properties

PropertyTypeRequiredDescription
subscriptionIdstringUnique subscription identifier
eventsstring[]Event patterns to subscribe to (supports wildcards, e.g., "record.*", "user.created")
objectsstring[]optionalObject names to filter events by (e.g., ["account", "contact"])
filtersanyoptionalFilter conditions for event payloads (not yet enforced — the runtime filters by object name and event type only)
channelsstring[]optionalChannel names for scoped subscriptions

PingMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'ping'
timestampstringISO 8601 datetime when message was sent

PongMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'pong'
timestampstringISO 8601 datetime when message was sent
pingMessageIdstringoptionalID of ping message being responded to

PresenceMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'presence'
timestampstringISO 8601 datetime when message was sent
presence{ userId: string; sessionId: string; status: Enum<'online' | 'away' | 'busy' | 'offline'>; lastSeen: string; … }Presence state

PresenceState

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringUnique session identifier
statusEnum<'online' | 'away' | 'busy' | 'offline'>Current presence status
lastSeenstringISO 8601 datetime of last activity
currentLocationstringoptionalCurrent page/route user is viewing
deviceEnum<'desktop' | 'mobile' | 'tablet' | 'other'>optionalDevice type
customStatusstringoptionalCustom user status message
metadataRecord<string, any>optionalAdditional custom presence data

PresenceUpdate

Properties

PropertyTypeRequiredDescription
statusEnum<'online' | 'away' | 'busy' | 'offline'>optionalUpdated presence status
currentLocationstringoptionalUpdated current location
customStatusstringoptionalUpdated custom status message
metadataRecord<string, any>optionalUpdated metadata

SimpleCursorPosition

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
recordIdstringRecord identifier being edited
fieldNamestringField name being edited
positionnumberCursor position (character offset from start)
selection{ start: number; end: number }optionalText selection range (if text is selected)

SimplePresenceState

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
userNamestringUser display name
statusEnum<'online' | 'away' | 'offline'>User presence status
lastSeennumberUnix timestamp of last activity in milliseconds
metadataRecord<string, any>optionalAdditional presence metadata (e.g., current page, custom status)

SubscribeMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'subscribe'
timestampstringISO 8601 datetime when message was sent
subscription{ subscriptionId: string; events: string[]; objects?: string[]; filters?: any; … }Subscription configuration

UnsubscribeMessage

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'unsubscribe'
timestampstringISO 8601 datetime when message was sent
request{ subscriptionId: string }Unsubscribe request

UnsubscribeRequest

Properties

PropertyTypeRequiredDescription
subscriptionIdstringSubscription ID to unsubscribe from

WebSocketConfig

Properties

PropertyTypeRequiredDescription
urlstringWebSocket server URL
protocolsstring[]optionalWebSocket sub-protocols
reconnectbooleanEnable automatic reconnection
reconnectIntervalintegerReconnection interval in milliseconds
maxReconnectAttemptsintegerMaximum reconnection attempts
pingIntervalintegerPing interval in milliseconds
timeoutintegerMessage timeout in milliseconds
headersRecord<string, string>optionalCustom headers for WebSocket handshake

WebSocketEvent

Properties

PropertyTypeRequiredDescription
typeEnum<'subscribe' | 'unsubscribe' | 'data-change' | 'presence-update' | 'cursor-update' | 'error'>Event type
channelstringChannel identifier (e.g., "record.account.123", "user.456")
payloadanyEvent payload data
timestampnumberUnix timestamp in milliseconds

WebSocketMessage

Union Options

This schema accepts one of the following structures:

Option 1

Type: subscribe

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'subscribe'
timestampstringISO 8601 datetime when message was sent
subscription{ subscriptionId: string; events: string[]; objects?: string[]; filters?: any; … }Subscription configuration

Option 2

Type: unsubscribe

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'unsubscribe'
timestampstringISO 8601 datetime when message was sent
request{ subscriptionId: string }Unsubscribe request

Option 3

Type: event

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'event'
timestampstringISO 8601 datetime when message was sent
subscriptionIdstringSubscription ID this event belongs to
eventNamestringEvent name
objectstringoptionalObject name the event relates to
payloadanyEvent payload data
userIdstringoptionalUser who triggered the event

Option 4

Type: presence

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'presence'
timestampstringISO 8601 datetime when message was sent
presence{ userId: string; sessionId: string; status: Enum<'online' | 'away' | 'busy' | 'offline'>; lastSeen: string; … }Presence state

Option 5

Type: cursor

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'cursor'
timestampstringISO 8601 datetime when message was sent
cursor{ userId: string; sessionId: string; documentId: string; position?: object; … }Cursor position

Option 6

Type: edit

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'edit'
timestampstringISO 8601 datetime when message was sent
operation{ operationId: string; documentId: string; userId: string; sessionId: string; … }Edit operation

Option 7

Type: ack

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'ack'
timestampstringISO 8601 datetime when message was sent
ackMessageIdstringID of the message being acknowledged
successbooleanWhether the operation was successful
errorstringoptionalError message if operation failed

Option 8

Type: error

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'error'
timestampstringISO 8601 datetime when message was sent
codestringError code
messagestringError message
detailsanyoptionalAdditional error details

Option 9

Type: ping

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'ping'
timestampstringISO 8601 datetime when message was sent

Option 10

Type: pong

Properties

PropertyTypeRequiredDescription
messageIdstringUnique message identifier
type'pong'
timestampstringISO 8601 datetime when message was sent
pingMessageIdstringoptionalID of ping message being responded to


WebSocketMessageType

Allowed Values

  • subscribe
  • unsubscribe
  • event
  • ping
  • pong
  • ack
  • error
  • presence
  • cursor
  • edit

WebSocketPresenceStatus

Allowed Values

  • online
  • away
  • busy
  • offline

WebSocketServerConfig

Properties

PropertyTypeRequiredDescription
enabledbooleanEnable WebSocket server
pathstringWebSocket endpoint path
heartbeatIntervalnumberHeartbeat interval in milliseconds
reconnectAttemptsnumberMaximum reconnection attempts for clients
presencebooleanEnable presence tracking
cursorSharingbooleanEnable collaborative cursor sharing

On this page