---
title: Collaboration
description: Collaboration protocol schemas
---

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs go in content/docs/guides/. */}

Real-Time Collaboration Protocol

Defines schemas for real-time collaborative editing in ObjectStack.

Supports Operational Transformation (OT), CRDT (Conflict-free Replicated Data Types),

cursor sharing, and awareness state for collaborative applications.

Industry alignment: Google Docs, Figma, VSCode Live Share, Yjs

<Callout type="info">
**Source:** `packages/spec/src/system/collaboration.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { AwarenessEvent, AwarenessSession, AwarenessUpdate, AwarenessUserState, CRDTMergeResult, CRDTState, CRDTType, CollaborationMode, CollaborationSession, CollaborationSessionConfig, CollaborativeCursor, CounterOperation, CursorColorPreset, CursorSelection, CursorStyle, CursorUpdate, GCounter, LWWRegister, ORSet, ORSetElement, OTComponent, OTOperation, OTOperationType, OTTransformResult, PNCounter, TextCRDTOperation, TextCRDTState, UserActivityStatus, VectorClock } from '@objectstack/spec/system';
import type { AwarenessEvent, AwarenessSession, AwarenessUpdate, AwarenessUserState, CRDTMergeResult, CRDTState, CRDTType, CollaborationMode, CollaborationSession, CollaborationSessionConfig, CollaborativeCursor, CounterOperation, CursorColorPreset, CursorSelection, CursorStyle, CursorUpdate, GCounter, LWWRegister, ORSet, ORSetElement, OTComponent, OTOperation, OTOperationType, OTTransformResult, PNCounter, TextCRDTOperation, TextCRDTState, UserActivityStatus, VectorClock } from '@objectstack/spec/system';

// Validate data
const result = AwarenessEvent.parse(data);
```

---

## AwarenessEvent

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **eventId** | `string` | ✅ | Event identifier |
| **sessionId** | `string` | ✅ | Session identifier |
| **eventType** | `Enum<'user.joined' \| 'user.left' \| 'user.updated' \| 'session.created' \| 'session.ended'>` | ✅ | Type of awareness event |
| **userId** | `string` | optional | User involved in event |
| **timestamp** | `string` | ✅ | ISO 8601 datetime of event |
| **payload** | `any` | ✅ | Event payload |


---

## AwarenessSession

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **sessionId** | `string` | ✅ | Session identifier |
| **documentId** | `string` | optional | Document ID this session is for |
| **users** | `Object[]` | ✅ | Active users in session |
| **startedAt** | `string` | ✅ | ISO 8601 datetime when session started |
| **lastUpdate** | `string` | ✅ | ISO 8601 datetime of last update |
| **metadata** | `Record<string, any>` | optional | Session metadata |


---

## AwarenessUpdate

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **status** | `Enum<'active' \| 'idle' \| 'viewing' \| 'disconnected'>` | optional | Updated status |
| **currentDocument** | `string` | optional | Updated current document |
| **currentView** | `string` | optional | Updated current view |
| **metadata** | `Record<string, any>` | optional | Updated metadata |


---

## AwarenessUserState

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **sessionId** | `string` | ✅ | Session identifier |
| **userName** | `string` | ✅ | Display name |
| **userAvatar** | `string` | optional | User avatar URL |
| **status** | `Enum<'active' \| 'idle' \| 'viewing' \| 'disconnected'>` | ✅ | Current activity status |
| **currentDocument** | `string` | optional | Document ID user is currently editing |
| **currentView** | `string` | optional | Current view/page user is on |
| **lastActivity** | `string` | ✅ | ISO 8601 datetime of last activity |
| **joinedAt** | `string` | ✅ | ISO 8601 datetime when user joined session |
| **permissions** | `string[]` | optional | User permissions in this session |
| **metadata** | `Record<string, any>` | optional | Additional user state metadata |


---

## CRDTMergeResult

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **state** | `Object \| Object \| Object \| Object \| Object` | ✅ | Merged CRDT state |
| **conflicts** | `Object[]` | optional | Conflicts encountered during merge |


---

## CRDTState

### Union Options

This schema accepts one of the following structures:

#### Option 1

