@docx-editor.dev/core/collaboration

@docx-editor.dev/core/collaboration — provider-neutral collaboration contracts.

This lane names the attachment between the canonical tree and an optional replication implementation. It performs no networking and imports no CRDT.

Functions (2)

isCollaborationFailureCodefunctionSource ↗

True when value is a [CollaborationFailureCode](CollaborationFailureCode) member.

declare function isCollaborationFailureCode(value: string): value is CollaborationFailureCode;

safeParticipantColorfunctionSource ↗

Return value when it is a color this engine can safely paint, otherwise undefined.

declare function safeParticipantColor(value: string | undefined): string | undefined;

Interfaces (13)

CollaborationEditorPositioninterfaceSource ↗

A position in this replica's editor tree. Unlike a stable paragraph id, which a remote change can rename on one replica, a node id names one paragraph of this editor.

interface CollaborationEditorPosition
MemberTypeSummary
nodeIdstringThe node id of the paragraph in this replica's editor tree.
offsetnumberA UTF-16 offset in the paragraph's text.

CollaborationEditorSelectioninterfaceSource ↗

A selection in this replica's editor.

interface CollaborationEditorSelection
MemberTypeSummary
anchorCollaborationEditorPositionWhere the selection starts: it stays put when the selection extends.
headCollaborationEditorPositionWhere the selection ends: the caret.

CollaborationFailureinterfaceSource ↗

One collaboration failure: a typed code plus optional free-form detail.

interface CollaborationFailure
MemberTypeSummary
codeCollaborationFailureCodeStable code for application logic.
detail?stringBounded diagnostic text for logs. Not a parsing contract.

CollaborationIdentityinterfaceSource ↗

Human or automation identity attached to authored collaboration transactions.

interface CollaborationIdentity
MemberTypeSummary
actorIdstringStable author id, 1 to 256 characters after trimming. Recorded on authored changes.
color?stringPresence color, at most 64 characters. An unsafe CSS color falls back to the accent.
namestringDisplay name, 1 to 256 characters after trimming.
role?'human' | 'agent'`agent` for automation. Defaults to `human`.

CollaborationLocalSelectioninterfaceSource ↗

Selection published by the local editor through ephemeral awareness.

Publish an anchor address and a head address. Do not materialize every covered paragraph.

interface CollaborationLocalSelection
MemberTypeSummary
anchorCollaborationSelectionAddressWhere the selection starts.
headCollaborationSelectionAddressWhere the selection ends: the caret.
kind?CollaborationSelectionKind`cells` for a table cell rectangle; absent for a character range.

CollaborationModuleContributioninterfaceSource ↗

What a collaboration module contributes: the replica the surface attaches.

interface CollaborationModuleContribution
MemberTypeSummary
sessionEditorCollaborationSessionA ready session. The host creates the Yjs room, then wraps it with `collaborationModule({ session })`.

CollaborationParticipantinterfaceSource ↗

One validated identity visible through ephemeral collaboration presence.

interface CollaborationParticipant extends CollaborationIdentity
MemberTypeSummary
isLocalbooleanTrue for this replica's own participant.

CollaborationRemoteSelectioninterfaceSource ↗

Stable remote selection resolved into this replica's canonical paragraph addresses.

Anchor and head may name different paragraphs. A collapsed caret is the same address twice.

interface CollaborationRemoteSelection
MemberTypeSummary
actorIdstringThe participant's `actorId`.
anchorCollaborationRemoteSelectionAddressWhere the selection starts.
color?stringThe participant's presence color, when it published a safe one.
headCollaborationRemoteSelectionAddressWhere the selection ends: the remote caret.
kind?CollaborationSelectionKind`cells` for a table cell rectangle; absent for a character range.
namestringThe participant's display name.

CollaborationRemoteSelectionAddressinterfaceSource ↗

One endpoint of a remote selection resolved into this replica's canonical addresses.

paragraphId is the stable w14:paraId. nodeId is replica-local and is used to paint.

interface CollaborationRemoteSelectionAddress
MemberTypeSummary
nodeIdstringThe paragraph's node id in this replica's editor tree.
offsetnumberA UTF-16 offset in the paragraph's text.
paragraphIdstringThe stable `w14:paraId` of the paragraph.

CollaborationSelectionAddressinterfaceSource ↗

One endpoint of a published selection: a stable paragraph id and a UTF-16 offset.

