[]
js-collaboration-ot의 DocumentServices 클래스는 서버 측 OT(Operational Transformation) 기능의 핵심 구성 요소로, 문서 스냅샷과 작업(op)을 저장, 제출, 조회하는 등 전반적인 관리를 담당합니다. 이 문서는 DocumentServices의 생성 및 사용 방법을 다음 항목을 중심으로 설명합니다.
문서 스냅샷 및 작업 저장/조회
작업 제출 및 스냅샷 업데이트 처리
미들웨어 및 훅 확장 추가
OT 동작 커스터마이징
성능 최적화
특정 영속성(persistence) 솔루션 구현
DocumentServices는 생성자에서 설정 객체(IDocConfig)를 전달받아, 데이터베이스 및 동작 관련 파라미터를 커스터마이징할 수 있습니다.
파라미터 이름 | 타입 | 설명 | 기본값 |
|---|---|---|---|
|
| 스냅샷과 작업을 저장하는 데이터베이스 어댑터 |
|
|
| 주기적인 스냅샷 저장에 사용되는 마일스톤 데이터베이스 어댑터 | 인메모리 구현 |
|
| 작업 제출 시 최대 재시도 횟수 | 제한 없음 |
|
| 누적된 작업(op)을 현재 스냅샷에 적용한 뒤, 갱신된 스냅샷을 데이터베이스에 제출하기 전까지 허용되는 작업 수 | 100 |
submitSnapshotBatchSize에 대한 설명:
이 파라미터는 스냅샷 업데이트 빈도를 정의합니다. 서버에 누적된 작업 수가 이 값에 도달하면, 해당 작업들이 현재 스냅샷에 적용되어 새로운 스냅샷이 생성되고, 기존 스냅샷을 덮어쓰는 형태로 데이터베이스에 저장됩니다.
작업(op) 자체는 별도로 저장되며, 스냅샷은 항상 최신 버전을 유지합니다. 이 메커니즘은 스냅샷 업데이트 빈도와 데이터베이스 쓰기 부하 간의 균형을 맞추기 위한 것입니다.
import { DocumentServices, MemoryDb } from '@mescius/js-collaboration-ot';
// DocumentServices 설정
const docService = new DocumentServices({
db: new MemoryDb(), // 인메모리 데이터베이스 사용
maxSubmitRetries: 3, // 최대 3회 재시도
submitSnapshotBatchSize: 50 // 작업 50개 누적 시 스냅샷 업데이트
});기본값은 개발 및 테스트에 적합한 MemoryDb입니다.
운영 환경에서는 영속 저장소를 사용하는 어댑터(예: Postgres 어댑터)를 사용하는 것을 권장합니다.

작업 처리 과정에 커스텀 로직을 추가하기 위해 미들웨어를 등록합니다.
use<K extends keyof IDocMiddlewareContext<S, T>>(
action: K,
middleware: IMiddleware<IDocMiddlewareContext<S, T>[K]>
)매개변수
action: 미들웨어 동작 이름 (예: "submit", "receive")
middleware: 미들웨어 함수 (IMiddleware 타입). 컨텍스트를 전달받아 처리 흐름을 제어합니다.
예제
docService.use('submit', async (context, next) => {
console.log('작업 제출:', context.request.op);
});작업 이벤트를 수신하기 위한 훅(hook)을 등록합니다.
on<K extends keyof IDocHookContext>(
hookName: K,
hook: IHook<IDocHookContext[K]>
)매개변수
hookName: 훅 이름 (예: "submitRequestEnd")
hook: 훅 함수 (IHook 타입), 컨텍스트를 인자로 받습니다.
예제
docService.on('submitRequestEnd', (context) => {
console.log('제출 완료:', context);
});지정된 문서의 최신 스냅샷을 조회합니다.
fetch(id: string, context?: IContext): Promise<ISnapshot<S>>매개변수
id: 문서 ID (string)
context (선택): 작업 컨텍스트
반환값
Promise<ISnapshot<S>> — 최신 스냅샷을 포함하는 Promise
예제
const snapshot = await docService.fetch('doc1');
console.log('최신 스냅샷:', snapshot.data);지정된 문서에서 특정 버전 범위(from 포함, to 미포함)의 작업을 조회합니다.
getOps(
id: string,
from: number,
to?: number,
context?: IContext
): Promise<IOp<T>[]>매개변수
id: 문서 ID (string)
from: 시작 버전 번호 (포함)
to (선택): 종료 버전 번호 (미포함)
context (선택): 작업 컨텍스트
반환값
Promise<IOp<T>[]> — 작업 배열을 포함하는 Promise
예제
const ops = await docService.getOps('doc1', 0, 5);
console.log(ops);지정된 문서에 작업을 제출합니다.
submit(
id: string,
op: IOp<T>,
context?: IContext
): Promise<IOp<T>[]>매개변수
id: 문서 ID (string)
op: 작업 (IOp<T> 타입)
context (선택): 작업 컨텍스트
반환값
Promise<IOp<T>[]> — 처리 결과 작업을 포함하는 Promise
예제
docService.submit('doc1', op);지정된 문서의 과거 스냅샷을 조회합니다.
fetchHistorySnapshot(
id: string,
version?: number,
context?: IContext
): Promise<ISnapshot<S>>매개변수
id: 문서 ID (string)
version (선택): 조회할 대상 버전 번호 (생략 시 최신 스냅샷 반환)
context (선택): 작업 컨텍스트
반환값
Promise<ISnapshot<S>> — 과거 스냅샷을 포함하는 Promise
예제
const snapshot = await docService.fetchHistorySnapshot('doc1', 2);
console.log('과거 스냅샷:', snapshot.data);