feat: notify document updates over websocket

This commit is contained in:
2026-04-29 09:14:49 -04:00
parent 9b8f2968e8
commit 6e244d55db
12 changed files with 358 additions and 19 deletions

View File

@@ -0,0 +1,70 @@
package realtime
import (
"encoding/json"
"log/slog"
"sync"
)
type Event struct {
Type string `json:"type"`
Data any `json:"data"`
}
type Client struct {
send chan []byte
}
type Hub struct {
logger *slog.Logger
mu sync.RWMutex
clients map[*Client]struct{}
}
func NewHub(logger *slog.Logger) *Hub {
return &Hub{
logger: logger,
clients: make(map[*Client]struct{}),
}
}
func (h *Hub) NewClient(buffer int) *Client {
return &Client{send: make(chan []byte, buffer)}
}
func (h *Hub) Register(client *Client) {
h.mu.Lock()
defer h.mu.Unlock()
h.clients[client] = struct{}{}
}
func (h *Hub) Unregister(client *Client) {
h.mu.Lock()
defer h.mu.Unlock()
if _, ok := h.clients[client]; ok {
delete(h.clients, client)
close(client.send)
}
}
func (h *Hub) Broadcast(event Event) {
payload, err := json.Marshal(event)
if err != nil {
h.logger.Error("marshal realtime event", "error", err)
return
}
h.mu.RLock()
defer h.mu.RUnlock()
for client := range h.clients {
select {
case client.send <- payload:
default:
h.logger.Warn("dropping realtime event for slow client")
}
}
}
func (c *Client) Send() <-chan []byte {
return c.send
}