import type { InsertionPoint } from '../../../types'; import type { NodeId, NodeIds } from '../itemIds'; /** * InsertionCursor tracks the point at which the next node will be inserted during * Change-style DOM serialization. * * When a new node is added to the document, we use an InsertionPoint to encode its * position. There are often multiple equally-valid ways to express the same insertion * point; we generally want to favor encodings that use as few characters as possible (to * reduce uncompressed size) and that are as repetitive as possible (to reduce compressed * size). InsertionCursor's purpose is to heuristically pick an efficient encoding based * on the nodes we've recently serialized, while doing as little work as possible. The * results are not optimal, but should be close to it in most situations. * * At the beginning of the serialization process, use a factory function like * createRootInsertionCursor() to create a new cursor with an appropriate initial * position. * * When visiting a node, the expected usage pattern is as follows: * 1. Call advance() to get a node id and insertion point for the node. * 2. Serialize the node. * 3. If the node has no children, we're done; continue to the node's next * sibling and apply this algorithm again. * 4. Otherwise, call descend() to move the cursor into the node's child list. * 5. Recursively apply this algorithm. * 6. Call ascend() to move the cursor out of the node's child list. We're done; * continue to the node's next sibling and apply this algorithm again. */ export interface InsertionCursor { /** * Given the node id for a new node, returns the InsertionPoint for that node. * Updates the cursor to point to the new node's next sibling. */ advance(node: Node): { nodeId: NodeId; insertionPoint: InsertionPoint; }; /** * Ascends out of the current child list and updates the cursor to point to the parent * node's next sibling. */ ascend(): void; /** * Descends into the child list of the last node we inserted and updates the cursor to * point to the node's first child. */ descend(): void; } /** Returns an InsertionCursor which starts positioned at the root of the document. */ export declare function createRootInsertionCursor(nodeIds: NodeIds): InsertionCursor; /** * Returns an InsertionCursor which starts positioned in the child list of the given * parent node. If a next sibling is provided, the cursor points to the position * immediately before the next sibling; otherwise, the cursor points to the end of the * child list. */ export declare function createChildInsertionCursor(parentId: NodeId, nextSiblingId: NodeId | undefined, nodeIds: NodeIds): InsertionCursor;