/** * @license * Copyright (c) 2025 Handsoncode. All rights reserved. */ import { SimpleCellAddress } from './Cell'; import { FormulaTransformer } from './dependencyTransformers/Transformer'; import { Ast, ParserWithCaching } from './parser'; import { Statistics } from './statistics/Statistics'; import { UndoRedo } from './UndoRedo'; /** * Manages lazy application of formula AST transformations. * * ## Problem * Structural operations (adding/removing rows/columns, moving cells, renaming sheets) * require updating every formula that references the affected area. Applying these * transformations eagerly to all formulas after every operation is expensive, especially * for large spreadsheets with many formulas. * * ## Solution: Lazy Transformation * Instead of transforming all formulas immediately, this service stores transformations * in a queue. Each formula vertex (FormulaVertex) and column index entry (ValueIndex) * tracks its own version number. When a consumer needs up-to-date data, it calls * `applyTransformations()` with its current version and receives all transformations * accumulated since that version. * * ## Compaction * Over time, the transformations array grows unboundedly. To prevent this memory leak, * the engine periodically triggers compaction when the number of accumulated * transformations reaches the configurable `maxPendingLazyTransformations`: * * 1. All FormulaVertex instances are forced to apply pending transformations * (via `DependencyGraph.forceApplyPostponedTransformations()`). * 2. All ColumnIndex entries are forced to apply pending transformations * (via `ColumnSearchStrategy.forceApplyPostponedTransformations()`). * 3. `compact()` is called, which advances `versionOffset` and clears the * transformations array. * 4. `UndoRedo.cleanupOrphanedOldData()` removes any oldData entries that were * written during forced application but belong to already-evicted undo entries. * * The `versionOffset` ensures that version numbers remain globally consistent * after compaction: `version() = versionOffset + transformations.length`. */ export declare class LazilyTransformingAstService { private readonly stats; private readonly maxPendingLazyTransformations; parser?: ParserWithCaching; undoRedo?: UndoRedo; private transformations; private versionOffset; private combinedTransformer?; constructor(stats: Statistics, maxPendingLazyTransformations: number); version(): number; addTransformation(transformation: FormulaTransformer): number; beginCombinedMode(sheet: number): void; commitCombinedMode(): number; applyTransformations(ast: Ast, address: SimpleCellAddress, version: number): [Ast, SimpleCellAddress, number]; getTransformationsFrom(version: number, filter?: (transformation: FormulaTransformer) => boolean): IterableIterator; /** * Returns true when enough transformations have accumulated to justify the cost * of forcing all consumers (FormulaVertex, ColumnIndex) to apply pending changes. */ needsCompaction(): boolean; /** * Compacts the transformations array by discarding all entries that have already * been applied by every consumer. Safe to call only after all FormulaVertex and * ColumnIndex consumers have been brought up to the current version. * After calling, UndoRedo.cleanupOrphanedOldData() must be invoked to remove * oldData entries written during forceApplyPostponedTransformations for * already-evicted undo entries. */ compact(): void; }