ObjectStackObjectStack

Collaboration

Collaboration protocol schemas

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

Source: packages/spec/src/system/collaboration.zod.ts

TypeScript Usage

import { AwarenessEventSchema, AwarenessSessionSchema, AwarenessUpdateSchema, AwarenessUserStateSchema, CRDTMergeResultSchema, CRDTStateSchema, CRDTType, CollaborationMode, CollaborationSessionSchema, CollaborationSessionConfigSchema, CollaborativeCursorSchema, CounterOperationSchema, CursorColorPreset, CursorSelectionSchema, CursorStyleSchema, CursorUpdateSchema, GCounterSchema, LWWRegisterSchema, ORSetSchema, ORSetElementSchema, OTComponentSchema, OTOperationSchema, OTOperationType, OTTransformResultSchema, PNCounterSchema, TextCRDTOperationSchema, TextCRDTStateSchema, UserActivityStatus, VectorClockSchema } 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 = AwarenessEventSchema.parse(data);

AwarenessEvent

Properties

PropertyTypeRequiredDescription
eventIdstringEvent identifier
sessionIdstringSession identifier
eventTypeEnum<'user.joined' | 'user.left' | 'user.updated' | 'session.created' | 'session.ended'>Type of awareness event
userIdstringoptionalUser involved in event
timestampstringISO 8601 datetime of event
payloadanyEvent payload

AwarenessSession

Properties

PropertyTypeRequiredDescription
sessionIdstringSession identifier
documentIdstringoptionalDocument ID this session is for
users{ userId: string; sessionId: string; userName: string; userAvatar?: string; … }[]Active users in session
startedAtstringISO 8601 datetime when session started
lastUpdatestringISO 8601 datetime of last update
metadataRecord<string, any>optionalSession metadata

Nested Shape: AwarenessSession.users[number]

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
userNamestringDisplay name
userAvatarstringoptionalUser avatar URL
statusEnum<'active' | 'idle' | 'viewing' | 'disconnected'>Current activity status
currentDocumentstringoptionalDocument ID user is currently editing
currentViewstringoptionalCurrent view/page user is on
lastActivitystringISO 8601 datetime of last activity
joinedAtstringISO 8601 datetime when user joined session
permissionsstring[]optionalUser permissions in this session
metadataRecord<string, any>optionalAdditional user state metadata

AwarenessUpdate

Properties

PropertyTypeRequiredDescription
statusEnum<'active' | 'idle' | 'viewing' | 'disconnected'>optionalUpdated status
currentDocumentstringoptionalUpdated current document
currentViewstringoptionalUpdated current view
metadataRecord<string, any>optionalUpdated metadata

AwarenessUserState

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
userNamestringDisplay name
userAvatarstringoptionalUser avatar URL
statusEnum<'active' | 'idle' | 'viewing' | 'disconnected'>Current activity status
currentDocumentstringoptionalDocument ID user is currently editing
currentViewstringoptionalCurrent view/page user is on
lastActivitystringISO 8601 datetime of last activity
joinedAtstringISO 8601 datetime when user joined session
permissionsstring[]optionalUser permissions in this session
metadataRecord<string, any>optionalAdditional user state metadata

CRDTMergeResult

Properties

PropertyTypeRequiredDescription
state{ type: 'lww-register'; value: any; timestamp: string; replicaId: string; … } | { type: 'g-counter'; counts: Record<string, integer> } | { type: 'pn-counter'; positive: Record<string, integer>; negative: Record<string, integer> } | { type: 'or-set'; elements: object[] } | … +1 moreMerged CRDT state
conflicts{ type: string; description: string; resolved: boolean }[]optionalConflicts encountered during merge

Nested Shape: CRDTMergeResult.state[type='lww-register']

PropertyTypeRequiredDescription
type'lww-register'
valueanyCurrent register value
timestampstringISO 8601 datetime of last write
replicaIdstringID of replica that performed last write
vectorClock{ clock: Record<string, integer> }optionalOptional vector clock for causality tracking

