# TypeScript Types Reference

Complete reference for all exported TypeScript types in Vuer-RTC.

## Core Message Types

### CRDTMessage

The envelope containing CRDT metadata and a batch of operations. This is the fundamental unit of communication in Vuer-RTC.

```typescript
interface CRDTMessage {
  // CRDT Metadata (wrapper)
  id: string;              // Message ID (UUID)
  sessionId: string;       // Session that created this message
  clock: VectorClock;      // Vector clock for causal ordering
  lamportTime: number;     // Lamport timestamp for total ordering
  timestamp: number;       // Wall-clock time (seconds since epoch)

  // Operations (batch)
  ops: Operation[];        // One or more operations
}
```

**Example:**
```typescript
const message: CRDTMessage = {
  id: 'msg-uuid-123',
  sessionId: 'session-abc',
  clock: { 'session-abc': 5, 'session-xyz': 3 },
  lamportTime: 42,
  timestamp: 1708989600,
  ops: [
    { ot: 'vector3.set', key: 'cube', path: 'position', value: [1, 2, 3] }
  ]
};
```

### Operation

Union type of all operation types. Every operation extends `BaseOp`.

```typescript
type Operation =
  | NumberSetOp | NumberAddOp | NumberMultiplyOp | NumberMinOp | NumberMaxOp
  | StringSetOp | StringConcatOp
  | TextInitOp | TextInsertOp | TextDeleteOp | TextReplaceOp
  | BooleanSetOp | BooleanOrOp | BooleanAndOp
  | Vector3SetOp | Vector3AddOp | Vector3MultiplyOp | Vector3ApplyEulerOp | Vector3ApplyQuaternionOp
  | EulerSetOp | EulerAddOp
  | QuaternionSetOp | QuaternionMultiplyOp
  | ColorSetOp | ColorBlendOp
  | ArraySetOp | ArrayPushOp | ArrayUnionOp | ArrayRemoveOp
  | ObjectSetOp | ObjectMergeOp
  | NodeInsertOp | NodeRemoveOp | NodeMoveOp
  | MetaUndoOp | MetaRedoOp;
```

### BaseOp

Base interface extended by all operations.

```typescript
interface BaseOp {
  key: string;     // Node key (human-friendly, e.g., 'cube-1', 'player', 'scene')
  ot: string;   // dtype operation: 'number.set', 'vector3.add', etc.
  path: string;    // Property path: 'color', 'transform.position', etc.
}
```

## Number Operations

### NumberSetOp

```typescript
interface NumberSetOp extends BaseOp {
  ot: 'number.set';
  value: number;
}
```

**Example:**
```typescript
{ ot: 'number.set', key: 'light-1', path: 'intensity', value: 0.8 }
```

### NumberAddOp

```typescript
interface NumberAddOp extends BaseOp {
  ot: 'number.add';
  value: number;
}
```

**Example:**
```typescript
{ ot: 'number.add', key: 'player', path: 'score', value: 100 }
```

### NumberMultiplyOp

```typescript
interface NumberMultiplyOp extends BaseOp {
  ot: 'number.multiply';
  value: number;
}
```

### NumberMinOp

```typescript
interface NumberMinOp extends BaseOp {
  ot: 'number.min';
  value: number;
}
```

### NumberMaxOp

```typescript
interface NumberMaxOp extends BaseOp {
  ot: 'number.max';
  value: number;
}
```

## String Operations

### StringSetOp

```typescript
interface StringSetOp extends BaseOp {
  ot: 'string.set';
  value: string;
}
```

### StringConcatOp

```typescript
interface StringConcatOp extends BaseOp {
  ot: 'string.concat';
  value: string;
  separator?: string;  // Optional separator (default: '')
}
```

## Text CRDT Operations

Text operations support collaborative character-level editing using a CRDT.

### TextInitOp

Initialize a CRDT-backed text property. Must be called before using text operations.

```typescript
interface TextInitOp extends BaseOp {
  ot: 'text.init';
  value?: string;  // Optional initial content
}
```

**Example:**
```typescript
{ ot: 'text.init', key: 'doc', path: 'content', value: 'Hello world' }
```

### TextInsertOp

Insert text at a position. Supports two formats:
1. **Position-based** (local operations): `{ position, value }`
2. **CRDT metadata** (network sync): `{ id, value: [anchor, content], seq, ts }`

```typescript
interface TextInsertOp extends BaseOp {
  ot: 'text.insert';
  // Position-based format (local convenience)
  position?: number;
  value?: [string | null, string];  // [anchor, content] tuple — anchor null for local
  // CRDT metadata format (network sync)
  id?: string;   // ItemId string: "client:seq"
  seq?: number;  // Lamport timestamp
  ts?: number;   // Wall-clock time (seconds) for tie-breaking
}
```

