[]
SharedDoc는 공유 문서 인스턴스를 나타내며, 문서 스냅샷(snapshot)과 작업(op)을 관리하고, 연결(Connection)을 통해 서버와 데이터를 동기화하는 데 사용됩니다. 다중 사용자 작업의 일관성을 보장하기 위해 OT(Operational Transformation) 메커니즘을 지원합니다. 이 문서는 클라이언트 측에서 SharedDoc를 사용하는 방법을 다음 항목 중심으로 설명합니다.
SharedDoc 초기화
문서 생성 및 삭제
문서 스냅샷 요청 및 업데이트
작업 제출, 수신 및 변환
이벤트 수신
속성 이름 | 설명 | 타입 |
|---|---|---|
| 공유 문서의 고유 식별자를 반환합니다. |
|
| 현재 스냅샷의 버전 번호를 나타냅니다. |
|
| 스냅샷의 작업 타입(OT 타입)을 나타냅니다. |
|
| 현재 스냅샷의 데이터를 나타냅니다. |
|
| 공유 문서의 연결 객체를 반환합니다. |
|
문서의 스냅샷 데이터를 가져오며, 결과는 doc.data에 저장됩니다.
fetch(): Promise<void>반환값
Promise<void>: 스냅샷을 가져온 후 resolve되며, 가져온 스냅샷 데이터는 doc.data에 저장됩니다.
예제
try {
await doc.fetch();
if (!doc.type) {
return console.log('문서가 존재하지 않습니다');
}
console.log('문서 스냅샷', doc.data);
} catch (error) {
if (error) {
return console.error(error);
}
}문서의 스냅샷 데이터를 가져오고 이후의 업데이트를 수신합니다.
subscribe(): Promise<void>반환값
Promise<void>: 스냅샷 구독이 완료되면 resolve되며, 구독된 스냅샷 데이터는 doc.data에 저장됩니다.
예제
try {
await doc.subscribe();
if (!doc.type) {
return console.log('문서가 존재하지 않습니다');
}
console.log('문서 스냅샷', doc.data);
doc.on('op', (op, source) => {
console.log('문서가 업데이트됨', op, source);
});
} catch (error) {
if (error) {
return console.error(error);
}
}문서에 작업을 제출합니다.
submitOp(component: T, options?: IOptions): Promise<void>매개변수
component (T): 작업(op) 컴포넌트
options (IOptions): 작업 옵션(선택)
반환값
Promise<void>: 작업 제출이 완료되면 resolve됩니다.
예제
// 위치 1에 텍스트 'Hi' 삽입
await doc.submitOp({ pos: 1, text: 'Hi' }, { source: doc.connection.id });
console.log('작업이 제출되었습니다');새 문서를 생성합니다.
create(data: S, type: string, options: IOptions): Promise<void>매개변수
data (S): 스냅샷을 초기화하는 데 사용할 데이터
type (string): OT 타입의 URI
options (IOptions): 작업 옵션
반환값
Promise<void>: 문서 생성이 완료되면 resolve됩니다.
예제
try {
await doc.create('Hello', textType.uri, {});
console.log('문서가 성공적으로 생성됨:', doc.data); // "Hello"
} catch (err) {
console.error('생성 실패:', err);
}문서의 과거 스냅샷 데이터를 가져옵니다.
fetchHistorySnapshot(options: IHistorySnapshotRequestOptions): Promise<ISnapshot<S>>매개변수
options (IHistorySnapshotRequestOptions): 과거 스냅샷 요청 옵션
반환값
Promise<ISnapshot<S>>: 과거 스냅샷을 가져온 후 resolve됩니다.
예제
const snapshot = await doc.fetchHistorySnapshot({ version: 6 }, textType.uri, {});
console.log('과거 스냅샷:', snapshot);문서를 삭제합니다.
del(options: IOptions): Promise<void>매개변수
options (IOptions): 삭제 옵션
반환값
Promise<void>: 문서 삭제가 완료되면 resolve됩니다.
문서를 특정 버전으로 복원합니다.
restore(targetVersion: number, options?: IOptions): Promise<void>;매개변수
targetVersion (number): 복원할 대상 버전 번호
options (IOptions): 복원 옵션
반환값
Promise<void>: 문서 복원이 완료되면 resolve됩니다.
예제
await doc.restore(10);
console.log('문서가 성공적으로 복원됨:', doc.data); // 버전 10의 데이터스냅샷 데이터를 최신 버전으로 강제로 롤백합니다.
hardRollback(): Promise<void>반환값
Promise<void>: 롤백이 완료되면 resolve됩니다.
인스턴스를 제거하고 모든 리소스를 해제합니다.
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('서버로부터 작업 수신:', op);
}
});한 번만 실행되는 이벤트 리스너를 등록합니다.
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('성공적으로 생성됨:', doc.data);
} catch (error) {
console.error('생성 실패:', error);
return;
}
}
uiComponent.setText(doc.data);
// 작업 수신
doc.on('op', (op, source) => {
if (source === doc.connection.id) {
return;
}
console.log('작업 수신:', op, '현재 데이터:', doc.data);
uiComponent.applyOp(op.pos, op.text); // 점진적 업데이트 권장
// 또는 uiComponent.setText(doc.data); // 전체 업데이트
});
// 복원 이벤트 수신 시 UI 동기화
doc.on('restore', (targetVersion) => {
console.log(`문서가 버전 ${targetVersion}으로 복원됨`);
uiComponent.setText(doc.data); // 스냅샷과 일치하도록 전체 업데이트
});
// UI에서 발생한 작업을 서버로 제출
uiComponent.on('op', async (op) => {
await doc.submitOp(op, { source: doc.connection.id });
});
});실시간 동시 작업 텍스트 편집기를 직접 만들어 보세요: