Skip to main content
Reference status

This page predates the current package split. Use the current package guides for checked installation, public imports, and onboarding examples. The detailed examples below have not all been revalidated.

DataStore Operations API

DataStore operations are low-level operations that directly manipulate the DataStore with overlay and lock support. They are organized into logical classes.

Overview​

DataStore operations are grouped into the following classes:

  • CoreOperations: Basic CRUD operations (setNode, getNode, deleteNode, etc.)
  • ContentOperations: Parent-child relationship management (addChild, removeChild, moveNode, etc.)
  • RangeOperations: Text range operations (insertText, deleteText, replaceText, etc.)
  • MarkOperations: Mark management (normalizeMarks, addMark, removeMark, etc.)
  • QueryOperations: Node querying and searching
  • SplitMergeOperations: Node splitting and merging
  • DecoratorOperations: Decorator management
  • UtilityOperations: Utility functions (editable node detection, traversal, etc.)
  • SerializationOperations: Serialization and deserialization

Usage Pattern​

All DataStore operations are accessed through the DataStore instance:

import { DataStore } from '@barocss/datastore';

const dataStore = new DataStore();

// Operations are accessed via dataStore properties
dataStore.core.setNode(node);
dataStore.content.addChild(parentId, child);
dataStore.range.insertText(range, 'Hello');
dataStore.mark.normalizeMarks(nodeId);
dataStore.query.findNodesByType('paragraph');
dataStore.splitMerge.splitTextNode('text-1', 5);
dataStore.utility.getPreviousEditableNode('text-1');

Note: DataStore operations automatically use overlay when a transaction is active (via dataStore.begin()).

Operation Categories​

When to Use Each Class​

TaskUse This ClassExample
Create/Read/Update/Delete nodesCoreOperationsdataStore.core.setNode(), dataStore.core.getNode()
Manage parent-child relationshipsContentOperationsdataStore.content.addChild(), dataStore.content.moveNode()
Manipulate text rangesRangeOperationsdataStore.range.insertText(), dataStore.range.deleteText()
Manage marksMarkOperationsdataStore.mark.normalizeMarks(), dataStore.mark.toggleMark()
Query/search nodesQueryOperationsdataStore.query.findNodesByType(), dataStore.query.searchText()
Split/merge nodesSplitMergeOperationsdataStore.splitMerge.splitTextNode(), dataStore.splitMerge.mergeTextNodes()
Utility functionsUtilityOperationsdataStore.utility.getParent(), dataStore.utility.isLeafNode()
Decorator managementDecoratorOperationsSee Decorators Guide
SerializationSerializationOperationsSee DataStore README

CoreOperations​

Basic CRUD operations for nodes.

setNode(node: INode, validate?: boolean): void​

Creates or updates a node in DataStore.

Parameters:

  • node: Node to set (assigns sid if missing)
  • validate: Whether to validate against schema (default: true)

Behavior:

  • Assigns sid if missing using DataStore.generateId()
  • Validates against schema if validate=true and schema exists
  • Converts object children in content to IDs recursively
  • Overlay-aware: writes go to overlay if transaction active
  • Emits 'create' or 'update' operation event

Example:

dataStore.core.setNode({
sid: 'p1',
stype: 'paragraph',
text: 'Hello',
content: []
});

getNode(nodeId: string): INode | undefined​

Retrieves a node by ID.

Parameters:

  • nodeId: Node ID (SID)

Returns:

  • INode | undefined: Node if found, undefined otherwise

Read Path:

  1. Check deletedNodeIds → return undefined if deleted
  2. Check overlayNodes → return overlay version if exists
  3. Fallback to baseNodes → return base version

Example:

const node = dataStore.core.getNode('text-1');

deleteNode(nodeId: string): boolean​

Deletes a node from DataStore.

Parameters:

  • nodeId: Node ID to delete

Returns:

  • boolean: true if deleted, false if node not found

Behavior:

  • Cannot delete root node (throws error)
  • Removes node from parent's content array
  • Emits 'delete' operation event
  • Overlay-aware

Example:

const deleted = dataStore.core.deleteNode('node-1');

updateNode(nodeId: string, updates: Partial<INode>, validate?: boolean): { valid: boolean; errors: string[] } | null​

Updates a node with partial changes.

Parameters:

  • nodeId: Node ID to update
  • updates: Partial node data to apply
  • validate: Whether to validate (default: true)