**Examples:**
```typescript
// Local format
{ ot: 'text.insert', key: 'doc', path: 'content', position: 5, value: [null, 'world'] }

// CRDT format (generated internally)
{
  ot: 'text.insert',
  key: 'doc',
  path: 'content',
  id: 'session-abc:10',
  value: ['session-abc:9', 'world'],  // [anchor, content]
  seq: 42,
  ts: 1234567890.123
}
```

### TextDeleteOp

Delete text at a position. Supports two formats:
1. **Position-based**: `{ position, length }`
2. **CRDT metadata**: `{ rm }`

```typescript
interface TextDeleteOp extends BaseOp {
  ot: 'text.delete';
  // Position-based format
  position?: number;
  length?: number;
  // CRDT metadata format (rope tuple format)
  rm?: Array<[string, number]>;  // [[itemId, length], ...]
}
```

**Examples:**
```typescript
// Local format
{ ot: 'text.delete', key: 'doc', path: 'content', position: 5, length: 3 }

// CRDT format
{
  ot: 'text.delete',
  key: 'doc',
  path: 'content',
  rm: [['session-abc:10', 3]]  // [[itemId, length], ...]
}
```

### TextReplaceOp

Atomic delete + insert (for select-and-type).

```typescript
interface TextReplaceOp extends BaseOp {
  ot: 'text.replace';
  // Position-based format
  position?: number;
  length?: number;    // chars to delete
  value?: [string | null, string];  // [anchor, content] tuple — chars to insert
  // CRDT metadata format (rope tuple format)
  rm?: Array<[string, number]>;     // [[itemId, length], ...]
  id?: string;   // ItemId string: "client:seq"
  seq?: number;
  ts?: number;
}
```

## Boolean Operations

### BooleanSetOp

```typescript
interface BooleanSetOp extends BaseOp {
  ot: 'boolean.set';
  value: boolean;
}
```

### BooleanOrOp

```typescript
interface BooleanOrOp extends BaseOp {
  ot: 'boolean.or';
  value: boolean;
}
```

### BooleanAndOp

```typescript
interface BooleanAndOp extends BaseOp {
  ot: 'boolean.and';
  value: boolean;
}
```

## Vector3 Operations

### Vector3SetOp

```typescript
interface Vector3SetOp extends BaseOp {
  ot: 'vector3.set';
  value: [number, number, number];
}
```

**Example:**
```typescript
{ ot: 'vector3.set', key: 'cube', path: 'position', value: [1, 2, 3] }
```

### Vector3AddOp

```typescript
interface Vector3AddOp extends BaseOp {
  ot: 'vector3.add';
  value: [number, number, number];
}
```

### Vector3MultiplyOp

```typescript
interface Vector3MultiplyOp extends BaseOp {
  ot: 'vector3.multiply';
  value: [number, number, number];
}
```

### Vector3ApplyEulerOp

Rotate a vector by euler angles.

```typescript
type EulerOrder = 'XYZ' | 'XZY' | 'YXZ' | 'YZX' | 'ZXY' | 'ZYX';

interface Vector3ApplyEulerOp extends BaseOp {
  ot: 'vector3.applyEuler';
  value: [number, number, number];  // [x, y, z] rotation angles in radians
  order?: EulerOrder;               // Default: 'XYZ'
  intrinsic?: boolean;              // Default: true (axes move with body)
}
```

**Example:**
```typescript
// Intrinsic YXZ rotation (common for FPS cameras)
{
  ot: 'vector3.applyEuler',
  key: 'camera',
  path: 'direction',
  value: [0, Math.PI/2, 0],
  order: 'YXZ'
}
```

### Vector3ApplyQuaternionOp

```typescript
interface Vector3ApplyQuaternionOp extends BaseOp {
  ot: 'vector3.applyQuaternion';
  value: [number, number, number, number];  // [x, y, z, w]
}
```

## Euler Operations

### EulerSetOp

```typescript
interface EulerSetOp extends BaseOp {
  ot: 'euler.set';
  value: [number, number, number];  // [x, y, z] in radians
}
```

### EulerAddOp

```typescript
interface EulerAddOp extends BaseOp {
  ot: 'euler.add';
  value: [number, number, number];  // [x, y, z] in radians
}
```

## Quaternion Operations

### QuaternionSetOp

