Real-time collaboration

Two people (or two AI agents) on the same grid: presence (who's here and where their cursor is) and live edits (a change in one client appears in every other). SvGrid packages this as a headless controller over a pluggable transport - the only infrastructure-specific piece.

import { createCollaboration, broadcastChannelTransport } from 'sv-grid-community'

const collab = createCollaboration({
  user: { id: myId, name: 'Ada', color: '#ef4444' },
  transport: broadcastChannelTransport('my-grid-room'),
  onPeersChange: (peers) => renderCursors(peers),
  onRemoteEdit: ({ rowId, columnId, value }) => applyEdit(rowId, columnId, value),
})

Wire it to the grid:

<SvGrid {data} {columns} editable getRowId={(r) => r.id}
  onActiveCellChange={(c) => collab.setCell({ rowId: data[c.rowIndex].id, columnId: c.columnId })}
  onCellValueChange={(e) => collab.sendEdit(data[e.rowIndex].id, e.columnId, e.newValue)} />

The transport

The controller is transport-agnostic. It ships with one adapter:

For cross-machine collaboration implement CollabTransport (a post(msg) + subscribe(handler) pair) over a WebSocket, WebRTC datachannel, or a CRDT library:

const wsTransport: CollabTransport = {
  post: (msg) => socket.send(JSON.stringify(msg)),
  subscribe: (h) => { const l = (e) => h(JSON.parse(e.data)); socket.addEventListener('message', l); return () => socket.removeEventListener('message', l) },
}

The controller API

Method Does
setCell(cell | null) Broadcast where your cursor is.
sendEdit(rowId, col, val) Broadcast a cell edit.
peers() Present peers (excludes you), with their cursor.
dispose() Announce leave + tear down (call on unmount).

onPeersChange fires whenever the peer set or any cursor moves; onRemoteEdit fires for edits from other users only (never echoes your own).

Notes

See the live Real-time collaboration demo (open it in two tabs).