Returns:

  • Validation result: { valid: boolean; errors: string[] } or null

Behavior:

  • Merges fields (attributes shallow-merge)
  • Validates against schema if validate=true
  • Overlay-aware: writes go to overlay if transaction active
  • Emits 'update' operation event

Example:

const result = dataStore.core.updateNode('text-1', { 
text: 'Updated text'
});

createNodeWithChildren(node: INode, schema?: Schema): INode​

Creates a node with all its children recursively.

Parameters:

  • node: Node with nested children (objects)
  • schema: Optional schema for validation

Returns:

  • INode: Created node with assigned IDs

Behavior:

  • Recursively creates all child nodes
  • Assigns IDs to all nodes
  • Converts object children to ID arrays
  • Overlay-aware

Example:

const root = dataStore.core.createNodeWithChildren({
stype: 'document',
content: [
{
stype: 'paragraph',
content: [
{ stype: 'inline-text', text: 'Hello' }
]
}
]
});

transformNode(nodeId: string, newType: string, newAttrs?: Record<string, any>): { valid: boolean; errors: string[]; newNodeId?: string }​

Transforms a node to a different type.

Parameters:

  • nodeId: Node ID to transform
  • newType: New schema type (stype)
  • newAttrs: Optional new attributes

Returns:

  • Validation result with optional newNodeId

Example:

const result = dataStore.core.transformNode('p1', 'heading', { level: 1 });

ContentOperations​

Manages parent-child relationships and content ordering.

addChild(parentId: string, child: INode | string, position?: number): string​

Adds a child node to a parent's content array.

Parameters:

  • parentId: Parent node ID
  • child: Child node (object) or child ID (string)
  • position: Insert position (default: end)

Returns:

  • string: Child node ID

Behavior:

  • Creates child if object provided (assigns ID if missing)
  • Inserts child ID at position in parent's content array
  • Updates child's parentId
  • Emits 'update' for parent
  • Overlay-aware

Example:

// Add existing node
const childId = dataStore.content.addChild('parent-1', 'child-1', 0);

// Create and add new node
const newChildId = dataStore.content.addChild('parent-1', {
stype: 'paragraph',
text: 'New paragraph'
}, 0);

removeChild(parentId: string, childId: string): boolean​

Removes a child from parent's content array.

Parameters:

  • parentId: Parent node ID
  • childId: Child node ID to remove

Returns:

  • boolean: true if removed, false if not found

Behavior:

  • Removes child ID from parent's content array
  • Clears child's parentId
  • Emits 'update' for parent
  • Overlay-aware

Example:

const removed = dataStore.content.removeChild('parent-1', 'child-1');

moveNode(nodeId: string, newParentId: string, position?: number): boolean​

Moves a node to a new parent.

Parameters:

  • nodeId: Node ID to move
  • newParentId: New parent node ID
  • position: Position in new parent (default: end)

Returns:

  • boolean: true if moved, false if failed

Behavior:

  • Removes from old parent's content array
  • Adds to new parent's content array at position
  • Updates node's parentId
  • Emits 'move' operation event
  • Overlay-aware

Example:

const moved = dataStore.content.moveNode('node-1', 'new-parent-1', 0);

reorderChildren(parentId: string, childIds: string[]): void​

Reorders children in a parent's content array.

Parameters:

  • parentId: Parent node ID
  • childIds: New order of child IDs

Behavior:

  • Updates parent's content array with new order
  • Validates all child IDs exist
  • Emits 'update' for parent
  • Overlay-aware

Example:

dataStore.content.reorderChildren('parent-1', ['child-3', 'child-1', 'child-2']);

RangeOperations​

Text range operations for manipulating text content within ranges.

insertText(contentRange: ModelSelection, text: string): string​

Inserts text at the specified range position.

Parameters:

  • contentRange: Range where to insert (start=end for insertion point)
  • text: Text to insert

Returns:

  • string: Inserted text

Behavior:

  • Inserts text at range position
  • Updates marks to reflect insertion
  • Uses updateNode() (overlay-aware)
  • Handles single-node and multi-node ranges

Example:

const inserted = dataStore.range.insertText({
startNodeId: 'text-1',
startOffset: 5,
endNodeId: 'text-1',
endOffset: 5
}, 'Hello');

deleteText(contentRange: ModelSelection): string​

