Changeset library incorporating an operational transformation (OT) algorithm - for node and the browser, with shareJS support
The changesets package implements an Operational Transformation (OT) algorithm for managing concurrent edits to text documents. Unlike version control systems that work on full document snapshots, OT enables real-time collaborative editing by transforming operations so they can be applied in different orders while maintaining consistency. This package provides the core primitives for building collaborative text editors, supporting both Node.js and browser environments.
Operational Transformation solves the challenge of concurrent editing where multiple users modify the same document simultaneously. When User A inserts text at position 5 while User B deletes characters at position 3, their operations must be transformed relative to each other to maintain document integrity. The changesets library handles these transformations through retain, insert, and skip operations that can be composed, inverted, and transformed according to OT theory.
This package is designed for developers building collaborative applications like shared document editors, code collaboration tools, or any system requiring conflict-free concurrent text modifications. It includes support for ShareJS, a popular real-time collaboration framework, making it suitable for production collaborative editing systems. The library handles the mathematical complexity of OT algorithms including Forward Transformation, Backward Transformation, Inclusion Transformation, and Exclusion Transformation.
While this package shares a name with the more popular @changesets/cli monorepo versioning tool, it serves an entirely different purpose focused on text editing operations rather than package management. It's a specialized library for developers who need low-level control over collaborative text editing without implementing OT algorithms from scratch.
const Changeset = require('changesets');
// Create a changeset representing text operations
// Document: "Hello World"
const cs1 = new Changeset()
.retain(6) // Keep "Hello "
.insert('Beautiful ') // Insert new text
.retain(5); // Keep "World"
// Another user's concurrent changeset
const cs2 = new Changeset()
.retain(11) // Keep "Hello World"
.insert('!'); // Add exclamation
// Apply first changeset
let doc = "Hello World";
doc = cs1.apply(doc);
console.log(doc); // "Hello Beautiful World"
// Transform cs2 against cs1 to handle concurrent edit
const cs2Transformed = cs2.transform(cs1, 'right');
doc = cs2Transformed.apply(doc);
console.log(doc); // "Hello Beautiful World!"
// Create inverse for undo functionality
const inverseCs1 = cs1.invert("Hello World");
let undone = inverseCs1.apply("Hello Beautiful World");
console.log(undone); // "Hello World"
// Compose multiple changesets into one
const cs3 = new Changeset().retain(5).insert(' there');
const composed = cs1.compose(cs3);
console.log(composed.apply("Hello World")); // "Hello there Beautiful World"Real-time collaborative text editors: Build Google Docs-style editors where multiple users edit simultaneously. The package transforms each user's operations so all clients converge to the same document state regardless of network latency or operation order.
Collaborative code editing: Implement pair programming tools or collaborative IDEs where developers work on the same file. The OT algorithm ensures syntax remains valid by correctly handling simultaneous insertions and deletions at nearby positions.
Undo/redo systems: Create robust undo functionality in collaborative contexts where other users' changes have occurred since your last action. The library's inversion operations allow reversing changes while accounting for intervening edits.
Conflict-free synchronization: Build offline-first applications that sync text changes between devices. Operations can be queued locally and transformed against server operations when connectivity returns, maintaining consistency without overwriting changes.
Change tracking and diff generation: Generate meaningful diffs between document versions by composing changesets over time. This enables features like revision history, blame annotations, or audit trails in collaborative document systems.
npm install changesetspnpm add changesetsbun add changesets