Skip to Content
Collaborative Editing

Collaborative Editing Tools

Multiple users edit the same document while receiving immediate updates.

Core pattern

  • SHARED table for canonical document operations
  • STREAM table for cursor/presence heartbeat
  • live subscriptions for low-latency co-editing
  • optional worker for conflict normalization/versioning

Example schema

sql snippetSQL
CREATE TABLE docs.document_ops (  op_id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),  doc_id TEXT NOT NULL,  user_id TEXT NOT NULL,  op_type TEXT NOT NULL,  payload JSON NOT NULL,  created_at TIMESTAMP DEFAULT NOW()) WITH (TYPE = 'SHARED', FLUSH_POLICY = 'interval:30'); CREATE TABLE docs.presence (  id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),  doc_id TEXT NOT NULL,  user_id TEXT,  cursor_position INT,  last_seen TIMESTAMP DEFAULT NOW()) WITH (TYPE = 'STREAM', TTL_SECONDS = 5);

Example implementation

typescript snippettypescript
const escapedDocId = String(docId).replace(/'/g, "''");await client.liveEvents(  `SELECT * FROM docs.document_ops WHERE doc_id = '${escapedDocId}'`,  (event) => {    if (event.type === 'initial_data_batch' && event.rows) {      rebuildDocument(event.rows);    }    if (event.type === 'change' && event.change_type === 'insert') {      applyRemoteOps(event.rows);    }  },  { batchSize: 500 }); await client.query(  'INSERT INTO docs.document_ops (doc_id, user_id, op_type, payload) VALUES ($1, $2, $3, $4)',  [docId, userId, 'insert', JSON.stringify(op)]);

Code references

Last updated on