principletypescriptTip
Operational Transform Requires Server-Side Operation Sequencing
Viewed 0 times
operational transformOTShareDBconcurrent editingconflict resolutionrevision numberdocument sync
Problem
Two clients concurrently edit the same document position. Without coordination, applying both edits produces corrupted text because each operation was designed against a different document state.
Solution
OT uses a transform function that adjusts the position/content of a concurrent operation so it can be applied after another operation has already been applied. A central server serializes all operations and assigns revision numbers.
interface InsertOp {
type: 'insert';
position: number;
text: string;
revision: number;
clientId: string;
}
// Server: transforms incoming op against all ops since client's revision
function transformAgainst(incoming: InsertOp, applied: InsertOp): InsertOp {
if (applied.position <= incoming.position) {
return { ...incoming, position: incoming.position + applied.text.length };
}
return incoming;
}
// Server applies and broadcasts the transformed op
function receiveOp(incoming: InsertOp, history: InsertOp[]): InsertOp {
const concurrent = history.filter(op => op.revision >= incoming.revision);
return concurrent.reduce(transformAgainst, incoming);
}Why
OT was designed for centralized architectures like Google Docs. The server is the single source of truth for operation order, which makes the transform function simpler but creates a hard dependency on server availability.
Gotchas
- OT correctness proofs are notoriously complex — prefer battle-tested libraries over DIY implementations.
- The transformation function must satisfy the convergence property (TP1) and optionally the undo property (TP2).
- OT works poorly in peer-to-peer topologies without a central sequencer — use CRDTs instead.
- ShareDB is the most mature OT library for Node.js; it uses JSON0 OT type.
Revisions (0)
No revisions yet.