[]
        
(Showing Draft Content)

SharedDoc Class

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

Initialization

Initalizing SharedDoc

Properties

Property Name

Description

Types

id

Returns the unique identifier of the shared document.

string (read-only)

version

Indicates the version number of the current snapshot.

`number

type

Indicates the operation type (Operational Transformation type) of the snapshot.

`OT_Type<S, T>

data

Indicates the data of the current snapshot.

`S

connection

Returns the connection object of the shared document.

Connection (read-only)

Methods

fetch

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);
    }
}

subscribe

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);
    }
}

submitOp

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

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);
}

fetchHistorySnapshot

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);

del

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.

hardRollback

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

Destroy the instance and release all resources.

destroy(): void

Events

SharedDoc supports the following events, managed by the on, once, and off methods:

Event Name

Description

Parameters

error

Triggered when an error occurs.

err: OTError object

load

Triggered after retrieving or subscribing to a snapshot.

None

create

Triggered when the document is created.

source: Operation source

beforeOp

Triggered before an operation is applied.

op: Operation data, source: Source

op

Triggered after an operation is applied.

op: Operation data, source: Source

del

Triggered when the document is deleted.

data: Data before deletion, source: Source

hardRollback

Triggered during a forced rollback.

None

on

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);
    }
});

once

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);
});

off

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.

Integration with UI Components

The following figure shows a collaborative process.

sharedoc_class

// 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.