The wire payload carries only these two endpoints. The receiver walks its own canonical tree to find the paragraphs between them, so a select-all does not grow with document size.

interface CollaborationSelectionAddress
MemberTypeSummary
offsetnumberA UTF-16 offset in the paragraph's text.
paragraphIdstringThe stable `w14:paraId` of the paragraph.

CollaborationSelectionMoveinterfaceSource ↗

Where a collaboration session carried the local selection across the last remote change.

The editor uses to only while its selection still equals from: a selection the user moved since is the user's.

interface CollaborationSelectionMove
MemberTypeSummary
fromCollaborationEditorSelectionThe selection the session carried, as the editor last published it.
toCollaborationEditorSelectionWhere it stands now: beside the same characters, wherever they show.

CollaborationStatusSnapshotinterfaceSource ↗

Cached status read. Same reference until one of its fields changes.

interface CollaborationStatusSnapshot
MemberTypeSummary
failureCount?numberHow many failures this session has recorded. It changes with each new failure, also when its code and detail repeat the last one, as a refused edit refused again does. Absent from a session that does not count.
lastFailureCollaborationFailure | undefinedThe most recent `error` reason. Kept after the replica recovers.
reasonCollaborationFailure | undefinedWhy the replica holds `status`, or `undefined` when nothing is wrong.
recovering?booleanThe session is in `error` but heals by itself: it realigns on the next clean update and returns to its previous status. A host shows a passing notice, not a rejoin action. Absent means false.
statusCollaborationStatusCurrent lifecycle state.
waiting?booleanEdits wait: the room sent an update that depends on one still on its way, and an edit made now could touch the text it changes. The editor refuses edits meanwhile, with `collaboration-session-not-ready`, and accepts them again when the update arrives or the wait times out. Absent means false.

EditorCollaborationSessioninterfaceSource ↗

Optional replication session attached to an editor or headless automation host.

Implementations own replication state only. The attached document port remains the authored authority for reads, layout, paint, and save.

interface EditorCollaborationSession
MemberTypeSummary
attachAttach the editor's document port and start replicating. Returns the detach function. A second, different port moves the session to `error` with `port-already-attached`.
attachedbooleanWhether an editor has attached its document port to this replica.
canRedoWhether the shared undo history holds a local step to redo.
canUndoWhether the shared undo history holds a local step to undo.
destroyStop replicating and release listeners. The status becomes `destroyed`.
documentIdstringThe room's document id. An attached port must carry the same id.
flushPendingJournalsPublish queued local journals to shared state.
gateOperationsCheck whether `ops` may commit now. Returns `null` to admit them, or the refusal code. Call it before every store transaction a custom port commits.
historySelectionThe selection the last `undo` or `redo` restored: the one its author had before the undone change. Null when the step recorded none. Optional; a session without it leaves the editor to place the caret at the change.
identityCollaborationIdentityThe validated local identity.
participantsParticipants in presence, this replica included. Capped at 256.
redoRedo this participant's last undone step. Returns false when refused.
remoteSelectionMoveWhere the last remote change carried the local selection, on the shared characters beside its endpoints, and the selection it was carried from, both in the editor's paragraph node ids. Null when the session could not carry it. Optional; without it the editor maps the selection by text.
remoteSelectionsOther participants' selections, resolved into this replica's addresses.
sessionIdstringUnique identity for this attachment lifetime. It prevents operation ID reuse after reconnect.
setLocalSelectionPublish the local selection through presence. `null` clears it.
statusCurrent lifecycle state.
statusSnapshotCached status, current reason, and last failure.
subscribeParticipantsCall `listener` when the participant list changes. Returns the unsubscribe function.
subscribeRemoteSelectionsCall `listener` when a remote selection changes. Returns the unsubscribe function.
subscribeStatusCall `listener` on each status or reason change. Returns the unsubscribe function.
undoUndo this participant's last step; others' edits stay. Returns false when refused.

Type aliases (3)

CollaborationFailureCodetypeSource ↗

Why a replica refused work, left ready, or failed a schema check.

Free-form extras (a transport phrase, a blob key, a store refusal) travel in [CollaborationFailure.detail](CollaborationFailure.detail), not here. Branch on the code; log the detail.

