# Collaborative Presence
URL: https://pro.rv-grid.com/api/collaborative-presence/
Source: src/content/docs/api/collaborative-presence.md
## Module Extensions

### `HTMLRevoGridElement` (Extended from `@revolist/revogrid`)

```ts
interface HTMLRevoGridElement {
  collaborativePresence?: CollaborativePresenceConfig;
  'collaborative-presence'?: CollaborativePresenceConfig
}
```

---

### `AdditionalData` (Extended from `@revolist/revogrid`)

```ts
interface AdditionalData {
  collaborativePresence?: CollaborativePresenceConfig
}
```

## Plugin API

### `CollaborativePresencePlugin`

Renders remote collaborator focus and range presence without mutating local
grid focus, selection, data, or history.

#### Dependencies

- **Config integration** `additionalData.collaborativePresence`: Reads remote collaborator presence from grid.collaborativePresence or additionalData.collaborativePresence.
- **Event integration** `afterrender`: Refreshes visible remote focus and range markers after grid render updates.

```ts
class CollaborativePresencePlugin {
  destroy();
}
```

---

### `CollaborativePresenceActivity`

```ts
export type CollaborativePresenceActivity = 'viewing' | 'editing' | 'idle';
```

---

### `CollaborativePresenceCellRef`

```ts
interface CollaborativePresenceCellRef {
  x: number;
  y: number;
  colType?: DimensionCols;
  rowType?: DimensionRows
}
```

---

### `CollaborativePresenceRangeRef` (Extended from `index.ts`)

```ts
interface CollaborativePresenceRangeRef {
  colType?: DimensionCols;
  rowType?: DimensionRows
}
```

---

### `CollaborativePresenceUser`

```ts
interface CollaborativePresenceUser {
  id: string;
  name: string;
  initials?: string;
  color?: string;
  activity?: CollaborativePresenceActivity;
  focus?: CollaborativePresenceCellRef | null;
  range?: CollaborativePresenceRangeRef | null;
  lastActiveAt?: number | string | Date
}
```

---

### `CollaborativePresenceRowPatch`

```ts
interface CollaborativePresenceRowPatch {
  rowIndex: number;
  data: Record<string, unknown>;
  rowType?: DimensionRows
}
```

---

### `CollaborativePresenceConfig`

```ts
interface CollaborativePresenceConfig {
  enabled?: boolean;
  showLabels?: boolean;
  staleAfterMs?: number;
  users?: CollaborativePresenceUser[];
  remoteEdits?: CollaborativePresenceRowPatch[]
}
```

---

### `ResolvedCollaborativePresenceConfig`

```ts
interface ResolvedCollaborativePresenceConfig {
  enabled: boolean;
  showLabels: boolean;
  staleAfterMs?: number;
  users: CollaborativePresenceUser[];
  remoteEdits: CollaborativePresenceRowPatch[]
}
```

---

### `CollaborativePresenceRect`

```ts
interface CollaborativePresenceRect {
  left: number;
  top: number;
  width: number;
  height: number
}
```

---

### `CollaborativePresenceMarker`

```ts
interface CollaborativePresenceMarker {
  kind: 'focus' | 'range';
  user: CollaborativePresenceUser;
  rect: CollaborativePresenceRect;
  colType: DimensionCols;
  rowType: DimensionRows
}
```

---

### `normalizeCollaborativePresenceCell`

```ts
export function normalizeCollaborativePresenceCell(
  cell: CollaborativePresenceCellRef,
): Required<CollaborativePresenceCellRef>;
```

---

### `normalizeCollaborativePresenceRange`

```ts
export function normalizeCollaborativePresenceRange(
  range: CollaborativePresenceRangeRef,
): Required<CollaborativePresenceRangeRef>;
```

---

### `resolveCollaborativePresenceConfig`

```ts
export function resolveCollaborativePresenceConfig(
  config?: CollaborativePresenceConfig,
): ResolvedCollaborativePresenceConfig;
```

---

### `getVisibleCollaborativePresenceUsers`

```ts
export function getVisibleCollaborativePresenceUsers(
  config: ResolvedCollaborativePresenceConfig,
  now = Date.now(),
): CollaborativePresenceUser[];
```

---

### `resolveCollaborativePresenceMarkers`

```ts
export function resolveCollaborativePresenceMarkers(
  _grid: HTMLElement,
  users: CollaborativePresenceUser[],
  providers?: PluginProviders,
): CollaborativePresenceMarker[];
```

---

### `applyCollaborativePresenceRowPatches`

Applies row patches directly into the RevoGrid data store without triggering
a full source reset or plugin re-initialization.

`rowIndex` is treated as a **source (physical) index** — the position in the
original data array — so patches always target the correct row regardless of
the current sort or reorder state.

Per rowType:
  1. Mutate source[rowIndex] directly for each patch
  2. store.set('source', [...]) once — triggers a single targeted reactive update

Mirrors the low-level write pattern in spreadsheet.simulation.ts.

```ts
export function applyCollaborativePresenceRowPatches(
  providers: PluginProviders,
  patches: CollaborativePresenceRowPatch[],
): void;
```

---

### `CollaborativePresenceLayer`

Manages per-viewport slot overlay elements and draws presence markers into them.
Each viewport type combination (colType × rowType) gets its own slot div so markers
clip and scroll correctly within their viewport.

```ts
class CollaborativePresenceLayer {
  render(markers: CollaborativePresenceMarker[], showLabels: boolean): void;

  destroy(): void;
}
```

---

### `resolveCollaborativePresenceCellRect`

```ts
export function resolveCollaborativePresenceCellRect(
  providers: PluginProviders | undefined,
  cell: PresenceCell,
): CollaborativePresenceRect | undefined;
```

---

### `resolveCollaborativePresenceRangeRect`

```ts
export function resolveCollaborativePresenceRangeRect(
  providers: PluginProviders | undefined,
  range: PresenceRange,
): CollaborativePresenceRect | undefined;
```
