/** * Per-worksheet row/cell index — the O(1)-amortized fast path behind * `Worksheet.setCell` / `findCell` / `findRow` / `ensureRow` / `ensureCell`. * * WHY: the pre-index navigation re-scanned `sheetData` in document order * on every call (O(rows) per access → O(n²) for bulk writes; the Phase-3 * DX audit measured a 10k-row write at ~21 s). This cursor keeps Map * indexes (row number → row element, column → cell element) over the live * DOM so repeated access is O(1) amortized. * * LENS-OVER-DOM INVARIANT (CLAUDE.md rule 1): the DOM stays the single * source of truth. The index is a pure acceleration structure over the * live `sheetData` element — it never owns data, and every answer is * verified against the DOM before use: * * - sheet level: the index records the `sheetData` element identity and * its child count; any mismatch (raw-DOM row insertion/removal, a * different sheetData element) discards and rebuilds the whole index * from the live DOM. * - row level: an indexed row is used only while it is still a child of * `sheetData`, its `r` attribute still parses to the looked-up number, * and its child count matches the recorded one (this catches raw-DOM * cell insertion/removal inside the row). * - cell level: an indexed cell is used only while it is still a child * of its row and its `r` still parses to the looked-up column. * * Every verification failure is treated as a raw-DOM mutation: the * `onRawMutation` callback fires (the Workbook uses it to invalidate its * incrementally maintained shared-string reference total) and the index * is rebuilt from the live DOM before answering. Mutations performed * through this cursor update the recorded counts, so lens-only usage * never rebuilds. * * FALLBACK: a sheet whose rows (or a row whose cells) carry no explicit * `r`, duplicate indices, or out-of-document-order indices is NOT * indexable — implied-position semantics depend on document order, and * index-based insertion could diverge from the document-order scan. Such * sheets permanently use the legacy scans at the bottom of this file * (verbatim the pre-index algorithms), which are always correct against * the live DOM. Everything this library writes uses explicit ascending * references, so library-written and real-producer sheets index. * * RESIDUAL (documented limitation): a compensating raw-DOM edit that * changes no child count and touches no element the lens later verifies * (e.g. removing one row element and inserting a different one, or * renumbering an untouched row's `r`, between two lens calls) is not * detectable in O(1). The exposure is bounded: navigation may then see * the pre-edit shape until any count-changing access rebuilds, and the * shared-string `count` contract is independently enforced by the full * recount `Workbook.save()` performs (CONTRACTS.md §8.4 — counts correct * in saved bytes). */ import { XmlElement } from '../xml/index.js'; import { type CellAddress } from './internal.js'; /** * The navigation cursor one `Worksheet` owns. All row/cell navigation of * the lens goes through here (index.ts delegates `findRow` / `findCell` / * `ensureRow` / `ensureCell` / cell removal), so the index stays coherent * through every mutation path — setCell, setFormula, setCellStyle range * writes, addTable header writes. Streaming never mutates and does not * come through here. */ export declare class SheetDataCursor { #private; constructor(onRawMutation: () => void); /** The `row` element for 1-based `row`, or undefined. */ findRow(sheetData: XmlElement, row: number): XmlElement | undefined; /** Find or create the row, inserted in ascending r order. */ ensureRow(sheetData: XmlElement, row: number): XmlElement; /** The `c` element at `addr`, or undefined. */ findCell(sheetData: XmlElement, addr: CellAddress): XmlElement | undefined; /** * Find or create the cell at `addr` (row created too), inserted in * ascending column order within its row. */ ensureCell(sheetData: XmlElement, addr: CellAddress): XmlElement; /** * Remove `cell` (already located via {@link findCell}) from its row, * keeping the index's recorded counts coherent so lens-only usage never * triggers a spurious raw-mutation rebuild. */ removeCell(cell: XmlElement, addr: CellAddress): void; } //# sourceMappingURL=sheet-index.d.ts.map