**Type:** `lww-register`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **value** | `any` | ✅ | Current register value |
| **timestamp** | `string` | ✅ | ISO 8601 datetime of last write |
| **replicaId** | `string` | ✅ | ID of replica that performed last write |
| **vectorClock** | `Object` | optional | Optional vector clock for causality tracking |

---

#### Option 2

**Type:** `g-counter`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **counts** | `Record<string, integer>` | ✅ | Map of replica ID to count |

---

#### Option 3

**Type:** `pn-counter`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **positive** | `Record<string, integer>` | ✅ | Positive increments per replica |
| **negative** | `Record<string, integer>` | ✅ | Negative increments per replica |

---

#### Option 4

**Type:** `or-set`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **elements** | `Object[]` | ✅ | Set elements with metadata |

---

#### Option 5

**Type:** `text`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **documentId** | `string` | ✅ | Document identifier |
| **content** | `string` | ✅ | Current text content |
| **operations** | `Object[]` | ✅ | History of operations |
| **lamportClock** | `integer` | ✅ | Current Lamport clock value |
| **vectorClock** | `Object` | ✅ | Vector clock for causality |

---


---

## CRDTType

### Allowed Values

* `lww-register`
* `g-counter`
* `pn-counter`
* `g-set`
* `or-set`
* `lww-map`
* `text`
* `tree`
* `json`


---

## CollaborationMode

### Allowed Values

* `ot`
* `crdt`
* `lock`
* `hybrid`


---

## CollaborationSession

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **sessionId** | `string` | ✅ | Session identifier |
| **documentId** | `string` | ✅ | Document identifier |
| **config** | `Object` | ✅ | Session configuration |
| **users** | `Object[]` | ✅ | Active users |
| **cursors** | `Object[]` | ✅ | Active cursors |
| **version** | `integer` | ✅ | Current document version |
| **operations** | `Object \| Object[]` | optional | Recent operations |
| **createdAt** | `string` | ✅ | ISO 8601 datetime when session was created |
| **lastActivity** | `string` | ✅ | ISO 8601 datetime of last activity |
| **status** | `Enum<'active' \| 'idle' \| 'ended'>` | ✅ | Session status |


---

## CollaborationSessionConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **mode** | `Enum<'ot' \| 'crdt' \| 'lock' \| 'hybrid'>` | ✅ | Collaboration mode to use |
| **enableCursorSharing** | `boolean` | ✅ | Enable cursor sharing |
| **enablePresence** | `boolean` | ✅ | Enable presence tracking |
| **enableAwareness** | `boolean` | ✅ | Enable awareness state |
| **maxUsers** | `integer` | optional | Maximum concurrent users |
| **idleTimeout** | `integer` | ✅ | Idle timeout in milliseconds |
| **conflictResolution** | `Enum<'ot' \| 'crdt' \| 'manual'>` | ✅ | Conflict resolution strategy |
| **persistence** | `boolean` | ✅ | Enable operation persistence |
| **snapshot** | `Object` | optional | Snapshot configuration |


---

## CollaborativeCursor

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **sessionId** | `string` | ✅ | Session identifier |
| **documentId** | `string` | ✅ | Document identifier |
| **userName** | `string` | ✅ | Display name of user |
| **position** | `Object` | ✅ | Current cursor position |
| **selection** | `Object` | optional | Current text selection |
| **style** | `Object` | ✅ | Visual style for this cursor |
| **isTyping** | `boolean` | ✅ | Whether user is currently typing |
| **lastUpdate** | `string` | ✅ | ISO 8601 datetime of last cursor update |
| **metadata** | `Record<string, any>` | optional | Additional cursor metadata |


---

## CounterOperation

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **replicaId** | `string` | ✅ | Replica identifier |
| **delta** | `integer` | ✅ | Change amount (positive for increment, negative for decrement) |
| **timestamp** | `string` | ✅ | ISO 8601 datetime of operation |


---

## CursorColorPreset

### Allowed Values

* `blue`
* `green`
* `red`
* `yellow`
* `purple`
* `orange`
* `pink`
* `teal`
* `indigo`
* `cyan`


---

## CursorSelection

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **anchor** | `Object` | ✅ | Selection anchor (start point) |
| **focus** | `Object` | ✅ | Selection focus (end point) |
| **direction** | `Enum<'forward' \| 'backward'>` | optional | Selection direction |


---