Nested Shape: CRDTMergeResult.state[type='g-counter']

PropertyTypeRequiredDescription
type'g-counter'
countsRecord<string, integer>Map of replica ID to count

Nested Shape: CRDTMergeResult.state[type='pn-counter']

PropertyTypeRequiredDescription
type'pn-counter'
positiveRecord<string, integer>Positive increments per replica
negativeRecord<string, integer>Negative increments per replica

Nested Shape: CRDTMergeResult.state[type='or-set']

PropertyTypeRequiredDescription
type'or-set'
elements{ value: any; timestamp: string; replicaId: string; uid: string; … }[]Set elements with metadata

Nested Shape: CRDTMergeResult.state[type='text']

PropertyTypeRequiredDescription
type'text'
documentIdstringDocument identifier
contentstringCurrent text content
operations{ operationId: string; replicaId: string; position: integer; insert?: string; … }[]History of operations
lamportClockintegerCurrent Lamport clock value
vectorClock{ clock: Record<string, integer> }Vector clock for causality

Nested Shape: CRDTMergeResult.conflicts[number]

PropertyTypeRequiredDescription
typestringConflict type
descriptionstringConflict description
resolvedbooleanWhether conflict was automatically resolved

CRDTState

Union Options

This schema accepts one of the following structures:

Option 1

Type: lww-register

Properties

PropertyTypeRequiredDescription
type'lww-register'
valueanyCurrent register value
timestampstringISO 8601 datetime of last write
replicaIdstringID of replica that performed last write
vectorClock{ clock: Record<string, integer> }optionalOptional vector clock for causality tracking

Nested Shape: CRDTState[type='lww-register'].vectorClock

PropertyTypeRequiredDescription
clockRecord<string, integer>Map of replica ID to logical timestamp

Option 2

Type: g-counter

Properties

PropertyTypeRequiredDescription
type'g-counter'
countsRecord<string, integer>Map of replica ID to count

Option 3

Type: pn-counter

Properties

PropertyTypeRequiredDescription
type'pn-counter'
positiveRecord<string, integer>Positive increments per replica
negativeRecord<string, integer>Negative increments per replica

Option 4

Type: or-set

Properties

PropertyTypeRequiredDescription
type'or-set'
elements{ value: any; timestamp: string; replicaId: string; uid: string; … }[]Set elements with metadata

Nested Shape: CRDTState[type='or-set'].elements[number]

PropertyTypeRequiredDescription
valueanyElement value
timestampstringAddition timestamp
replicaIdstringReplica that added the element
uidstringUnique identifier for this addition
removedbooleanoptional (default: false)Whether element has been removed

Option 5

Type: text

Properties

PropertyTypeRequiredDescription
type'text'
documentIdstringDocument identifier
contentstringCurrent text content
operations{ operationId: string; replicaId: string; position: integer; insert?: string; … }[]History of operations
lamportClockintegerCurrent Lamport clock value
vectorClock{ clock: Record<string, integer> }Vector clock for causality

Nested Shape: CRDTState[type='text'].operations[number]

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
replicaIdstringReplica identifier
positionintegerPosition in document
insertstringoptionalText to insert
deleteintegeroptionalNumber of characters to delete
timestampstringISO 8601 datetime of operation
lamportTimestampintegerLamport timestamp for ordering

Nested Shape: CRDTState[type='text'].vectorClock

PropertyTypeRequiredDescription
clockRecord<string, integer>Map of replica ID to logical timestamp


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

PropertyTypeRequiredDescription
sessionIdstringSession identifier
documentIdstringDocument identifier
config{ mode: Enum<'ot' | 'crdt' | 'lock' | 'hybrid'>; enableCursorSharing: boolean; enablePresence: boolean; enableAwareness: boolean; … }Session configuration
users{ userId: string; sessionId: string; userName: string; userAvatar?: string; … }[]Active users
cursors{ userId: string; sessionId: string; documentId: string; userName: string; … }[]Active cursors
versionintegerCurrent document version
operations({ operationId: string; documentId: string; userId: string; sessionId: string; … } | { operationId: string; replicaId: string; position: integer; insert?: string; … })[]optionalRecent operations
createdAtstringISO 8601 datetime when session was created
lastActivitystringISO 8601 datetime of last activity
statusEnum<'active' | 'idle' | 'ended'>Session status

