[]
SharedDoc represents a shared document instance, used to manage document snapshots (snapshot) and operations (op), synchronizing data with the server through a connection (Connection). It supports the Operational Transformation (OT) mechanism to ensure consistency of multi-user operations. This document explains how to use SharedDoc on the client side, including:
Initialize SharedDoc
Create or delete documents
Request and update document snapshots
Submit, receive, and transform operations
Listen for events
Property Name | Description | Types |
|---|---|---|
| Returns the unique identifier of the shared document. |
|
| Indicates the version number of the current snapshot. | `number |
| Indicates the operation type (Operational Transformation type) of the snapshot. | `OT_Type<S, T> |
| Indicates the data of the current snapshot. | `S |
| Returns the connection object of the shared document. |
|
Retrieve the document's snapshot data, with the result stored in doc.data.
fetch(): Promise<void>Return
Promise<void>: Returns a promise that resolves after the snapshot is fetched, the fetched snapshot data is 'doc.data'.
Example
try {
await doc.fetch();
if (!doc.type) {
return console.log('Document does not exist');
}
console.log('Document snapshot', doc.data);
} catch (error) {
if (error) {
return console.error(error);
}
}Retrieve the document's snapshot data and listen for subsequent updates.
subscribe(): Promise<void>Return
Promise<void>: Returns a promise that resolves after the snapshot is subscribed, the subscribed snapshot data is 'doc.data'.
Example
try {
await doc.subscribe();
if (!doc.type) {
return console.log('Document does not exist');
}
console.log('Document snapshot', doc.data);
doc.on('op', (op, source) => {
console.log('Document updated', op, source);
});
} catch (error) {
if (error) {
return console.error(error);
}
}Submit an operation to the document.
submitOp(component: T, options?: IOptions): Promise<void>Parameters
component (T): The op component.
options (IOptions): Options for the operation (optional).
Return
Promise<void> : Returns a promise that resolves after the op is submitted.
Example
// Insert text 'x' at position 1
await doc.submitOp({ pos: 1, text: 'Hi' }, { source: doc.connection.id });
console.log('Operation submitted');Create a new document.
create(data: S, type: string, options: IOptions): Promise<void>Parameters
data (S): The data used to initialize the snapshot.
type (string): The URI of the OT type.
options (IOptions): Options for the operation.
Return
Promise<void>: Returns a promise that resolves after the document is created.
Example
try {
await doc.create('Hello', textType.uri, {});
console.log('Document created successfully:', doc.data); // "Hello"
} catch (err) {
console.error('Creation failed:', err);
}Retrieve historical snapshot data of the document.
fetchHistorySnapshot(options: IHistorySnapshotRequestOptions): Promise<ISnapshot<S>>Parameter
options (IHistorySnapshotRequestOptions): Historical snapshot request options.
Return
Promise<ISnapshot<S>>: Returns a promise that resolves after the history snapshot is fetched.
Example
const snapshot = await doc.fetchHistorySnapshot({ version: 6 }, textType.uri, {});
console.log('Document created successfully, snapshot :', snapshot);Delete the document.
del(options: IOptions): Promise<void>Parameter
options (IOptions): Deletion options.
Return
Promise<void>: Returns a promise that resolves after the document is deleted.
Forcefully rollback the snapshot data to the latest version.
hardRollback(): Promise<void>Return
Promise<void>: Returns a promise that resolves when the rollback is complete.
Destroy the instance and release all resources.
destroy(): voidSharedDoc supports the following events, managed by the on, once, and off methods:
Event Name | Description | Parameters |
|---|---|---|
| Triggered when an error occurs. |
|
| Triggered after retrieving or subscribing to a snapshot. | None |
| Triggered when the document is created. |
|
| Triggered before an operation is applied. |
|
| Triggered after an operation is applied. |
|
| Triggered when the document is deleted. |
|
| Triggered during a forced rollback. | None |
Register an event listener.
on<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): ISharedDocEvents<S, T>[NAME];Parameters
name (NAME): Event name, must be a key in the ISharedDocEvents<S, T> interface.
f (ISharedDocEvents<S, T>[NAME]): Event handler function.
Return
ISharedDocEvents<S, T>[NAME]: The registered event handler.
Example
doc.on('op', (op, source) => {
if (source !== doc.connection.id) {
console.log('receive op from server:', op);
}
});Register an event listener that triggers only once.
once<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): void;Parameters
name (NAME): Event name.
f (ISharedDocEvents<S, T>[NAME]): Event handler function.
Example
doc.once('op', (op, source) => {
console.log('op', op, source);
});Remove a specific event listener.
off<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): void;Parameters
name (NAME): Event name.
f (ISharedDocEvents<S, T>[NAME]): Event handler function to remove.
The following figure shows a collaborative process.

// Initialize the UI component. xxx.uiComponent is fictional and should be replaced with an actual UI component implementation, such as Quill or others.
const uiComponent = new xxx.uiComponent();
// Subscribe to the document
doc.subscribe().then(async () => {
// Create the document if it does not exist
if (!doc.type) {
try {
await doc.create('Hello', textType.uri, {});
console.log('Created successfully:', doc.data);
} catch (error) {
console.error('Creation failed:', error);
return;
}
}
uiComponent.setText(doc.data);
// Listen for operations
doc.on('op', (op, source) => {
if (source === doc.connection.id) {
return;
}
console.log('Received operation:', op, 'Current data:', doc.data);
uiComponent.applyOp(op.pos, op.text); // Prefer incremental updates
// Or uiComponent.setText(doc.data); // Full update
});
// Listen for UI component operations and submit to the server
uiComponent.on('op', (op) => {
await doc.submitOp(op, { source: doc.connection.id });
});
})Try to build a real-time collaborative text editor: Tutorial: Real-Time Collaborative Text Editor.