import { Model } from '../model';
import { type ITimestampStruct, type Patch } from '../../json-crdt-patch';
import type { Printable } from 'tree-dump/lib/types';
import type { JsonNode } from '../nodes/types';
/**
 * The `Log` represents a history of patches applied to a JSON CRDT model. It
 * consists of: (1) a starting {@link Model} instance, (2) a list of {@link Patch} instances,
 * that can be applied to the starting model to reach the current state of the
 * document, and (3) the current state of the document, the `end` {@link Model}.
 *
 * The log can be used to replay the history of patches to any point in time,
 * from the "start" to the "end" of the log, and return the resulting {@link Model}
 * state.
 *
 * @todo Make this implement UILifecycle (start, stop) interface.
 */
export declare class Log<N extends JsonNode = JsonNode<any>, Metadata extends Record<string, unknown> = Record<string, unknown>> implements Printable {
    /**
     * Model factory function that creates a new JSON CRDT model instance, which
     * is used as the starting point of the log. It is called every time a new
     * model is needed to replay the log.
     *
     * @readonly Internally this function may be updated, but externally it is
     *           read-only.
     *
     * @todo Rename to something else to give way to a `start()` in UILifecycle.
     *     Call "snapshot". Maybe introduce `type Snapshot<N> = () => Model<N>;`.
     */
    start: () => Model<N>;
    /**
     * The end of the log, the current state of the document. It is the model
     * instance that is used to apply new patches to the log.
     *
     * @readonly
     */
    readonly end: Model<N>;
    /**
     * Creates a `PatchLog` instance from a newly JSON CRDT model. Checks if
     * the model API buffer has any initial operations applied, if yes, it
     * uses them to create the initial state of the log.
     *
     * @param model A new JSON CRDT model, just created with
     *              `Model.create()` or `Model.withServerClock()`.
     * @returns A new `PatchLog` instance.
     */
    static fromNewModel<N extends JsonNode = JsonNode<any>>(model: Model<N>): Log<N>;
    static from<N extends JsonNode = JsonNode<any>>(model: Model<N>): Log<N>;
    /**
     * Custom metadata associated with the log, it will be stored in the log's
     * header when serialized with {@link LogEncoder} and can be used to store
     * additional information about the log.
     */
    metadata: Metadata;
    /**
     * The collection of patches which are applied to the `start()` model to reach
     * the `end` model. The patches in the log, stored in an AVL tree for
     * efficient replaying. The patches are sorted by their logical timestamps
     * and applied in causal order.
     *
     * @readonly
     */
    patches: {
        min: import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        root: import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        max: import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        readonly comparator: import("sonic-forest/lib/types").Comparator<ITimestampStruct>;
        set(k: ITimestampStruct, v: Patch): import("sonic-forest/lib/types").SonicNodePublicReference<import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch>>;
        find(k: ITimestampStruct): import("sonic-forest/lib/types").SonicNodePublicReference<import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch>> | undefined;
        get(k: ITimestampStruct): Patch | undefined;
        del(k: ITimestampStruct): boolean;
        clear(): void;
        has(k: ITimestampStruct): boolean;
        _size: number;
        size(): number;
        isEmpty(): boolean;
        getOrNextLower(k: ITimestampStruct): import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        forEach(fn: (node: import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch>) => void): void;
        first(): import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        last(): import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        readonly next: <N_1 extends import("sonic-forest/lib/types").HeadlessNode>(curr: N_1) => N_1 | undefined;
        iterator0(): () => import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch> | undefined;
        iterator(): Iterator<import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch>, any, undefined>;
        entries(): IterableIterator<import("sonic-forest/lib/types").ITreeNode<ITimestampStruct, Patch>>;
        toString(tab: string): string;
    };
    private __onPatch;
    private __onFlush;
    constructor(
    /**
     * Model factory function that creates a new JSON CRDT model instance, which
     * is used as the starting point of the log. It is called every time a new
     * model is needed to replay the log.
     *
     * @readonly Internally this function may be updated, but externally it is
     *           read-only.
     *
     * @todo Rename to something else to give way to a `start()` in UILifecycle.
     *     Call "snapshot". Maybe introduce `type Snapshot<N> = () => Model<N>;`.
     */
    start: () => Model<N>, 
    /**
     * The end of the log, the current state of the document. It is the model
     * instance that is used to apply new patches to the log.
     *
     * @readonly
     */
    end?: Model<N>, metadata?: Metadata);
    /**
     * Call this method to destroy the {@link Log} instance. It unsubscribes patch
     * and flush listeners from the `end` model and clears the patch log.
     */
    destroy(): void;
    /**
     * Creates a new model instance using the `start()` factory function and
     * replays all patches in the log to reach the current state of the document.
     *
     * @returns A new model instance with all patches replayed.
     */
    replayToEnd(): Model<N>;
    /**
     * Replays the patch log until a specified timestamp, including the patch
     * at the given timestamp. The model returned is a new instance of `start()`
     * with patches replayed up to the given timestamp.
     *
     * @param ts Timestamp ID of the patch to replay to.
     * @param inclusive If `true`, the patch at the given timestamp `ts` is included,
     *     otherwise replays up to the patch before the given timestamp. Default is `true`.
     * @returns A new model instance with patches replayed up to the given timestamp.
     */
    replayTo(ts: ITimestampStruct, inclusive?: boolean): Model<N>;
    /**
     * Advance the start of the log to a specified timestamp, excluding the patch
     * at the given timestamp. This method removes all patches from the log that
     * are older than the given timestamp and updates the `start()` factory
     * function to replay the log from the new start.
     *
     * @param ts Timestamp ID of the patch to advance to.
     */
    advanceTo(ts: ITimestampStruct): void;
    /**
     * Finds the latest patch for a given session ID.
     *
     * @param sid Session ID to find the latest patch for.
     * @return The latest patch for the given session ID, or `undefined` if no
     *     such patch exists.
     */
    findMax(sid: number): Patch | undefined;
    /**
     * @returns A deep clone of the log, including the start function, metadata,
     *     patches, and the end model.
     */
    clone(): Log<N, Metadata>;
    /**
     * Rebase a batch of patches on top of the current end of the log, or on top
     * of the latest patch for a given session ID.
     *
     * @param batch A batch of patches to rebase.
     * @param sid Session ID to find the latest patch for rebasing. If not provided,
     *     the latest patch in the log is used.
     * @returns The rebased patches.
     */
    rebaseBatch(batch: Patch[], sid?: number): Patch[];
    /**
     * Resets the log to the state of another log. Consumes all state fron the `to`
     * log. The `to` log will be destroyed and should not be used after calling
     * this method.
     *
     * If you want to preserve the `to` log, use `.clone()` method first.
     *
     * ```ts
     * const log1 = new Log();
     * const log2 = new Log();
     * log1.reset(log2.clone());
     * ```
     *
     * @param to The log to consume the state from.
     */
    reset(to: Log<N, Metadata>): void;
    /**
     * Creates a patch which reverts the given patch. The RGA insertion operations
     * are reversed just by deleting the inserted values. All other operations
     * require time travel to the state just before the patch was applied, so that
     * a copy of a mutated object can be created and inserted back into the model.
     *
     * @param patch The patch to undo
     * @returns A new patch that undoes the given patch
     */
    undo(patch: Patch): Patch;
    toString(tab?: string): string;
}