Deletes text in the specified range.

Parameters:

  • contentRange: Range to delete

Returns:

  • string: Deleted text

Behavior:

  • Fast-path for same-node deletion
  • Multi-node: trims start node, clears middle nodes, trims end node
  • Updates marks to reflect deletion (split/trim/shift)
  • Uses updateNode() (overlay-aware)

Example:

const deleted = dataStore.range.deleteText({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-1',
endOffset: 5
});

replaceText(contentRange: ModelSelection, newText: string): string​

Replaces text in the specified range.

Parameters:

  • contentRange: Range to replace
  • newText: New text

Returns:

  • string: Replaced text (old text)

Behavior:

  • Deletes old text and inserts new text
  • Updates marks appropriately
  • Uses updateNode() (overlay-aware)

Example:

const replaced = dataStore.range.replaceText({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-1',
endOffset: 5
}, 'New text');

extractText(contentRange: ModelSelection): string​

Extracts text from range without modifying nodes.

Parameters:

  • contentRange: Range to extract

Returns:

  • string: Extracted text

Behavior:

  • Read-only operation (does not modify nodes)
  • Uses DocumentIterator to traverse range
  • Concatenates text from all nodes

Example:

const extracted = dataStore.range.extractText({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-3',
endOffset: 10
});

applyMark(contentRange: ModelSelection, mark: IMark): IMark​

Applies a mark to the specified range.

Parameters:

  • contentRange: Range to apply mark
  • mark: Mark to apply

Returns:

  • IMark: Applied mark

Behavior:

  • Adds mark to nodes in range
  • Merges with existing marks
  • Updates marks via updateNode() (overlay-aware)

Example:

const mark = dataStore.range.applyMark({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-1',
endOffset: 5
}, {
type: 'bold',
range: [0, 5]
});

removeMark(contentRange: ModelSelection, markType: string): number​

Removes a mark type from the specified range.

Parameters:

  • contentRange: Range to remove mark
  • markType: Mark type to remove

Returns:

  • number: Number of marks removed

Example:

const removed = dataStore.range.removeMark({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-1',
endOffset: 5
}, 'bold');

toggleMark(contentRange: ModelSelection, markType: string, attrs?: Record<string, any>): void​

Toggles a mark on/off in the specified range.

Parameters:

  • contentRange: Range to toggle mark
  • markType: Mark type to toggle
  • attrs: Optional mark attributes

Behavior:

  • Adds mark if not present
  • Removes mark if present
  • Uses updateNode() (overlay-aware)

Example:

dataStore.range.toggleMark({
startNodeId: 'text-1',
startOffset: 0,
endNodeId: 'text-1',
endOffset: 5
}, 'bold');

MarkOperations​

Mark management and normalization.

normalizeMarks(nodeId: string): void​

Normalizes marks for a node.

Behavior:

  • Assigns full-range to marks missing range
  • Clamps ranges to [0, textLength]
  • Drops empty/invalid ranges
  • Removes duplicates by (type, attrs, range)
  • Merges overlapping marks with identical (type, attrs)
  • Sorts by start position
  • Persists via updateNode() (overlay-aware)

Example:

dataStore.mark.normalizeMarks('text-1');

normalizeAllMarks(): number​

Normalizes marks for all nodes in DataStore.

Returns:

  • number: Number of nodes normalized

Example:

const count = dataStore.mark.normalizeAllMarks();

setMarks(nodeId: string, marks: IMark[], replace?: boolean): void​

Sets marks for a node.

Parameters:

  • nodeId: Node ID
  • marks: Array of marks to set
  • replace: Whether to replace existing marks (default: true)

Behavior:

  • Replaces or merges marks based on replace flag
  • Uses updateNode() (overlay-aware)

Example:

dataStore.mark.setMarks('text-1', [
{ type: 'bold', range: [0, 5] },
{ type: 'italic', range: [2, 7] }
]);

removeMark(nodeId: string, markType: string, range?: [number, number]): number​

Removes a mark type from a node.

Parameters:

  • nodeId: Node ID
  • markType: Mark type to remove
  • range: Optional range to remove from

Returns:

  • number: Number of marks removed

Example:

const removed = dataStore.mark.removeMark('text-1', 'bold', [0, 5]);

updateMark(nodeId: string, markType: string, attrs: Record<string, any>, range?: [number, number]): number​