Nested Shape: CollaborationSession.config

PropertyTypeRequiredDescription
modeEnum<'ot' | 'crdt' | 'lock' | 'hybrid'>Collaboration mode to use
enableCursorSharingbooleanoptional (default: true)Enable cursor sharing
enablePresencebooleanoptional (default: true)Enable presence tracking
enableAwarenessbooleanoptional (default: true)Enable awareness state
maxUsersintegeroptionalMaximum concurrent users
idleTimeoutintegeroptional (default: 300000)Idle timeout in milliseconds
conflictResolutionEnum<'ot' | 'crdt' | 'manual'>optional (default: "ot")Conflict resolution strategy
persistencebooleanoptional (default: true)Enable operation persistence
snapshot{ enabled: boolean; interval: integer }optionalSnapshot configuration

Nested Shape: CollaborationSession.users[number]

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
userNamestringDisplay name
userAvatarstringoptionalUser avatar URL
statusEnum<'active' | 'idle' | 'viewing' | 'disconnected'>Current activity status
currentDocumentstringoptionalDocument ID user is currently editing
currentViewstringoptionalCurrent view/page user is on
lastActivitystringISO 8601 datetime of last activity
joinedAtstringISO 8601 datetime when user joined session
permissionsstring[]optionalUser permissions in this session
metadataRecord<string, any>optionalAdditional user state metadata

