# DocumentServices 구성 및 사용

## Content

`js-collaboration-ot`의 `DocumentServices` 클래스는 서버 측 OT(Operational Transformation) 기능의 핵심 구성 요소로, 문서 스냅샷과 작업(op)을 저장, 제출, 조회하는 등 전반적인 관리를 담당합니다. 이 문서는 [DocumentServices](/spreadjs/api/collaboration/js-collaboration-ot/classes/DocumentServices)의 생성 및 사용 방법을 다음 항목을 중심으로 설명합니다.

* 문서 스냅샷 및 작업 저장/조회
* 작업 제출 및 스냅샷 업데이트 처리
* 미들웨어 및 훅 확장 추가

## **사용 사례**

* OT 동작 커스터마이징
* 성능 최적화
* 특정 영속성(persistence) 솔루션 구현

## 초기화

[DocumentServices 초기화](/spreadjs/docs/spreadjs-collaboration-server/collaboration-framework/js-collaboration-ot/initalizing-documentservices)

## 생성자 구성

`DocumentServices`는 생성자에서 설정 객체([IDocConfig](/spreadjs/api/collaboration/js-collaboration-ot/interfaces/IDocConfig))를 전달받아, 데이터베이스 및 동작 관련 파라미터를 커스터마이징할 수 있습니다.

### 설정 파라미터

| 파라미터 이름 | 타입 | 설명 | 기본값 |
| ------- | --- | --- | --- |
| `db` | `IDataBaseAdapter` | 스냅샷과 작업을 저장하는 데이터베이스 어댑터 | `MemoryDb` |
| `milestoneDb` | `IMilestoneDataBaseAdapter` | 주기적인 스냅샷 저장에 사용되는 마일스톤 데이터베이스 어댑터 | 인메모리 구현 |
| `maxSubmitRetries` | `number` | 작업 제출 시 최대 재시도 횟수 | 제한 없음 |
| `submitSnapshotBatchSize` | `number` | 누적된 작업(op)을 현재 스냅샷에 적용한 뒤, 갱신된 스냅샷을 데이터베이스에 제출하기 전까지 허용되는 작업 수 | 100 |

>type=note
> **submitSnapshotBatchSize에 대한 설명**:
> 이 파라미터는 스냅샷 업데이트 빈도를 정의합니다. 서버에 누적된 작업 수가 이 값에 도달하면, 해당 작업들이 현재 스냅샷에 적용되어 새로운 스냅샷이 생성되고, 기존 스냅샷을 덮어쓰는 형태로 데이터베이스에 저장됩니다.
> 작업(op) 자체는 별도로 저장되며, 스냅샷은 항상 최신 버전을 유지합니다. 이 메커니즘은 스냅샷 업데이트 빈도와 데이터베이스 쓰기 부하 간의 균형을 맞추기 위한 것입니다.

### 예제: 기본 설정

```typescript
import { DocumentServices, MemoryDb } from '@mescius/js-collaboration-ot';

// DocumentServices 설정
const docService = new DocumentServices({
    db: new MemoryDb(),              // 인메모리 데이터베이스 사용
    maxSubmitRetries: 3,             // 최대 3회 재시도
    submitSnapshotBatchSize: 50      // 작업 50개 누적 시 스냅샷 업데이트
});
```

>type=note
> 기본값은 개발 및 테스트에 적합한 MemoryDb입니다.
> 운영 환경에서는 영속 저장소를 사용하는 어댑터(예: Postgres 어댑터)를 사용하는 것을 권장합니다.

## 서버 측 작업(Op) 처리 흐름

![construct_documentServices.ab15fd.png](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/36b63360-fb01-457c-a448-c3ce32aaf454/construct_documentServices.ab15fd-20260107.3fbe8d.png?width=400)

## 메서드

### use

작업 처리 과정에 커스텀 로직을 추가하기 위해 미들웨어를 등록합니다.

```typescript
use<K extends keyof IDocMiddlewareContext<S, T>>(
  action: K,
  middleware: IMiddleware<IDocMiddlewareContext<S, T>[K]>
)
```

**매개변수**

* `action`: 미들웨어 동작 이름 (예: `"submit"`, `"receive"`)
* `middleware`: 미들웨어 함수 (`IMiddleware` 타입). 컨텍스트를 전달받아 처리 흐름을 제어합니다.

**예제**

```typescript
docService.use('submit', async (context, next) => {
    console.log('작업 제출:', context.request.op);
});
```

### on

작업 이벤트를 수신하기 위한 훅(hook)을 등록합니다.

```typescript
on<K extends keyof IDocHookContext>(
  hookName: K,
  hook: IHook<IDocHookContext[K]>
)
```

**매개변수**

* `hookName`: 훅 이름 (예: `"submitRequestEnd"`)
* `hook`: 훅 함수 (`IHook` 타입), 컨텍스트를 인자로 받습니다.

**예제**

```typescript
docService.on('submitRequestEnd', (context) => {
    console.log('제출 완료:', context);
});
```

### fetch

지정된 문서의 최신 스냅샷을 조회합니다.

```typescript
fetch(id: string, context?: IContext): Promise<ISnapshot<S>>
```

**매개변수**

* `id`: 문서 ID (`string`)
* `context` (선택): 작업 컨텍스트

**반환값**
`Promise<ISnapshot<S>>` — 최신 스냅샷을 포함하는 Promise

**예제**

```typescript
const snapshot = await docService.fetch('doc1');
console.log('최신 스냅샷:', snapshot.data);
```

### getOps

지정된 문서에서 특정 버전 범위(`from` 포함, `to` 미포함)의 작업을 조회합니다.

```typescript
getOps(
  id: string,
  from: number,
  to?: number,
  context?: IContext
): Promise<IOp<T>[]>
```

**매개변수**

* `id`: 문서 ID (`string`)
* `from`: 시작 버전 번호 (포함)
* `to` (선택): 종료 버전 번호 (미포함)
* `context` (선택): 작업 컨텍스트

**반환값**
`Promise<IOp<T>[]>` — 작업 배열을 포함하는 Promise

**예제**

```typescript
const ops = await docService.getOps('doc1', 0, 5);
console.log(ops);
```

### submit

지정된 문서에 작업을 제출합니다.

```typescript
submit(
  id: string,
  op: IOp<T>,
  context?: IContext
): Promise<IOp<T>[]>
```

**매개변수**

* `id`: 문서 ID (`string`)
* `op`: 작업 (`IOp<T>` 타입)
* `context` (선택): 작업 컨텍스트

**반환값**
`Promise<IOp<T>[]>` — 처리 결과 작업을 포함하는 Promise

**예제**

```typescript
docService.submit('doc1', op);
```

### fetchHistorySnapshot

지정된 문서의 과거 스냅샷을 조회합니다.

```typescript
fetchHistorySnapshot(
  id: string,
  version?: number,
  context?: IContext
): Promise<ISnapshot<S>>
```

**매개변수**

* `id`: 문서 ID (`string`)
* `version` (선택): 조회할 대상 버전 번호 (생략 시 최신 스냅샷 반환)
* `context` (선택): 작업 컨텍스트

**반환값**
`Promise<ISnapshot<S>>` — 과거 스냅샷을 포함하는 Promise

**예제**

```typescript
const snapshot = await docService.fetchHistorySnapshot('doc1', 2);
console.log('과거 스냅샷:', snapshot.data);
```