/** * Dirty Tracker * * Tracks which pages and blocks need to be repainted during incremental layout updates. * This enables efficient partial repaints by identifying only the affected regions, * avoiding full document reflows during typing and editing operations. * * Tracking Strategy: * 1. Mark dirty regions when edits occur (pages, blocks, or ranges) * 2. Query dirty state to determine what needs repainting * 3. Clear dirty state after processing * 4. Support viewport-based queries for prioritizing visible content * * @module dirty-tracker */ /** * Represents a range of dirty content with reason for tracking. */ export interface DirtyRange { /** Starting page index (inclusive) */ startPage: number; /** Ending page index (inclusive) */ endPage: number; /** Starting block index (inclusive) */ startBlock: number; /** Ending block index (inclusive) */ endBlock: number; /** Reason this range became dirty */ reason: 'edit' | 'resize' | 'scroll' | 'pagination'; } /** * DirtyTracker manages dirty state for incremental layout updates. * * This class provides fine-grained tracking of which pages and blocks need * repainting, enabling efficient partial updates during typing bursts. */ export declare class DirtyTracker { private dirtyPages; private dirtyBlocks; private dirtyRanges; private maxPageTracked; /** * Mark a specific page as dirty. * * @param pageIndex - Zero-based page index to mark dirty * @param reason - Reason for marking dirty */ markPageDirty(pageIndex: number, reason: DirtyRange['reason']): void; /** * Mark a range of blocks as dirty. * * @param startBlock - Starting block index (inclusive) * @param endBlock - Ending block index (inclusive) * @param reason - Reason for marking dirty */ markBlocksDirty(startBlock: number, endBlock: number, reason: DirtyRange['reason']): void; /** * Mark all pages from a starting point as dirty. * Used for pagination changes that affect all subsequent pages. * * @param startPage - Starting page index (inclusive) * @param reason - Reason for marking dirty (typically 'pagination') */ markDirtyFrom(startPage: number, reason: DirtyRange['reason']): void; /** * Get dirty pages that intersect with the viewport range. * * @param viewportStart - Starting page index of viewport (inclusive) * @param viewportEnd - Ending page index of viewport (inclusive) * @returns Sorted array of dirty page indices within viewport */ getDirtyPagesInViewport(viewportStart: number, viewportEnd: number): number[]; /** * Get all dirty ranges. * * @returns Array of dirty ranges (copy to prevent external mutation) */ getDirtyRanges(): DirtyRange[]; /** * Clear dirty state for the specified pages. * * @param pages - Array of page indices to clear */ clearDirty(pages: number[]): void; /** * Check if any dirty content exists. * * @returns True if there are any dirty pages, blocks, or ranges */ hasDirty(): boolean; /** * Clear all dirty state. */ clearAll(): void; /** * Add a new range or merge with existing compatible ranges. * * @param newRange - Range to add * @private */ private addOrMergeRange; /** * Check if two ranges overlap or are adjacent. * * This method is used for range merging optimization. Two ranges are considered * mergeable if they overlap or are directly adjacent (touching). This prevents * fragmentation of the dirty ranges list. * * Algorithm: * - Ranges [a, b] and [c, d] overlap if: a <= d+1 AND c <= b+1 * - The +1 accounts for adjacent ranges (e.g., [1,3] and [4,6] are adjacent) * * Examples: * - [1, 3] and [2, 5]: overlap (intersect) * - [1, 3] and [4, 6]: adjacent (touch at boundary) * - [1, 3] and [5, 7]: separate (gap of 1) * * Complexity: O(1) * * @param start1 - Start of first range (inclusive) * @param end1 - End of first range (inclusive) * @param start2 - Start of second range (inclusive) * @param end2 - End of second range (inclusive) * @returns True if ranges overlap or are adjacent, false otherwise * @private */ private rangesOverlap; } //# sourceMappingURL=dirty-tracker.d.ts.map