Nested Shape: CollaborationSession.cursors[number]

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
documentIdstringDocument identifier
userNamestringDisplay name of user
position{ line: integer; column: integer }Current cursor position
selection{ anchor: object; focus: object; direction?: Enum<'forward' | 'backward'> }optionalCurrent text selection
style{ color: Enum<'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'orange' | 'pink' | 'teal' | 'indigo' | 'cyan'> | string; opacity: number; label?: string; showLabel: boolean; … }Visual style for this cursor
isTypingbooleanoptional (default: false)Whether user is currently typing
lastUpdatestringISO 8601 datetime of last cursor update
metadataRecord<string, any>optionalAdditional cursor metadata

Nested Shape: CollaborationSession.operations[number][option 1]

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
documentIdstringDocument identifier
userIdstringUser who created the operation
sessionIdstringSession identifier
components({ type: 'insert'; text: string; attributes?: Record<string, any> } | { type: 'delete'; count: integer } | { type: 'retain'; count: integer; attributes?: Record<string, any> })[]Operation components
baseVersionintegerDocument version this operation is based on
timestampstringISO 8601 datetime when operation was created
metadataRecord<string, any>optionalAdditional operation metadata

Nested Shape: CollaborationSession.operations[number][option 2]

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
replicaIdstringReplica identifier
positionintegerPosition in document
insertstringoptionalText to insert
deleteintegeroptionalNumber of characters to delete
timestampstringISO 8601 datetime of operation
lamportTimestampintegerLamport timestamp for ordering

CollaborationSessionConfig

Properties

PropertyTypeRequiredDescription
modeEnum<'ot' | 'crdt' | 'lock' | 'hybrid'>Collaboration mode to use
enableCursorSharingbooleanoptional (default: true)Enable cursor sharing
enablePresencebooleanoptional (default: true)Enable presence tracking
enableAwarenessbooleanoptional (default: true)Enable awareness state
maxUsersintegeroptionalMaximum concurrent users
idleTimeoutintegeroptional (default: 300000)Idle timeout in milliseconds
conflictResolutionEnum<'ot' | 'crdt' | 'manual'>optional (default: "ot")Conflict resolution strategy
persistencebooleanoptional (default: true)Enable operation persistence
snapshot{ enabled: boolean; interval: integer }optionalSnapshot configuration

Nested Shape: CollaborationSessionConfig.snapshot

PropertyTypeRequiredDescription
enabledbooleanEnable periodic snapshots
intervalintegerSnapshot interval in milliseconds

CollaborativeCursor

Properties

PropertyTypeRequiredDescription
userIdstringUser identifier
sessionIdstringSession identifier
documentIdstringDocument identifier
userNamestringDisplay name of user
position{ line: integer; column: integer }Current cursor position
selection{ anchor: object; focus: object; direction?: Enum<'forward' | 'backward'> }optionalCurrent text selection
style{ color: Enum<'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'orange' | 'pink' | 'teal' | 'indigo' | 'cyan'> | string; opacity: number; label?: string; showLabel: boolean; … }Visual style for this cursor
isTypingbooleanoptional (default: false)Whether user is currently typing
lastUpdatestringISO 8601 datetime of last cursor update
metadataRecord<string, any>optionalAdditional cursor metadata

Nested Shape: CollaborativeCursor.position

PropertyTypeRequiredDescription
lineintegerCursor line number (0-indexed)
columnintegerCursor column number (0-indexed)

Nested Shape: CollaborativeCursor.selection

PropertyTypeRequiredDescription
anchor{ line: integer; column: integer }Selection anchor (start point)
focus{ line: integer; column: integer }Selection focus (end point)
directionEnum<'forward' | 'backward'>optionalSelection direction

Nested Shape: CollaborativeCursor.style

PropertyTypeRequiredDescription
colorEnum<'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'orange' | 'pink' | 'teal' | 'indigo' | 'cyan'> | stringCursor color (preset or custom hex)
opacitynumberoptional (default: 1)Cursor opacity (0-1)
labelstringoptionalLabel to display with cursor (usually username)
showLabelbooleanoptional (default: true)Whether to show label
pulseOnUpdatebooleanoptional (default: true)Whether to pulse when cursor moves

CounterOperation

Properties

PropertyTypeRequiredDescription
replicaIdstringReplica identifier
deltaintegerChange amount (positive for increment, negative for decrement)
timestampstringISO 8601 datetime of operation

CursorColorPreset

Allowed Values

  • blue
  • green
  • red
  • yellow
  • purple
  • orange
  • pink
  • teal
  • indigo
  • cyan

CursorSelection

Properties

PropertyTypeRequiredDescription
anchor{ line: integer; column: integer }Selection anchor (start point)
focus{ line: integer; column: integer }Selection focus (end point)
directionEnum<'forward' | 'backward'>optionalSelection direction

Nested Shape: CursorSelection.anchor

PropertyTypeRequiredDescription
lineintegerAnchor line number
columnintegerAnchor column number

Nested Shape: CursorSelection.focus

PropertyTypeRequiredDescription
lineintegerFocus line number
columnintegerFocus column number

CursorStyle

Properties

PropertyTypeRequiredDescription
colorEnum<'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'orange' | 'pink' | 'teal' | 'indigo' | 'cyan'> | stringCursor color (preset or custom hex)
opacitynumberoptional (default: 1)Cursor opacity (0-1)
labelstringoptionalLabel to display with cursor (usually username)
showLabelbooleanoptional (default: true)Whether to show label
pulseOnUpdatebooleanoptional (default: true)Whether to pulse when cursor moves

CursorUpdate

Properties

PropertyTypeRequiredDescription
position{ line: integer; column: integer }optionalUpdated cursor position
selection{ anchor: object; focus: object; direction?: Enum<'forward' | 'backward'> }optionalUpdated selection
isTypingbooleanoptionalUpdated typing state
metadataRecord<string, any>optionalUpdated metadata

Nested Shape: CursorUpdate.selection

PropertyTypeRequiredDescription
anchor{ line: integer; column: integer }Selection anchor (start point)
focus{ line: integer; column: integer }Selection focus (end point)
directionEnum<'forward' | 'backward'>optionalSelection direction

GCounter

Properties

PropertyTypeRequiredDescription
type'g-counter'
countsRecord<string, integer>Map of replica ID to count

LWWRegister

Properties

PropertyTypeRequiredDescription
type'lww-register'
valueanyCurrent register value
timestampstringISO 8601 datetime of last write
replicaIdstringID of replica that performed last write
vectorClock{ clock: Record<string, integer> }optionalOptional vector clock for causality tracking

Nested Shape: LWWRegister.vectorClock

PropertyTypeRequiredDescription
clockRecord<string, integer>Map of replica ID to logical timestamp

ORSet

Properties

PropertyTypeRequiredDescription
type'or-set'
elements{ value: any; timestamp: string; replicaId: string; uid: string; … }[]Set elements with metadata

Nested Shape: ORSet.elements[number]

PropertyTypeRequiredDescription
valueanyElement value
timestampstringAddition timestamp
replicaIdstringReplica that added the element
uidstringUnique identifier for this addition
removedbooleanoptional (default: false)Whether element has been removed

ORSetElement

Properties

PropertyTypeRequiredDescription
valueanyElement value
timestampstringAddition timestamp
replicaIdstringReplica that added the element
uidstringUnique identifier for this addition
removedbooleanoptional (default: false)Whether element has been removed

OTComponent

Union Options

This schema accepts one of the following structures:

Option 1

Type: insert

Properties

PropertyTypeRequiredDescription
type'insert'
textstringText to insert
attributesRecord<string, any>optionalText formatting attributes (e.g., bold, italic)

Option 2

Type: delete

Properties

PropertyTypeRequiredDescription
type'delete'
countintegerNumber of characters to delete

Option 3

Type: retain

Properties

PropertyTypeRequiredDescription
type'retain'
countintegerNumber of characters to retain
attributesRecord<string, any>optionalAttribute changes to apply


OTOperation

Properties

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
documentIdstringDocument identifier
userIdstringUser who created the operation
sessionIdstringSession identifier
components({ type: 'insert'; text: string; attributes?: Record<string, any> } | { type: 'delete'; count: integer } | { type: 'retain'; count: integer; attributes?: Record<string, any> })[]Operation components
baseVersionintegerDocument version this operation is based on
timestampstringISO 8601 datetime when operation was created
metadataRecord<string, any>optionalAdditional operation metadata

Nested Shape: OTOperation.components[number][type='insert']

PropertyTypeRequiredDescription
type'insert'
textstringText to insert
attributesRecord<string, any>optionalText formatting attributes (e.g., bold, italic)

Nested Shape: OTOperation.components[number][type='delete']

PropertyTypeRequiredDescription
type'delete'
countintegerNumber of characters to delete

Nested Shape: OTOperation.components[number][type='retain']

PropertyTypeRequiredDescription
type'retain'
countintegerNumber of characters to retain
attributesRecord<string, any>optionalAttribute changes to apply

OTOperationType

Allowed Values

  • insert
  • delete
  • retain

OTTransformResult

Properties

PropertyTypeRequiredDescription
operation{ operationId: string; documentId: string; userId: string; sessionId: string; … }Transformed operation
transformedbooleanWhether transformation was applied
conflictsstring[]optionalConflict descriptions if any

Nested Shape: OTTransformResult.operation

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
documentIdstringDocument identifier
userIdstringUser who created the operation
sessionIdstringSession identifier
components({ type: 'insert'; text: string; attributes?: Record<string, any> } | { type: 'delete'; count: integer } | { type: 'retain'; count: integer; attributes?: Record<string, any> })[]Operation components
baseVersionintegerDocument version this operation is based on
timestampstringISO 8601 datetime when operation was created
metadataRecord<string, any>optionalAdditional operation metadata

PNCounter

Properties

PropertyTypeRequiredDescription
type'pn-counter'
positiveRecord<string, integer>Positive increments per replica
negativeRecord<string, integer>Negative increments per replica

TextCRDTOperation

Properties

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
replicaIdstringReplica identifier
positionintegerPosition in document
insertstringoptionalText to insert
deleteintegeroptionalNumber of characters to delete
timestampstringISO 8601 datetime of operation
lamportTimestampintegerLamport timestamp for ordering

TextCRDTState

Properties

PropertyTypeRequiredDescription
type'text'
documentIdstringDocument identifier
contentstringCurrent text content
operations{ operationId: string; replicaId: string; position: integer; insert?: string; … }[]History of operations
lamportClockintegerCurrent Lamport clock value
vectorClock{ clock: Record<string, integer> }Vector clock for causality

Nested Shape: TextCRDTState.operations[number]

PropertyTypeRequiredDescription
operationIdstringUnique operation identifier
replicaIdstringReplica identifier
positionintegerPosition in document
insertstringoptionalText to insert
deleteintegeroptionalNumber of characters to delete
timestampstringISO 8601 datetime of operation
lamportTimestampintegerLamport timestamp for ordering

Nested Shape: TextCRDTState.vectorClock

PropertyTypeRequiredDescription
clockRecord<string, integer>Map of replica ID to logical timestamp

UserActivityStatus

Allowed Values

  • active
  • idle
  • viewing
  • disconnected

VectorClock

Properties

PropertyTypeRequiredDescription
clockRecord<string, integer>Map of replica ID to logical timestamp

On this page

TypeScript UsageAwarenessEventPropertiesAwarenessSessionPropertiesNested Shape: AwarenessSession.users[number]AwarenessUpdatePropertiesAwarenessUserStatePropertiesCRDTMergeResultPropertiesNested Shape: CRDTMergeResult.state[type='lww-register']Nested Shape: CRDTMergeResult.state[type='g-counter']Nested Shape: CRDTMergeResult.state[type='pn-counter']Nested Shape: CRDTMergeResult.state[type='or-set']Nested Shape: CRDTMergeResult.state[type='text']Nested Shape: CRDTMergeResult.conflicts[number]CRDTStateUnion OptionsOption 1PropertiesNested Shape: CRDTState[type='lww-register'].vectorClockOption 2PropertiesOption 3PropertiesOption 4PropertiesNested Shape: CRDTState[type='or-set'].elements[number]Option 5PropertiesNested Shape: CRDTState[type='text'].operations[number]Nested Shape: CRDTState[type='text'].vectorClockCRDTTypeAllowed ValuesCollaborationModeAllowed ValuesCollaborationSessionPropertiesNested Shape: CollaborationSession.configNested Shape: CollaborationSession.users[number]Nested Shape: CollaborationSession.cursors[number]Nested Shape: CollaborationSession.operations[number][option 1]Nested Shape: CollaborationSession.operations[number][option 2]CollaborationSessionConfigPropertiesNested Shape: CollaborationSessionConfig.snapshotCollaborativeCursorPropertiesNested Shape: CollaborativeCursor.positionNested Shape: CollaborativeCursor.selectionNested Shape: CollaborativeCursor.styleCounterOperationPropertiesCursorColorPresetAllowed ValuesCursorSelectionPropertiesNested Shape: CursorSelection.anchorNested Shape: CursorSelection.focusCursorStylePropertiesCursorUpdatePropertiesNested Shape: CursorUpdate.selectionGCounterPropertiesLWWRegisterPropertiesNested Shape: LWWRegister.vectorClockORSetPropertiesNested Shape: ORSet.elements[number]ORSetElementPropertiesOTComponentUnion OptionsOption 1PropertiesOption 2PropertiesOption 3PropertiesOTOperationPropertiesNested Shape: OTOperation.components[number][type='insert']Nested Shape: OTOperation.components[number][type='delete']Nested Shape: OTOperation.components[number][type='retain']OTOperationTypeAllowed ValuesOTTransformResultPropertiesNested Shape: OTTransformResult.operationPNCounterPropertiesTextCRDTOperationPropertiesTextCRDTStatePropertiesNested Shape: TextCRDTState.operations[number]Nested Shape: TextCRDTState.vectorClockUserActivityStatusAllowed ValuesVectorClockProperties