@docx-editor.dev/core/collaboration/replication

@docx-editor.dev/core/collaboration/replication — the seam a replication implementation binds to, not the surface a host consumes.

Everything here exists for the layer BETWEEN a CRDT and the canonical tree: the document port an adapter writes through, the primitive journal it reads, and the descriptors that journal is made of. A host that renders presence and reads a status needs none of it, which is why it lives behind its own subpath — autocomplete on @docx-editor.dev/core/collaboration should not offer putXmlPart and spliceChildren to somebody wiring up an avatar stack.

Reach for this when you are writing a provider. @docx-editor.dev/pro is one.

Functions (4)

createCollaborationDocumentPortfunctionSource ↗

Create the narrow collaboration view over one canonical package store.

declare function createCollaborationDocumentPort(store: TreePackageStore, options: CreateCollaborationDocumentPortOptions): CollaborationDocumentPort;

historyGroupOfJournalfunctionSource ↗

The history group the transaction behind journal named, if any.

declare function historyGroupOfJournal(journal: CanonicalPrimitiveJournal): HistoryGroup | undefined;

mapOffsetAcrossTextfunctionSource ↗

An offset carried across one change to a paragraph's text.

The local caret and the carets peers show both stay next to the same character this way, whatever a peer typed or deleted around it, even when one remote update changed text on both sides of the offset.

declare function mapOffsetAcrossText(offset: number, before: string, after: string): number;

reportHistoryGroupfunctionSource ↗

declare function reportHistoryGroup(group: HistoryGroup | undefined, kind: HistoryCaptureKind, reason?: HistoryCaptureReason): void;

Interfaces (11)

CanonicalAttributeNameinterfaceSource ↗

Attribute name as the journal addresses it. Prefix is authored fidelity, not identity.

interface CanonicalAttributeName
MemberTypeSummary
localNamestring
namespaceUristring
prefix?string

CanonicalBinaryDescriptorinterfaceSource ↗

Content-addressed binary part reference. Bytes stay out of the journal.

interface CanonicalBinaryDescriptor
MemberTypeSummary
digeststring
mediaTypestring
sizenumber
storageKeystring

CanonicalElementNodeDescriptorinterfaceSource ↗

OOXML element shell. Attributes, bindings, and children arrive as later effects.

interface CanonicalElementNodeDescriptor
MemberTypeSummary
kindOoxmlElement['kind']
logicalIdstring
qnameCanonicalAttributeName

CanonicalPrimitiveJournalinterfaceSource ↗

One immutable journal for one TreePackageStore transaction.

Empty only when a committed write used a path the journal does not yet intercept.

interface CanonicalPrimitiveJournal
MemberTypeSummary
effectsreadonly CanonicalPrimitiveEffect[]

CanonicalRelationshipRecordinterfaceSource ↗

One relationship as the journal records it.

interface CanonicalRelationshipRecord
MemberTypeSummary
idstring
ordernumber
ownerPartstring
rawTargetstring
targetMode'Internal' | 'External'
typestring

CanonicalTextNodeDescriptorinterfaceSource ↗

Text node shell. Value arrives later through spliceText.

interface CanonicalTextNodeDescriptor
MemberTypeSummary
kind'textValue'
logicalIdstring

CollaborationDocumentPortinterfaceSource ↗

Narrow canonical document capability handed to a collaboration implementation.

It deliberately exposes no mutable package or tree store. Every write returns through the same validated transaction path as browser and automation edits.

interface CollaborationDocumentPort
MemberTypeSummary
applyParagraphText
applyParagraphTexts
applyRemotePackagePublish one remotely materialized canonical package as one revision.
binaryPartBytes of one binary package part, or null when the part is absent.
documentIdstring
flushPendingJournalsFreeze and deliver queued journals in production order.
hasPendingJournalsTrue when a committed journal has not yet been frozen or delivered to observers.
observePrimitiveJournalObserve one settled primitive journal per committed canonical transaction.
paragraphByNodeId
paragraphByStableIdResolve a stable `w14:paraId` in any story this replica holds.
paragraphs
paragraphTextOfThe model text of the paragraph with this node id in any story, or null when the editor shows none. A lookup by node id, whatever the paragraph's `w14:paraId`. Optional.
revision
save
subscribe

