import { type ITimestampStruct, type ITimespanStruct } from '../../../json-crdt-patch/clock';
import { UndEndIterator, type UndEndNext } from '../../../util/iterator';
/**
 * @category CRDT Node
 */
export interface Chunk<T> {
    /** Unique sortable ID of this chunk and its span. */
    id: ITimestampStruct;
    /** Length of the logical clock interval of this chunk. */
    span: number;
    /** Whether this chunk is deleted. */
    del: boolean;
    /** Actual content of the chunk, may be undefined if chunk is deleted. */
    data: T | undefined;
    /** Length of content in this subtree (this node and its children). */
    len: number;
    /** Parent. */
    p: Chunk<T> | undefined;
    /** Left. */
    l: Chunk<T> | undefined;
    /** Right. */
    r: Chunk<T> | undefined;
    /** Parent 2. */
    p2: Chunk<T> | undefined;
    /** Left 2. */
    l2: Chunk<T> | undefined;
    /** Right 2. */
    r2: Chunk<T> | undefined;
    /** Split link, next chunk which was split from this chunk. */
    s: Chunk<T> | undefined;
    /** Add more content to this chunk. */
    merge(content: T): void;
    /**
     * Split this chunk after given clock ticks. Minimal `ticks` is 1.
     */
    split(ticks: number): Chunk<T>;
    /** Mark chunk as deleted. */
    delete(): void;
    /** Return a deep copy of itself. */
    clone(): Chunk<T>;
    /** Return the data of the chunk, if not deleted. */
    view(): T & {
        slice: (start: number, end: number) => T;
    };
}
/**
 * @category CRDT Node
 */
export declare abstract class AbstractRga<T, C extends Chunk<T> = Chunk<T>> {
    readonly id: ITimestampStruct;
    root: Chunk<T> | undefined;
    ids: Chunk<T> | undefined;
    count: number;
    abstract view(): unknown;
    protected abstract createChunk(id: ITimestampStruct, content: T | undefined): Chunk<T>;
    protected abstract onChange(): void;
    constructor(id: ITimestampStruct);
    ins(after: ITimestampStruct, id: ITimestampStruct, content: T): void;
    insAt(position: number, id: ITimestampStruct, content: T): ITimestampStruct | undefined;
    protected insAfterRoot(after: ITimestampStruct, id: ITimestampStruct, content: T): void;
    protected insAfterChunk(after: ITimestampStruct, chunk: Chunk<T>, chunkOffset: number, id: ITimestampStruct, content: T): void;
    delete(spans: ITimespanStruct[]): void;
    protected deleteSpan(span: ITimespanStruct): void;
    find(position: number): undefined | ITimestampStruct;
    findChunk(position: number): undefined | [chunk: Chunk<T>, offset: number];
    findInterval(position: number, length: number): ITimespanStruct[];
    /** Rename to .rangeX() method? */
    findInterval2(from: ITimestampStruct, to: ITimestampStruct): ITimespanStruct[];
    /**
     * @note All ".rangeX()" method are not performance optimized. For hot paths
     * it is better to hand craft the loop.
     *
     * @param startChunk Chunk from which to start the range. If undefined, the
     *                   chunk containing `from` will be used. This is an optimization
     *                   to avoid a lookup.
     * @param from ID of the first element in the range.
     * @param to ID of the last element in the range.
     * @param callback Function to call for each chunk slice in the range. If it
     *     returns truthy value, the iteration will stop.
     * @returns Reference to the last chunk in the range.
     */
    range0(startChunk: Chunk<T> | undefined, from: ITimestampStruct, to: ITimestampStruct, callback: (chunk: Chunk<T>, off: number, len: number) => boolean | void): Chunk<T> | void;
    first(): C | undefined;
    last(): Chunk<T> | undefined;
    lastId(): ITimestampStruct | undefined;
    /** @todo Maybe use implementation from tree utils, if does not impact performance. */
    /** @todo Or better remove this method completely, as it does not require "this". */
    next(curr: Chunk<T>): Chunk<T> | undefined;
    /** @todo Maybe use implementation from tree utils, if does not impact performance. */
    /** @todo Or better remove this method completely, as it does not require "this". */
    prev(curr: Chunk<T>): Chunk<T> | undefined;
    /** Content length. */
    length(): number;
    /** Number of chunks. */
    size(): number;
    /** Returns the position of the first element in the chunk. */
    pos(chunk: Chunk<T>): number;
    chunks0(): UndEndNext<C>;
    chunks(): UndEndIterator<C>;
    setRoot(chunk: Chunk<T>): void;
    insertBefore(chunk: Chunk<T>, before: Chunk<T>): void;
    insertAfter(chunk: Chunk<T>, after: Chunk<T>): void;
    protected insertAfterRef(chunk: Chunk<T>, ref: ITimestampStruct, left: Chunk<T>): void;
    protected mergeContent(chunk: Chunk<T>, content: T): void;
    protected insertInside(chunk: Chunk<T>, at: Chunk<T>, offset: number): void;
    protected split(chunk: Chunk<T>, ticks: number): Chunk<T>;
    protected mergeTombstones(ch1: Chunk<T>, ch2: Chunk<T>): boolean;
    protected mergeTombstones2(start: Chunk<T>, end: Chunk<T>): void;
    rmTombstones(): void;
    deleteChunk(chunk: Chunk<T>): void;
    insertId(chunk: Chunk<T>): void;
    insertIdFast(chunk: Chunk<T>): void;
    protected deleteId(chunk: Chunk<T>): void;
    findById(after: ITimestampStruct): Chunk<T> | undefined;
    posById(id: ITimestampStruct): number | undefined;
    /**
     * @param id ID of character to start the search from.
     * @returns Previous ID in the RGA sequence.
     */
    prevId(id: ITimestampStruct): ITimestampStruct | undefined;
    spanView(span: ITimespanStruct): T[];
    splay(chunk: Chunk<T>): void;
    iterator(): () => Chunk<T> | undefined;
    ingest(size: number, next: () => Chunk<T>): void;
    private _ingest;
    protected toStringName(): string;
    toString(tab?: string): string;
    protected printChunk(tab: string, chunk: Chunk<T>): string;
    protected formatChunk(chunk: Chunk<T>): string;
}