Codes are grouped by cause, and each group comment names the host action. In error, only a remote update that is not applied yet, or one refused local edit, heals on its own. The failure codes table in the collaboration reference lists every code. transport-disconnected and authentication-failed need opposite answers: wait for the first; refresh the credential and rejoin for the second. room-generation-changed means the server compacted the room while this replica was away: save a copy if it holds unsent changes, then rejoin.

type CollaborationFailureCode = 
/** Edit refused by the session gate. The status does not change. Wait for `ready`. */
'collaboration-session-destroyed' | 'collaboration-session-not-attached' | 'collaboration-session-not-ready' | 'collaboration-text-limit' | 'experimental-collaboration-body-text-only'
/** Factory input rejected before joining. Fix the value the host passed. */
 | 'invalid-document-id' | 'invalid-identity' | 'invalid-identity-color' | 'invalid-session-id'
/** Join or seed did not complete. Connect the provider, check the room id, and retry. */
 | 'already-initialized' | 'document-id-mismatch' | 'initialization-aborted' | 'initialization-timeout' | 'not-initialized'
/** The seed document cannot seed a room. Fix the file. */
 | 'baseline-too-large' | 'blob-read' | 'invalid-baseline' | 'missing-local-blob' | 'no-main-document-part'
/** This client and the room have different formats. Terminal. Save local work. */
 | 'collaboration-format-mismatch' | 'protocol-version-mismatch' | 'schema-version-mismatch'
/** The room is unusable. Terminal. Create a new room from saved bytes. */
 | 'blob-digest-mismatch' | 'concurrent-seed' | 'port-already-attached'
/** A remote update is not applied yet. Heals when a later update arrives. Wait. */
 | 'duplicate-paragraph-id' | 'invalid-relationships' | 'materialize-dropped-content' | 'missing-blob' | 'missing-root' | 'remote-apply-failed' | 'unknown-paragraph-id'
/** Over a resource limit. A local edit realigns; shared state over a limit is terminal. */
 | 'blob-store-full' | 'blob-too-large' | 'invalid-blob-descriptor' | 'invalid-bound' | 'invalid-logical-id' | 'invalid-string' | 'prototype-key' | 'text-too-long' | 'too-many-attributes' | 'too-many-children' | 'too-many-nodes' | 'too-many-parts' | 'too-many-relationships' | 'tree-too-deep' | 'unknown-logical-id' | 'unsafe-part-name'
/** Transport state. Only `transport-disconnected` recovers on its own. */
 | 'authentication-failed' | 'room-generation-changed' | 'transport' | 'transport-disconnected'
/** Reserved for a room server that refuses a saved room. Passed through, never emitted. */
 | 'invalid-saved-room' | 'saved-room-unavailable'
/** @deprecated Emitted by nothing. Kept for compatibility; do not branch on these. */
 | 'baseline-digest-mismatch' | 'experimental-collaboration-existing-paragraphs-only' | 'experimental-collaboration-text-only' | 'experimental-collaboration-untracked-text-only' | 'immutable-baseline-changed' | 'immutable-metadata-changed' | 'invalid-shared-metadata' | 'local-mirror-failed' | 'paragraph-set-mismatch' | 'shared-schema-invalid' | 'unsupported-root-key';

CollaborationSelectionKindtypeSource ↗

How a published selection covers the document.

Absent or omitted means a character range. cells means the table rectangle whose corner cells contain the two endpoints. The payload still carries only those endpoints, so a large table selection does not grow with the number of selected cells.

type CollaborationSelectionKind = 'cells';

CollaborationStatustypeSource ↗

Lifecycle state of one collaboration replica.

One axis, because the only question a host has to answer is whether to tell the reader to wait or to reload:

- initializing — joining. Edits are refused. Recovers on its own. - ready — replicating. Accepts edits. - disconnected — the transport dropped. The replica is intact and recovers on its own, so wait rather than reload. Edits continue by default, and the buffered updates merge on reconnect. A session created with offlineEditing: false refuses them until reconnect. - error — this replica does not agree with the room. Edits are refused. [CollaborationStatusSnapshot.reason](CollaborationStatusSnapshot.reason) says why. A remote update the replica could not apply yet heals when a later update completes shared state ([CollaborationStatusSnapshot.recovering](CollaborationStatusSnapshot.recovering)). A format or version mismatch needs an upgrade of this client or the room; every other cause needs a rejoin. - destroyed — torn down. Terminal.

type CollaborationStatus = 'initializing' | 'ready' | 'disconnected' | 'error' | 'destroyed';