CollaborationMutationinterfaceSource ↗

Attribution for one collaboration-derived canonical publication.

interface CollaborationMutation
MemberTypeSummary
actorIdstring
operationIdstring
originstring

CollaborationParagraphinterfaceSource ↗

One existing body paragraph exposed to the replication adapter.

interface CollaborationParagraph
MemberTypeSummary
nodeIdstringReplica-local canonical node identity. Never sent as wire identity.
paragraphIdstringUppercase `w14:paraId`, stable across save and reopen.
textstringCurrent canonical UTF-16 text.

CollaborationParagraphTextUpdateinterfaceSource ↗

One paragraph text value in an atomic collaboration publication.

interface CollaborationParagraphTextUpdate
MemberTypeSummary
paragraphIdstring
textstring

CreateCollaborationDocumentPortOptionsinterfaceSource ↗

Options for a canonical collaboration document port.

interface CreateCollaborationDocumentPortOptions
MemberTypeSummary
documentIdstring

Type aliases (4)

CanonicalNodeDescriptortypeSource ↗

Immutable node record required to create a registry entry.

type CanonicalNodeDescriptor = CanonicalTextNodeDescriptor | CanonicalElementNodeDescriptor;

CanonicalPrimitiveEffecttypeSource ↗

One compositional tree or package effect captured from a canonical write.

type CanonicalPrimitiveEffect = {
    readonly kind: 'putNode';
    readonly descriptor: CanonicalNodeDescriptor;
} | {
    readonly kind: 'spliceText';
    readonly logicalId: string;
    readonly utf16Start: number;
    readonly deleteCount: number;
    readonly insert: string;
} | {
    readonly kind: 'setAttribute';
    readonly logicalId: string;
    readonly qname: CanonicalAttributeName;
    readonly value: string | null;
} | {
    readonly kind: 'setNamespaceBinding';
    readonly logicalId: string;
    readonly prefix: string;
    readonly uri: string | null;
} | {
    readonly kind: 'spliceChildren';
    readonly parentLogicalId: string;
    readonly start: number;
    readonly deleteCount: number;
    readonly childLogicalIds: readonly string[];
} | {
    readonly kind: 'moveNode';
    readonly logicalId: string;
    readonly destinationParentLogicalId: string;
    readonly destinationIndex: number;
} | {
    readonly kind: 'putXmlPart';
    readonly name: string;
    readonly rootLogicalId: string;
} | {
    readonly kind: 'deleteXmlPart';
    readonly name: string;
} | {
    readonly kind: 'putRelationship';
    readonly owner: string;
    readonly record: CanonicalRelationshipRecord;
} | {
    readonly kind: 'deleteRelationship';
    readonly owner: string;
    readonly relationshipId: string;
} | {
    readonly kind: 'putContentTypeOverride';
    readonly partName: string;
    readonly mediaType: string;
} | {
    readonly kind: 'deleteContentTypeOverride';
    readonly partName: string;
} | {
    readonly kind: 'putBinary';
    readonly descriptor: CanonicalBinaryDescriptor;
} | {
    readonly kind: 'deleteBinary';
    readonly storageKey: string;
};

CollaborationApplyResulttypeSource ↗

Result of replacing one supported paragraph's canonical text.

type CollaborationApplyResult = {
    readonly ok: true;
    readonly changed: boolean;
} | {
    readonly ok: false;
    readonly reason: string;
};

HistoryGrouptypeSource ↗

The identity of one continuous user gesture, for history grouping.

A live color picker, a font-size stepper or a spacing slider applies every intermediate value so the document updates under the pointer, and each of those writes is a transaction in its own right — it must render, and a collaborator must receive it. What they are NOT is separate undo steps. The caller mints one token when the gesture starts (Symbol('color-drag')) and passes it with every write until the gesture ends.

A symbol rather than a string, so two unrelated callers cannot collide by naming their gesture the same way, and so a token cannot outlive its gesture by accident through serialization.

type HistoryGroup = symbol;