Collaborative editor integration
The collaborative editor uses CollabSession from @modula/editor plus a signaling endpoint.
Runtime responsibilities
CollabSession handles:
- Peer discovery/presence.
- Soft block locks.
- Signal fanout for lock/unlock/transaction/version events.
- WebRTC negotiation (
offer,answer,ice-candidate) and DataChannel messaging.
Server endpoint contract
Default route pattern in Modula REST:
GET /api/collab/:ref_id/signal?peer_id=<uuid>&held_locks=id1,id2POST /api/collab/:ref_id/signalDELETE /api/collab/:ref_id/signal?peer_id=<uuid>
GET returns:
{
"peers": {
"peer-id": { "userId": "u1", "name": "Alice", "image": null }
},
"signals": [
{ "id": "s1", "from": "peer-id", "type": "transaction", "data": [] }
],
"locks": {
"block-id": { "peerId": "peer-id", "userId": "u1", "name": "Alice", "image": null }
}
} Client integration
import { CollabSession, setCollabSessionContext } from '@modula/editor';
const session = new CollabSession(`/api/collab/${refId}/signal`).start();
setCollabSessionContext(session);
// Keep state aligned with remote operations.
session.on('transaction', (ops) => {
editorState.apply(...ops);
});
// Optional: version reconciliation.
session.on('version', (versionId) => {
console.info('Remote version', versionId);
}); On teardown:
await session.destroy(); Wiring locks in UI
Form already consumes collab context and applies lock semantics:
- On focus: lock current block (
collab.lock(block.id)). - On blur: unlock block (
collab.unlock(block.id)). - Remote locks disable editing and can display lock badges.
Suggested save + version flow
- User applies local edits (transactions).
- Broadcast operations via
session.transaction(tx). - Save snapshot to backend.
- Broadcast canonical version id via
session.setVersion(versionId).
This pattern reduces divergence and gives peers a stable synchronization boundary.
Notes
- Locks are soft, TTL-based (presence heartbeat refreshes them).
- Collaboration authorization is enforced server-side per
ref_id. - If collaboration is unavailable, set collab context to
nulland keep editor in local mode.