## CursorStyle

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **color** | `Enum<'blue' \| 'green' \| 'red' \| 'yellow' \| 'purple' \| 'orange' \| 'pink' \| 'teal' \| 'indigo' \| 'cyan'> \| string` | ✅ | Cursor color (preset or custom hex) |
| **opacity** | `number` | ✅ | Cursor opacity (0-1) |
| **label** | `string` | optional | Label to display with cursor (usually username) |
| **showLabel** | `boolean` | ✅ | Whether to show label |
| **pulseOnUpdate** | `boolean` | ✅ | Whether to pulse when cursor moves |


---

## CursorUpdate

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **position** | `Object` | optional | Updated cursor position |
| **selection** | `Object` | optional | Updated selection |
| **isTyping** | `boolean` | optional | Updated typing state |
| **metadata** | `Record<string, any>` | optional | Updated metadata |


---

## GCounter

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **counts** | `Record<string, integer>` | ✅ | Map of replica ID to count |


---

## LWWRegister

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **value** | `any` | ✅ | Current register value |
| **timestamp** | `string` | ✅ | ISO 8601 datetime of last write |
| **replicaId** | `string` | ✅ | ID of replica that performed last write |
| **vectorClock** | `Object` | optional | Optional vector clock for causality tracking |


---

## ORSet

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **elements** | `Object[]` | ✅ | Set elements with metadata |


---

## ORSetElement

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **value** | `any` | ✅ | Element value |
| **timestamp** | `string` | ✅ | Addition timestamp |
| **replicaId** | `string` | ✅ | Replica that added the element |
| **uid** | `string` | ✅ | Unique identifier for this addition |
| **removed** | `boolean` | ✅ | Whether element has been removed |


---

## OTComponent

### Union Options

This schema accepts one of the following structures:

#### Option 1

**Type:** `insert`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **text** | `string` | ✅ | Text to insert |
| **attributes** | `Record<string, any>` | optional | Text formatting attributes (e.g., bold, italic) |

---

#### Option 2

**Type:** `delete`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **count** | `integer` | ✅ | Number of characters to delete |

---

#### Option 3

**Type:** `retain`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **count** | `integer` | ✅ | Number of characters to retain |
| **attributes** | `Record<string, any>` | optional | Attribute changes to apply |

---


---

## OTOperation

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **operationId** | `string` | ✅ | Unique operation identifier |
| **documentId** | `string` | ✅ | Document identifier |
| **userId** | `string` | ✅ | User who created the operation |
| **sessionId** | `string` | ✅ | Session identifier |
| **components** | `Object \| Object \| Object[]` | ✅ | Operation components |
| **baseVersion** | `integer` | ✅ | Document version this operation is based on |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when operation was created |
| **metadata** | `Record<string, any>` | optional | Additional operation metadata |


---

## OTOperationType

### Allowed Values

* `insert`
* `delete`
* `retain`


---

## OTTransformResult

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **operation** | `Object` | ✅ | Transformed operation |
| **transformed** | `boolean` | ✅ | Whether transformation was applied |
| **conflicts** | `string[]` | optional | Conflict descriptions if any |


---

## PNCounter

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **positive** | `Record<string, integer>` | ✅ | Positive increments per replica |
| **negative** | `Record<string, integer>` | ✅ | Negative increments per replica |


---

## TextCRDTOperation

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **operationId** | `string` | ✅ | Unique operation identifier |
| **replicaId** | `string` | ✅ | Replica identifier |
| **position** | `integer` | ✅ | Position in document |
| **insert** | `string` | optional | Text to insert |
| **delete** | `integer` | optional | Number of characters to delete |
| **timestamp** | `string` | ✅ | ISO 8601 datetime of operation |
| **lamportTimestamp** | `integer` | ✅ | Lamport timestamp for ordering |


---

## TextCRDTState

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **documentId** | `string` | ✅ | Document identifier |
| **content** | `string` | ✅ | Current text content |
| **operations** | `Object[]` | ✅ | History of operations |
| **lamportClock** | `integer` | ✅ | Current Lamport clock value |
| **vectorClock** | `Object` | ✅ | Vector clock for causality |


---

## UserActivityStatus

### Allowed Values

* `active`
* `idle`
* `viewing`
* `disconnected`


---

## VectorClock

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **clock** | `Record<string, integer>` | ✅ | Map of replica ID to logical timestamp |


---