```typescript
interface QuaternionSetOp extends BaseOp {
  ot: 'quaternion.set';
  value: [number, number, number, number];  // [x, y, z, w]
}
```

### QuaternionMultiplyOp

```typescript
interface QuaternionMultiplyOp extends BaseOp {
  ot: 'quaternion.multiply';
  value: [number, number, number, number];  // [x, y, z, w]
}
```

## Color Operations

### ColorSetOp

```typescript
interface ColorSetOp extends BaseOp {
  ot: 'color.set';
  value: string;  // Hex color (e.g., '#ff0000')
}
```

### ColorBlendOp

```typescript
interface ColorBlendOp extends BaseOp {
  ot: 'color.blend';
  value: string;  // Hex color to blend towards
}
```

## Array Operations

### ArraySetOp

```typescript
interface ArraySetOp extends BaseOp {
  ot: 'array.set';
  value: any[];
}
```

### ArrayPushOp

```typescript
interface ArrayPushOp extends BaseOp {
  ot: 'array.push';
  value: any;
}
```

### ArrayUnionOp

```typescript
interface ArrayUnionOp extends BaseOp {
  ot: 'array.union';
  value: any[];  // Add unique items
}
```

### ArrayRemoveOp

```typescript
interface ArrayRemoveOp extends BaseOp {
  ot: 'array.remove';
  value: any;
}
```

## Object Operations

### ObjectSetOp

```typescript
interface ObjectSetOp extends BaseOp {
  ot: 'object.set';
  value: Record<string, any>;
}
```

### ObjectMergeOp

```typescript
interface ObjectMergeOp extends BaseOp {
  ot: 'object.merge';
  value: Record<string, any>;
}
```

## Scene Graph Operations

### NodeInsertOp

Create a new node as a child of parent.

```typescript
interface NodeInsertOp extends BaseOp {
  key: string;           // Parent node's key
  ot: 'node.insert';
  path: 'children';
  value: {
    key: string;         // New node's key (also used as id)
    tag: string;         // 'Scene' | 'Mesh' | 'Group' | ...
    name: string;        // Display name
    [key: string]: any;  // Initial properties
  };
}
```

**Example:**
```typescript
{
  ot: 'node.insert',
  key: 'scene',
  path: 'children',
  value: {
    key: 'cube-1',
    tag: 'Mesh',
    name: 'Red Cube',
    position: [0, 0, 0],
    color: '#ff0000'
  }
}
```

### NodeRemoveOp

Remove a node from parent (tombstone).

```typescript
interface NodeRemoveOp extends BaseOp {
  key: string;           // Parent node's key
  ot: 'node.remove';
  path: 'children';
  value: string;         // Node key to remove
}
```

### NodeMoveOp

Move a node from one parent to another (reparent).

```typescript
interface NodeMoveOp extends BaseOp {
  key: string;           // Old parent node's key
  ot: 'node.move';
  path: 'children';
  value: {
    nodeKey: string;     // Node key to move
    newParent: string;   // New parent node key
  };
}
```

## Meta Operations (Undo/Redo)

### MetaUndoOp

Mark a message as undone.

```typescript
interface MetaUndoOp {
  key: '_meta';
  ot: 'meta.undo';
  path: '_meta';
  targetMsgId: string;  // Message ID to undo
}
```

### MetaRedoOp

Unmark a message as undone.

```typescript
interface MetaRedoOp {
  key: '_meta';
  ot: 'meta.redo';
  path: '_meta';
  targetMsgId: string;  // Message ID to redo
}
```

## Scene Graph State

### SceneNode

A node in the flattened scene graph. Properties are stored directly with dot-notation paths.

```typescript
interface SceneNode {
  // Identity
  key: string;           // Unique key in scene (human-friendly)
  tag: string;           // Node type
  name: string;          // Display name

  // Tree structure
  children: string[];    // Child node keys

  // CRDT metadata envelope
  _crdt: CRDTEnvelope;

  // Dynamic properties (flat with dot-notation paths)
  // e.g., 'transform.position', 'color', 'opacity'
  [path: string]: unknown;
}
```

**Example:**
```typescript
const node: SceneNode = {
  key: 'cube-1',
  tag: 'Mesh',
  name: 'Red Cube',
  children: [],
  _crdt: {
    clock: { 'session-abc': 5 },
    lamportTime: 42,
    createdAt: 1708989600,
    updatedAt: 1708989650,
    lww: {
      'position': { lamportTime: 42, sessionId: 'session-abc' },
      'color': { lamportTime: 43, sessionId: 'session-abc' }
    }
  },
  'position': [1, 2, 3],
  'color': '#ff0000',
  'opacity': 0.8
};
```

