R
T

Step

tested

The atomic, invertible, serializable unit of change. Steps are the contract shared by the undo history (each carries its exact inverse) and the CRDT adapter (each maps to a CRDT operation). Keeping the set small (~12) means a new block type never needs a new step.

Signature

ts
export type Step
  = | { readonly type: 'insertInline'; readonly blockId: string; readonly offset: number; readonly content: Inline }
    | { readonly type: 'deleteText'; readonly blockId: string; readonly from: number; readonly to: number }
    | { readonly type: 'replaceInline'; readonly blockId: string; readonly from: number; readonly to: number; readonly content: Inline }
    | { readonly type: 'addMark'; readonly blockId: string; readonly from: number; readonly to: number; readonly mark: Mark }
    | { readonly type: 'removeMark'; readonly blockId: string; readonly from: number; readonly to: number; readonly mark: Mark }
    | { readonly type: 'setAttrs'; readonly blockId: string; readonly attrs: Attrs }
    | { readonly type: 'setType'; readonly blockId: string; readonly blockType: string; readonly attrs: Attrs }
    | { readonly type: 'splitBlock'; readonly blockId: string; readonly offset: number; readonly newId: string; readonly newType?: string; readonly newAttrs?: Attrs }
    | { readonly type: 'mergeBlock'; readonly blockId: string; readonly intoId: string }
    | { readonly type: 'insertBlock'; readonly node: Node; readonly index: number }
    | { readonly type: 'removeBlock'; readonly blockId: string }
    | { readonly type: 'moveBlock'; readonly blockId: string; readonly toIndex: number }
    | { readonly type: 'setDoc'; readonly doc: EditorDocument };