Updates attributes of a mark type.

Parameters:

  • nodeId: Node ID
  • markType: Mark type to update
  • attrs: New attributes
  • range: Optional range to update

Returns:

  • number: Number of marks updated

Example:

const updated = dataStore.mark.updateMark('text-1', 'link', { href: 'https://example.com' });

toggleMark(nodeId: string, markType: string, attrs?: Record<string, any>, range?: [number, number]): void​

Toggles a mark on/off for a node.

Parameters:

  • nodeId: Node ID
  • markType: Mark type to toggle
  • attrs: Optional mark attributes
  • range: Optional range to toggle

Example:

dataStore.mark.toggleMark('text-1', 'bold', undefined, [0, 5]);

QueryOperations​

Node querying and searching.

findNodes(predicate: (node: INode) => boolean): INode[]​

Finds nodes matching a predicate.

Parameters:

  • predicate: Function that returns true for matching nodes

Returns:

  • INode[]: Array of matching nodes

Example:

const nodes = dataStore.query.findNodes(node => node.stype === 'paragraph');

findNodesByType(stype: string): INode[]​

Finds nodes by schema type.

Parameters:

  • stype: Schema type to find

Returns:

  • INode[]: Array of matching nodes

Example:

const paragraphs = dataStore.query.findNodesByType('paragraph');

findNodesByAttribute(key: string, value: any): INode[]​

Finds nodes by attribute value.

Parameters:

  • key: Attribute key
  • value: Attribute value

Returns:

  • INode[]: Array of matching nodes

Example:

const headings = dataStore.query.findNodesByAttribute('level', 1);

findNodesByText(text: string): INode[]​

Finds nodes containing text.

Parameters:

  • text: Text to search for

Returns:

  • INode[]: Array of matching nodes

Example:

const nodes = dataStore.query.findNodesByText('Hello');

getNodeChildren(nodeId: string): INode[]​

Gets direct children of a node.

Parameters:

  • nodeId: Parent node ID

Returns:

  • INode[]: Array of child nodes

Example:

const children = dataStore.query.getNodeChildren('parent-1');

getNodeChildrenDeep(nodeId: string): INode[]​

Gets all descendants of a node (recursive).

Parameters:

  • nodeId: Parent node ID

Returns:

  • INode[]: Array of all descendant nodes

Example:

const allDescendants = dataStore.query.getNodeChildrenDeep('parent-1');

SplitMergeOperations​

Node splitting and merging operations.

splitTextNode(nodeId: string, splitPosition: number): string​

Splits a text node at the specified position.

Parameters:

  • nodeId: Text node ID to split
  • splitPosition: Position to split at

Returns:

  • string: ID of the new right node

Behavior:

  • Creates new node with text after split position
  • Updates original node with text before split position
  • Preserves marks appropriately (splits mark ranges)
  • Updates parent's content array
  • Overlay-aware

Example:

const rightNodeId = dataStore.splitMerge.splitTextNode('text-1', 5);
// Original: 'Hello World' → Left: 'Hello', Right: ' World'

mergeTextNodes(leftNodeId: string, rightNodeId: string): string​

Merges two adjacent text nodes.

Parameters:

  • leftNodeId: Left node ID
  • rightNodeId: Right node ID

Returns:

  • string: ID of merged node (left node ID)

Behavior:

  • Concatenates text from both nodes
  • Merges marks (adjusts ranges)
  • Removes right node
  • Updates parent's content array
  • Overlay-aware

Example:

const mergedId = dataStore.splitMerge.mergeTextNodes('text-1', 'text-2');
// Left: 'Hello', Right: ' World' → Merged: 'Hello World'

splitBlockNode(nodeId: string, splitPosition: number): string​

Splits a block node at the specified position.

Parameters:

  • nodeId: Block node ID to split
  • splitPosition: Position in content array to split at

Returns:

  • string: ID of the new right node

Behavior:

  • Creates new block with children after split position
  • Updates original block with children before split position
  • Updates parent's content array
  • Overlay-aware

Example:

const rightNodeId = dataStore.splitMerge.splitBlockNode('block-1', 2);
// Original: [child-1, child-2, child-3, child-4]
// Left: [child-1, child-2], Right: [child-3, child-4]

mergeBlockNodes(leftNodeId: string, rightNodeId: string): string​

Merges two adjacent block nodes.