### CRDTEnvelope

All CRDT metadata for a SceneNode, stored under `_crdt`.

```typescript
interface CRDTEnvelope {
  clock: VectorClock;
  lamportTime: number;
  createdAt: number;              // Timestamp when node was created
  updatedAt: number;              // Last update timestamp
  deletedAt?: number;             // Tombstone for soft delete
  lww: Record<string, PropertyLWW>;  // Per-property LWW metadata
}
```

### PropertyLWW

Per-property Last-Write-Wins metadata.

```typescript
interface PropertyLWW {
  lamportTime: number;
  sessionId: string;
}
```

### SceneGraph

Complete scene representation.

```typescript
interface SceneGraph {
  nodes: Record<string, SceneNode>;  // Flattened map by key
  rootKey: string;                    // Root node key
}
```

**Example:**
```typescript
const graph: SceneGraph = {
  rootKey: 'scene',
  nodes: {
    'scene': {
      key: 'scene',
      tag: 'Scene',
      name: 'Root',
      children: ['cube-1', 'light-1'],
      _crdt: { /* ... */ }
    },
    'cube-1': {
      key: 'cube-1',
      tag: 'Mesh',
      name: 'Red Cube',
      children: [],
      _crdt: { /* ... */ },
      'position': [1, 2, 3]
    }
  }
};
```

## Client State

### ClientState

Complete client-side state.

```typescript
interface ClientState {
  // Current computed value (derived from snapshot + journal + edits)
  graph: SceneGraph;

  // Committed edits (sent or pending acknowledgement)
  journal: JournalEntry[];

  // Uncommitted operations (in-progress edits)
  edits: EditBuffer;

  // Checkpoint for fast replay
  snapshot: Snapshot;

  // Clocks
  lamportTime: number;
  vectorClock: VectorClock;
  sessionId: string;
}
```

### JournalEntry

A committed message with metadata.

```typescript
interface JournalEntry {
  msg: CRDTMessage;
  ack: boolean;           // Has server acknowledged?
  deletedAt?: number;     // If set, message is "undone"
}
```

### EditBuffer

Uncommitted operations.

```typescript
interface EditBuffer {
  ops: Operation[];                // Pending operations (merged)
  baseGraph: SceneGraph | null;    // Graph state when edits started
}
```

### Snapshot

Checkpoint for fast replay.

```typescript
interface Snapshot {
  graph: SceneGraph;
  vectorClock: VectorClock;
  lamportTime: number;    // Max lamport time baked in
  journalIndex: number;   // How many entries are baked in
}
```

### GraphStore

The public API for the graph store.

```typescript
interface GraphStore {
  // State access
  getState: () => ClientState;
  subscribe: (listener: () => void) => () => void;

  // Edit operations
  edit: (op: Operation) => void;
  commit: (description?: string) => CRDTMessage | null;

  // Server communication
  receive: (msg: CRDTMessage) => void;
  ack: (msgId: string) => void;
  loadServerState: (snapshot: Snapshot, journal: CRDTMessage[]) => void;

  // Undo/redo
  undo: () => { msg: CRDTMessage | null };
  redo: () => { msg: CRDTMessage | null };

  // Maintenance
  compact: () => void;
  compactToWatermark: (watermark: VectorClock) => void;
}
```

### CreateGraphOptions

Options for creating a graph store.

```typescript
interface CreateGraphOptions {
  sessionId: string;
  initialSnapshot?: Snapshot;
  onSend?: (msg: CRDTMessage) => void;
  onStateChange?: (state: ClientState) => void;
}
```

## Vector Clock

### VectorClock

CRDT-inspired vector clock for causal ordering.

```typescript
type VectorClock = Record<string, number>;
```

**Example:**
```typescript
const clock: VectorClock = {
  'session-abc': 5,
  'session-xyz': 3,
  'session-123': 7
};
```

Vector clocks track causality:
- Each session has a counter
- Counters increment with each operation
- Clocks are merged to detect concurrent operations

## TextRope Types

Types for the collaborative text editing CRDT.

### ItemId

Identifier for a text item.

```typescript
type ItemId = string;  // "agent:seq" (e.g. "agent-1:42")
```

### Item

A text item in the rope.

```typescript
interface Item {
  id: ItemId;
  content: string;
  isDeleted: boolean;
  anchor?: ItemId;  // originLeft; omitted when null
  seq: number;  // Lamport timestamp
  ts: number;   // Wall-clock time (seconds) for tie-breaking
}
```

### InsertOp

Insert operation for text rope.

