[]
SharedDoc は共有ドキュメントインスタンスを表し、ドキュメントのスナップショット(snapshot)とオペレーション(op)を管理し、接続(Connection)を介してサーバーとデータを同期します。複数ユーザーのオペレーションの整合性を確保するために、Operational Transformation(OT,操作变换)メカニズムをサポートします。このドキュメントでは、クライアント側で SharedDoc を使用する方法を説明します。内容は次のとおりです。
SharedDoc を初期化する
ドキュメントを作成または削除する
ドキュメントのスナップショットを要求し、更新する
オペレーションを送信、受信、変換する
イベントを監視する
プロパティ名 | 説明 | 型 |
|---|---|---|
| 共有ドキュメントの一意な識別子を返します。 |
|
| 現在のスナップショットのバージョン番号を示します。 |
|
| スナップショットのオペレーションタイプ(Operational Transformation タイプ)を示します。 |
|
| 現在のスナップショットのデータを示します。 |
|
| 共有ドキュメントの connection オブジェクトを返します。 |
|
ドキュメントのスナップショットデータを取得し、結果を doc.data に格納します。
fetch(): Promise<void>戻り値
Promise<void>: スナップショットの取得が完了すると解決される Promise を返します。取得したスナップショットデータは doc.data に格納されます。
例
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(): Promise<void>戻り値
Promise<void>: スナップショットのサブスクライブ後に解決される Promise を返します。取得したスナップショットデータは doc.data に格納されます。
例
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(component: T, options?: IOptions): Promise<void>パラメータ
component (T): オペレーション(op)を構成するコンポーネントです。
options (IOptions): オペレーションのオプションです(任意)。
戻り値
Promise<void> : op の送信後に解決される Promise を返します。
例
// 位置 1 にテキスト 'Hi' を挿入
await doc.submitOp({ pos: 1, text: 'Hi' }, { source: doc.connection.id });
console.log('Operation submitted');新しいドキュメントを作成します。
create(data: S, type: string, options: IOptions): Promise<void>パラメータ
data (S): スナップショットの初期化に使用するデータです。
type (string): OT タイプの URI です。
options (IOptions): オペレーションのオプションです。
戻り値
Promise<void>: ドキュメントの作成後に解決される Promise を返します。
例
try {
await doc.create('Hello', textType.uri, {});
console.log('Document created successfully:', doc.data); // "Hello"
} catch (err) {
console.error('Creation failed:', err);
}ドキュメントの履歴スナップショットデータを取得します。
fetchHistorySnapshot(options: IHistorySnapshotRequestOptions): Promise<ISnapshot<S>>パラメータ
options (IHistorySnapshotRequestOptions): 履歴スナップショットのリクエストオプションです。
戻り値
Promise<ISnapshot<S>>: 履歴スナップショットの取得後に解決される Promise を返します。
例
const snapshot = await doc.fetchHistorySnapshot({ version: 6 }, textType.uri, {});
console.log('Document created successfully, snapshot :', snapshot);ドキュメントを削除します。
del(options: IOptions): Promise<void>パラメータ
options (IOptions): 削除オプションです。
戻り値
Promise<void>: ドキュメントの削除後に解決されるPromiseを返します。
ドキュメントを特定のバージョンに復元します。
restore(targetVersion: number, options?: IOptions): Promise<void>;パラメータ
targetVersion (number): 復元先のターゲットバージョン番号です。
options (IOptions): 復元オプションです。
戻り値
Promise<void>: ドキュメントの復元後に解決されるPromiseを返します。
例
await doc.restore(10);
console.log('Document restored successfully:', doc.data); // バージョン 10 のデータスナップショットデータを強制的に最新バージョンへロールバックします。
hardRollback(): Promise<void>戻り値
Promise<void>: ロールバックが完了した時点で解決されるPromiseを返します。
インスタンスを破棄し、すべてのリソースを解放します。
destroy(): voidSharedDoc は次のイベントをサポートします。これらのイベントは on、once、off メソッドで管理します。
イベント名 | 説明 | パラメータ |
|---|---|---|
| エラーが発生したときにトリガーされます。 |
|
| スナップショットを取得またはサブスクライブした後にトリガーされます。 | なし |
| ドキュメントが作成されたときにトリガーされます。 |
|
| オペレーションが適用される前にトリガーされます。 |
|
| オペレーションが適用された後にトリガーされます。 |
|
| ドキュメントが削除されたときにトリガーされます。 |
|
| ドキュメントが復元されたときにトリガーされます。 |
|
| 強制ロールバック中にトリガーされます。 | なし |
イベントリスナーを登録します。
on<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): ISharedDocEvents<S, T>[NAME];パラメータ
name (NAME): イベント名です。ISharedDocEvents<S, T> インターフェイスのキーである必要があります。
f (ISharedDocEvents<S, T>[NAME]): イベントハンドラー関数です。
戻り値
ISharedDocEvents<S, T>[NAME]: 登録したイベントハンドラーです。
例
doc.on('op', (op, source) => {
if (source !== doc.connection.id) {
console.log('receive op from server:', op);
}
});1 回だけトリガーされるイベントリスナーを登録します。
once<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): void;パラメータ
name (NAME): イベント名です。
f (ISharedDocEvents<S, T>[NAME]): イベントハンドラー関数です。
例
doc.once('op', (op, source) => {
console.log('op', op, source);
});特定のイベントリスナーを削除します。
off<NAME extends keyof ISharedDocEvents<S, T>>(name: NAME, f: ISharedDocEvents<S, T>[NAME]): void;パラメータ
name (NAME): イベント名です。
f (ISharedDocEvents<S, T>[NAME]): 削除するイベントハンドラー関数です。
次の図は、コラボレーションのプロセスを示しています。

// UI コンポーネントを初期化します。xxx.uiComponent は架空のものであり、Quill などの実際の UI コンポーネント実装に置き換える必要があります。
const uiComponent = new xxx.uiComponent();
// ドキュメントをサブスクライブします
doc.subscribe().then(async () => {
// ドキュメントが存在しない場合は作成します
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);
// オペレーションを監視します
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); // 差分更新を推奨
// または uiComponent.setText(doc.data); // 全体更新
});
// UI が復元後の状態を反映するように、restore イベントを監視します
doc.on('restore', (targetVersion) => {
console.log(`Document restored to version ${targetVersion}`);
uiComponent.setText(doc.data); // スナップショットに合わせるため全体更新を強制
});
// UI コンポーネントのオペレーションを監視し、サーバーに送信します
uiComponent.on('op', (op) => {
await doc.submitOp(op, { source: doc.connection.id });
});
})