Parameters:

  • leftNodeId: Left block node ID
  • rightNodeId: Right block node ID

Returns:

  • string: ID of merged node (left node ID)

Behavior:

  • Merges children from both blocks
  • Removes right node
  • Updates parent's content array
  • Overlay-aware

Example:

const mergedId = dataStore.splitMerge.mergeBlockNodes('block-1', 'block-2');
// Left: [child-1, child-2], Right: [child-3, child-4]
// Merged: [child-1, child-2, child-3, child-4]

autoMergeTextNodes(nodeId: string): string​

Automatically merges adjacent text nodes if they can be merged.

Parameters:

  • nodeId: Node ID to check

Returns:

  • string: ID of merged node or original node ID

Behavior:

  • Checks if node can be merged with next sibling
  • Merges if same type and no marks
  • Overlay-aware

Example:

const mergedId = dataStore.splitMerge.autoMergeTextNodes('text-1');

insertText(nodeId: string, position: number, text: string): string​

Inserts text at a position in a text node (single-node operation).

Parameters:

  • nodeId: Text node ID
  • position: Position to insert at
  • text: Text to insert

Returns:

  • string: Inserted text

Behavior:

  • Single-node text insertion
  • Updates marks appropriately
  • Overlay-aware

Example:

const inserted = dataStore.splitMerge.insertText('text-1', 5, 'Hello');

deleteTextRange(nodeId: string, startPosition: number, endPosition: number): string​

Deletes text in a range within a single node.

Parameters:

  • nodeId: Text node ID
  • startPosition: Start position
  • endPosition: End position

Returns:

  • string: Deleted text

Behavior:

  • Single-node text deletion
  • Updates marks appropriately
  • Overlay-aware

Example:

const deleted = dataStore.splitMerge.deleteTextRange('text-1', 0, 5);

replaceTextRange(nodeId: string, startPosition: number, endPosition: number, newText: string): string​

Replaces text in a range within a single node.

Parameters:

  • nodeId: Text node ID
  • startPosition: Start position
  • endPosition: End position
  • newText: New text

Returns:

  • string: Replaced text (old text)

Behavior:

  • Single-node text replacement
  • Updates marks appropriately
  • Overlay-aware

Example:

const replaced = dataStore.splitMerge.replaceTextRange('text-1', 0, 5, 'New');

QueryOperations​

Node querying and searching operations.

findNodes(predicate: (node: INode) => boolean): INode[]​

Finds nodes matching a predicate (includes orphaned nodes).

Parameters:

  • predicate: Function that returns true for matching nodes

Returns:

  • INode[]: Array of matching nodes

Behavior:

  • Iterates through ALL nodes (including orphaned)
  • Overlay-aware
  • Order not guaranteed

Example:

const nodes = dataStore.query.findNodes(node => node.stype === 'paragraph');

findNodesByType(stype: string): INode[]​

Finds nodes by schema type (uses DocumentIterator for performance).

Parameters:

  • stype: Schema type to find

Returns:

  • INode[]: Array of matching nodes

Behavior:

  • Uses DocumentIterator with type filter
  • Order follows document traversal
  • More efficient than findNodes()

Example:

const paragraphs = dataStore.query.findNodesByType('paragraph');

findNodesByAttribute(key: string, value: any): INode[]​

Finds nodes by attribute value.

Parameters:

  • key: Attribute key
  • value: Attribute value

Returns:

  • INode[]: Array of matching nodes

Example:

const headings = dataStore.query.findNodesByAttribute('level', 1);

findNodesByText(text: string): INode[]​

Finds nodes containing text.

Parameters:

  • text: Text to search for

Returns:

  • INode[]: Array of matching nodes

Example:

const nodes = dataStore.query.findNodesByText('Hello');

findChildrenByParentId(parentId: string): INode[]​

Gets direct children of a node.

Parameters:

  • parentId: Parent node ID

Returns:

  • INode[]: Array of direct child nodes

Example:

const children = dataStore.query.findChildrenByParentId('parent-1');

getNodeChildren(nodeId: string): INode[]​

Gets direct children (alias for findChildrenByParentId).

Example:

const children = dataStore.query.getNodeChildren('parent-1');

getNodeChildrenDeep(nodeId: string): INode[]​

Gets all descendants recursively.

Parameters:

  • nodeId: Parent node ID

Returns:

  • INode[]: Array of all descendant nodes

