Operation Types

PreviousNext

Serializable operation shapes used for document changes, replay, history, and collaboration.

Operation objects define the low-level instructions that Slate editors use to apply changes to their internal state. Representing all changes as operations is what allows Slate editors to easily implement history, collaboration, and other features.

Operation Object

Read Operation for the helper API. The sections below list the serializable operation shapes.

Node Operations

Node operations operate on Node objects.

// insert a new `Node`
type InsertNodeOperation = {
  type: "insert_node";
  path: Path;
  node: Node;
};
 
// merge two `Node` objects
type MergeNodeOperation = {
  type: "merge_node";
  path: Path;
  position: number;
  properties: Partial<Node>;
};
 
// move `Node` from one path to another
type MoveNodeOperation = {
  type: "move_node";
  path: Path;
  newPath: Path;
};
 
// Remove a `Node`
type RemoveNodeOperation = {
  type: "remove_node";
  path: Path;
  node: Node;
};
 
// Set properties of a `Node`
type SetNodeOperation = {
  type: "set_node";
  path: Path;
  properties: Partial<Node>;
  newProperties: Partial<Node>;
};
 
// Split a node into two separate `Node` objects
type SplitNodeOperation = {
  type: "split_node";
  path: Path;
  position: number;
  properties: Partial<Node>;
};
 
export type NodeOperation =
  | InsertNodeOperation
  | MergeNodeOperation
  | MoveNodeOperation
  | RemoveNodeOperation
  | SetNodeOperation
  | SplitNodeOperation;
// insert a new `Node`
type InsertNodeOperation = {
  type: "insert_node";
  path: Path;
  node: Node;
};
 
// merge two `Node` objects
type MergeNodeOperation = {
  type: "merge_node";
  path: Path;
  position: number;
  properties: Partial<Node>;
};
 
// move `Node` from one path to another
type MoveNodeOperation = {
  type: "move_node";
  path: Path;
  newPath: Path;
};
 
// Remove a `Node`
type RemoveNodeOperation = {
  type: "remove_node";
  path: Path;
  node: Node;
};
 
// Set properties of a `Node`
type SetNodeOperation = {
  type: "set_node";
  path: Path;
  properties: Partial<Node>;
  newProperties: Partial<Node>;
};
 
// Split a node into two separate `Node` objects
type SplitNodeOperation = {
  type: "split_node";
  path: Path;
  position: number;
  properties: Partial<Node>;
};
 
export type NodeOperation =
  | InsertNodeOperation
  | MergeNodeOperation
  | MoveNodeOperation
  | RemoveNodeOperation
  | SetNodeOperation
  | SplitNodeOperation;

Fragment Operations

Fragment operations replace a child slice under a path and carry the model selection before and after the replacement. Slate uses this shape for bulk edits such as paste, where one user action should stay one history and collaboration operation.

type ReplaceFragmentOperation = {
  type: "replace_fragment";
  path: Path;
  children: Node[];
  newChildren: Node[];
  selection: Range | null;
  newSelection: Range | null;
};
type ReplaceFragmentOperation = {
  type: "replace_fragment";
  path: Path;
  children: Node[];
  newChildren: Node[];
  selection: Range | null;
  newSelection: Range | null;
};

Collaboration adapters can replay this operation directly through tx.operations.replay(...). CRDT adapters that cannot represent subtree replacement atomically should lower it to their own CRDT edits at the adapter boundary.

Replace Children Operations

Replace-children operations replace a child slice at one index under a path. Slate uses this shape for root lifecycle updates and other edits where the operation must carry both the previous and next child slice.

type ReplaceChildrenOperation = {
  type: "replace_children";
  path: Path;
  index: number;
  children: Node[];
  newChildren: Node[];
  selection: Range | null;
  newSelection: Range | null;
  rootWasPresent?: boolean;
  rootIsPresent?: boolean;
};
type ReplaceChildrenOperation = {
  type: "replace_children";
  path: Path;
  index: number;
  children: Node[];
  newChildren: Node[];
  selection: Range | null;
  newSelection: Range | null;
  rootWasPresent?: boolean;
  rootIsPresent?: boolean;
};

Text Operations

Text operations operate on Text objects only.

Note: Text objects are Node objects so you can use Node operations on Text objects.

// insert text into an existing `Text` node
type InsertTextOperation = {
  type: "insert_text";
  path: Path;
  offset: number;
  text: string;
};
 
// remove text from an existing `Text` node
type RemoveTextOperation = {
  type: "remove_text";
  path: Path;
  offset: number;
  text: string;
};
 
export type TextOperation = InsertTextOperation | RemoveTextOperation;
// insert text into an existing `Text` node
type InsertTextOperation = {
  type: "insert_text";
  path: Path;
  offset: number;
  text: string;
};
 
// remove text from an existing `Text` node
type RemoveTextOperation = {
  type: "remove_text";
  path: Path;
  offset: number;
  text: string;
};
 
export type TextOperation = InsertTextOperation | RemoveTextOperation;

Selection Operation

Operation to set or unset a selection Range.

type SetSelectionOperation =
  | {
      type: "set_selection";
      properties: null;
      newProperties: Range;
    }
  | {
      type: "set_selection";
      properties: Partial<Range>;
      newProperties: Partial<Range>;
    }
  | {
      type: "set_selection";
      properties: Range;
      newProperties: null;
    };
 
export type SelectionOperation = SetSelectionOperation;
type SetSelectionOperation =
  | {
      type: "set_selection";
      properties: null;
      newProperties: Range;
    }
  | {
      type: "set_selection";
      properties: Partial<Range>;
      newProperties: Partial<Range>;
    }
  | {
      type: "set_selection";
      properties: Range;
      newProperties: null;
    };
 
export type SelectionOperation = SetSelectionOperation;

Base Operation

The combination of all operation types.

export type BaseOperation =
  | NodeOperation
  | ReplaceChildrenOperation
  | ReplaceFragmentOperation
  | SelectionOperation
  | TextOperation;
export type BaseOperation =
  | NodeOperation
  | ReplaceChildrenOperation
  | ReplaceFragmentOperation
  | SelectionOperation
  | TextOperation;