```typescript
interface InsertOp {
  ot: 'insert';
  id: ItemId;
  value: [ItemId | null, string];  // [anchor, content]
  seq: number;
  ts: number;
}
```

### DeleteOp

Delete operation for text rope.

```typescript
interface DeleteOp {
  ot: 'delete';
  rm: Array<[ItemId, number]>;  // [[itemId, length], ...]
}
```

### ReplaceOp

Replace operation (atomic delete + insert).

```typescript
interface ReplaceOp {
  ot: 'replace';
  rm: Array<[ItemId, number]>;
  id: ItemId;
  value: [ItemId | null, string];  // [anchor, content]
  seq: number;
  ts: number;
}
```

### MoveOp

Move operation (delete + insert at new position).

```typescript
interface MoveOp {
  ot: 'move';
  delete: DeleteOp;
  insert: InsertOp;
}
```

### TextRope

High-performance text CRDT based on RGA/YATA.

```typescript
class TextRope {
  _tree: ItemTree;
  _agentIndex: Map<string, SpanEntry[]>;
  agentId: string;
  clock: number;
  maxSeq: number;
}
```

## Sync Types

### SyncDigest

Bloom filter digest for sync reconciliation.

```typescript
interface SyncDigest {
  mtype: 'sync';
  vectorClock: VectorClock;  // Covers compacted (snapshot) entries
  filter: Uint8Array;        // Bloom filter bytes (covers journal entries)
  count: number;             // Journal length (diagnostics)
}
```

**Usage:**
```typescript

const digest = buildSyncDigest(clientState);
// Send to server for efficient sync
```

## Awareness Types

Ephemeral presence / cursor relay — see [Awareness](/awareness.md). Never persisted;
the `state` payload is app-defined and opaque to the relay.

### AwarenessState

```typescript
interface AwarenessState {
  user?: { id: string; name: string; color: string };
  cursor?: unknown;  // app-defined; e.g. { anchor, head } text offsets
  ts?: number;
}
```

### Awareness messages

```typescript
// Client → server → other clients: publish or clear my state
interface AwarenessMessage {
  mtype: 'awareness';
  client: string;
  state: AwarenessState | null;  // null clears / signals leave
}

// Server → a newly-joined client: everyone already in the room
interface AwarenessRoster {
  mtype: 'awareness-roster';
  states: Array<{ client: string; state: AwarenessState }>;
}
```

## Type Usage Examples

### Creating a CRDTMessage

```typescript

const store = createGraph({
  sessionId: 'session-abc',
  onSend: (msg: CRDTMessage) => {
    // Send to server
    console.log(`Sending ${msg.ops.length} operations`);
  }
});

// Edit operations are batched
store.edit({ ot: 'vector3.set', key: 'cube', path: 'position', value: [1, 2, 3] });
store.edit({ ot: 'color.set', key: 'cube', path: 'color', value: '#ff0000' });

// Commit creates a CRDTMessage with both ops
const msg = store.commit('Update cube');
```

### Working with SceneGraph

```typescript

const graph: SceneGraph = store.getState().graph;

// Access nodes
const cube: SceneNode | undefined = graph.nodes['cube-1'];

// Traverse children
const rootNode = graph.nodes[graph.rootKey];
rootNode.children.forEach(childKey => {
  const child = graph.nodes[childKey];
  console.log(`Child: ${child.name}`);
});

// Access properties with type safety
if (cube) {
  const position = cube['position'] as [number, number, number];
  const color = cube['color'] as string;
}
```

### Implementing Custom Operations

```typescript

function updateCubeColor(store: GraphStore, key: string, color: string) {
  const op: ColorSetOp = {
    ot: 'color.set',
    key,
    path: 'color',
    value: color
  };
  store.edit(op);
}

function moveCube(store: GraphStore, key: string, delta: [number, number, number]) {
  const op: Vector3AddOp = {
    ot: 'vector3.add',
    key,
    path: 'position',
    value: delta
  };
  store.edit(op);
}
```

### Handling Text CRDT

```typescript

// Initialize text property
const initOp: TextInitOp = {
  ot: 'text.init',
  key: 'doc',
  path: 'content',
  value: 'Hello world'
};
store.edit(initOp);

// Insert text
const insertOp: TextInsertOp = {
  ot: 'text.insert',
  key: 'doc',
  path: 'content',
  position: 6,
  value: [null, 'beautiful ']
};
store.edit(insertOp);

// Delete text
const deleteOp: TextDeleteOp = {
  ot: 'text.delete',
  key: 'doc',
  path: 'content',
  position: 0,
  length: 5
};
store.edit(deleteOp);
```
