// Package realtime implements the WebSocket hub: real-time delivery of // conversation events (messages, typing, presence, read receipts). package realtime import ( "encoding/json" "time" ) // Event type constants sent over the wire. const ( EventMessageCreated = "message.created" EventTyping = "typing" EventPresence = "presence" EventRead = "read" ) // Presence status values. const ( StatusOnline = "online" StatusOffline = "offline" ) // MessageCreated is published when a message is stored. type MessageCreated struct { TempID string `json:"temp_id,omitempty"` ConversationID int64 `json:"conversation_id"` MessageID int64 `json:"message_id"` SenderID int64 `json:"sender_id"` Body string `json:"body"` CreatedAt time.Time `json:"created_at"` } // Typing is published when a user starts or stops typing in a conversation. type Typing struct { ConversationID int64 `json:"conversation_id"` UserID int64 `json:"user_id"` IsTyping bool `json:"is_typing"` } // Presence is published when a user comes online or goes offline. type Presence struct { UserID int64 `json:"user_id"` Status string `json:"status"` } // Read is published when a user marks messages in a conversation as read. type Read struct { ConversationID int64 `json:"conversation_id"` UserID int64 `json:"user_id"` MessageID int64 `json:"message_id"` } // envelope is the wire format for every message, both inbound and outbound. type envelope struct { Type string `json:"type"` Data json.RawMessage `json:"data"` } // clientTyping is sent by the client to signal typing state. type clientTyping struct { ConversationID int64 `json:"conversation_id"` IsTyping bool `json:"is_typing"` } // clientRead is sent by the client to mark messages as read. type clientRead struct { ConversationID int64 `json:"conversation_id"` MessageID int64 `json:"message_id"` }