Example:

const allDescendants = dataStore.query.getNodeChildrenDeep('parent-1');

findRootNodes(): INode[]​

Finds all root nodes (nodes without parent).

Returns:

  • INode[]: Array of root nodes

Example:

const roots = dataStore.query.findRootNodes();

searchText(query: string): INode[]​

Searches for nodes containing text (full-text search).

Parameters:

  • query: Search query

Returns:

  • INode[]: Array of matching nodes

Example:

const results = dataStore.query.searchText('Hello World');

UtilityOperations​

Utility functions for node operations and traversal.

hasNode(nodeId: string): boolean​

Checks if a node exists.

Parameters:

  • nodeId: Node ID to check

Returns:

  • boolean: true if node exists

Example:

const exists = dataStore.utility.hasNode('node-1');

getChildCount(nodeId: string): number​

Gets the number of direct children.

Parameters:

  • nodeId: Parent node ID

Returns:

  • number: Number of direct children

Example:

const count = dataStore.utility.getChildCount('parent-1');

isLeafNode(nodeId: string): boolean​

Checks if a node is a leaf (no children).

Parameters:

  • nodeId: Node ID to check

Returns:

  • boolean: true if leaf node

Example:

const isLeaf = dataStore.utility.isLeafNode('text-1');

isRootNode(nodeId: string): boolean​

Checks if a node is the root node.

Parameters:

  • nodeId: Node ID to check

Returns:

  • boolean: true if root node

Example:

const isRoot = dataStore.utility.isRootNode('document-1');

getChildren(nodeId: string): INode[]​

Gets direct children nodes.

Parameters:

  • nodeId: Parent node ID

Returns:

  • INode[]: Array of child nodes

Example:

const children = dataStore.utility.getChildren('parent-1');

getParent(nodeId: string): INode | undefined​

Gets the parent node.

Parameters:

  • nodeId: Child node ID

Returns:

  • INode | undefined: Parent node or undefined

Example:

const parent = dataStore.utility.getParent('child-1');

getSiblings(nodeId: string): INode[]​

Gets sibling nodes (same parent).

Parameters:

  • nodeId: Node ID

Returns:

  • INode[]: Array of sibling nodes

Example:

const siblings = dataStore.utility.getSiblings('node-1');

getPreviousSibling(nodeId: string): string | null​

Gets the previous sibling node ID.

Parameters:

  • nodeId: Node ID

Returns:

  • string | null: Previous sibling ID or null

Example:

const prevSibling = dataStore.utility.getPreviousSibling('node-2');

getNextSibling(nodeId: string): string | null​

Gets the next sibling node ID.

Parameters:

  • nodeId: Node ID

Returns:

  • string | null: Next sibling ID or null

Example:

const nextSibling = dataStore.utility.getNextSibling('node-1');

getPreviousEditableNode(nodeId: string): string | null​

Gets the previous editable node in document order.

Parameters:

  • nodeId: Current node ID

Returns:

  • string | null: Previous editable node ID or null

Behavior:

  • Skips non-editable nodes (blocks, documents)
  • Returns only editable nodes (text, inline)

Example:

const prevNode = dataStore.utility.getPreviousEditableNode('text-3');

getNextEditableNode(nodeId: string): string | null​

Gets the next editable node in document order.

Parameters:

  • nodeId: Current node ID

Returns:

  • string | null: Next editable node ID or null

Example:

const nextNode = dataStore.utility.getNextEditableNode('text-1');

DecoratorOperations​

Decorator management operations.

adjustRanges(...)​

Adjusts decorator ranges after text changes.

Note: See Decorators Guide for detailed documentation.


SerializationOperations​

Serialization and deserialization operations.

Note: See DataStore README for detailed documentation.


Overlay and Lock Behavior​

All DataStore operations automatically respect:

  1. Overlay: When dataStore.begin() is called, all writes go to overlay
  2. Lock: Operations should be executed within a lock (acquired via acquireLock())

Example with Transaction:

// Lock and overlay are managed by TransactionManager
const result = await transaction(editor, [
...control('text-1', [
insertText(5, 'Hello')
])
]).commit();

// Internally:
// 1. acquireLock()
// 2. begin() (overlay)
// 3. RangeOperations.insertText() → updateNode() → overlay
// 4. end() (get operations)
// 5. commit() (apply to base)
// 6. releaseLock()