/** * Relative span model for incremental edits. * * Absolute source offsets are simple but fragile: an insertion at offset `at` * shifts EVERY downstream offset, so a whole-tree renumber is O(nodes-after-edit). * Storing each node's span RELATIVE to its parent's start makes edits local: an * insertion inside child k of a node only changes * (a) child k's relative end, * (b) the relative start of siblings after k, * and leaves the *children* of those shifted siblings untouched — they move with * their parent for free. So the mutation count is O(depth + trailing siblings), * not O(all following nodes), and every unaffected subtree is shared by identity. * * An absolute view is recovered on query by accumulating the parent base as you * descend (the `absolutize` / `absoluteSpanAt` cursor) — one source of truth, * two manifestations. */ /** A node with an ABSOLUTE source span and ordered children. */ export type AbsNode = { readonly start: number; readonly end: number; readonly children: readonly AbsNode[]; }; /** A node whose `start`/`end` are RELATIVE to its parent's start (root base = 0). */ export type RelNode = { readonly start: number; readonly end: number; readonly children: readonly RelNode[]; }; /** Convert an absolute tree to parent-relative spans. */ export declare function relativize(node: AbsNode, parentBase?: number): RelNode; /** Reconstruct absolute spans from a relative tree. Inverse of `relativize`. */ export declare function absolutize(node: RelNode, parentBase?: number): AbsNode; /** * Absolute span of the node at `path` (child indices from the root), accumulating * the base as it descends — O(path length), no full absolutize. The relative-form * cursor: query any node's absolute position without materializing the whole tree. */ export declare function absoluteSpanAt(root: RelNode, path: readonly number[]): { start: number; end: number; }; /** * A CST child as far as span projection cares: a nested span + optional children. * `children` is typed loosely (`unknown[]`) so the real heterogeneous CST unions * (nodes, leaves, error nodes — a leaf has no `children`) satisfy it directly. */ type Spanned = { readonly span: { readonly start: number; readonly end: number; }; readonly children?: readonly unknown[]; }; /** * Rewrite a CST subtree's spans to be RELATIVE to `parentBase` (the absolute * start of the node's parent; root base = 0). Each child's own children are * relativized against *this* node's absolute start. Preserves every other field * (`_tag`, `type`, `state`, leaf `value`, …) by shallow spread. */ export declare function relativizeCST(node: T, parentBase?: number): T; /** Reconstruct absolute CST spans from a relative subtree. Inverse of `relativizeCST`. */ export declare function absolutizeCST(node: T, parentBase?: number): T; /** * Absolute span of the CST node at `path` (child indices from the root), * accumulating the base as it descends — O(path length), no full absolutize. * The relative-form cursor for a positioned CST: query one node's absolute * position without materializing the whole tree. */ export declare function absoluteSpanCST(root: Spanned, path: readonly number[]): { start: number; end: number; }; /** Naive absolute reshift (baseline): shift every offset >= `at` by `delta`. */ export declare function shiftAbsolute(node: AbsNode, at: number, delta: number): AbsNode; /** * Apply an edit of `delta` characters at absolute offset `at` to a RELATIVE tree. * Returns a new relative tree; every subtree that ends at/before `at` (in absolute * terms) is returned by IDENTITY (unchanged), so the result structurally shares * all unaffected subtrees with the input. * * `stats.allocated` counts nodes that had to be re-created — the incremental cost. */ export declare function applyEdit(root: RelNode, at: number, delta: number, stats?: { allocated: number; }): RelNode; export {}; //# sourceMappingURL=relative-spans.d.ts.map