/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { OpSpaceCompressedId, SessionId, SessionSpaceCompressedId, StableId } from "@fluidframework/id-compressor";
import { type Brand, type JsonCompatibleReadOnly, type NestedMap, RangeMap } from "../../util/index.js";
import type { RevertibleAlpha } from "../revertible.js";
/**
 * The identifier for a particular session/user/client that can generate `GraphCommit`s
 */
export declare const SessionIdSchema: import("@sinclair/typebox").TUnsafe<SessionId>;
/**
 * A unique identifier for a commit. Commits that have been rebased, but are semantically
 * the same, will share the same revision tag.
 *
 * The constant 'root' is reserved for the trunk base: minting a SessionSpaceCompressedId is not
 * possible on readonly clients. These clients generally don't need ids, but  must be done at tree initialization time.
 */
export type RevisionTag = SessionSpaceCompressedId | "root";
export type EncodedRevisionTag = Brand<OpSpaceCompressedId, "EncodedRevisionTag"> | "root";
export declare const RevisionTagSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"root">, import("@sinclair/typebox").TUnsafe<Brand<OpSpaceCompressedId, "EncodedRevisionTag">>]>;
export type EncodedStableId = Brand<StableId, "EncodedStableId">;
export declare const StableIdSchema: import("@sinclair/typebox").TString;
/**
 * An ID which is unique within a revision of a `ModularChangeset`.
 * @remarks
 * Always a real number (never `NaN` or +/- `Infinity`).
 *
 * A `ModularChangeset` which is a composition of multiple revisions may contain duplicate `ChangesetLocalId`s,
 * but they are unique when qualified by the revision of the change they are used in.
 */
export type ChangesetLocalId = Brand<number, "ChangesetLocalId">;
/**
 * A globally unique ID for an atom of change, or a node associated with the atom of change.
 * *
 * @privateRemarks
 * TODO: Rename this to be more general.
 */
export interface ChangeAtomId {
    /**
     * Uniquely identifies the changeset within which the change was made.
     * Only undefined when referring to an anonymous changesets.
     */
    readonly revision?: RevisionTag;
    /**
     * Uniquely identifies, in the scope of the changeset, the change made to the field.
     */
    readonly localId: ChangesetLocalId;
}
export type EncodedChangeAtomId = [ChangesetLocalId, EncodedRevisionTag] | ChangesetLocalId;
export type ChangeAtomIdMap<T> = NestedMap<RevisionTag | undefined, ChangesetLocalId, T>;
/**
 * Returns true iff `a` and `b` are the same.
 */
export declare function areEqualChangeAtomIds(a: ChangeAtomId, b: ChangeAtomId): boolean;
export declare function areEqualChangeAtomIdOpts(a: ChangeAtomId | undefined, b: ChangeAtomId | undefined): boolean;
/**
 * Returns a ChangeAtomId with the given revision and local ID.
 */
export declare function makeChangeAtomId(localId: ChangesetLocalId, revision?: RevisionTag): ChangeAtomId;
export declare function asChangeAtomId(id: ChangesetLocalId | ChangeAtomId): ChangeAtomId;
export declare function taggedAtomId(id: ChangeAtomId, revision: RevisionTag | undefined): ChangeAtomId;
export declare function taggedOptAtomId(id: ChangeAtomId | undefined, revision: RevisionTag | undefined): ChangeAtomId | undefined;
export declare function offsetChangeAtomId<T extends ChangeAtomId>(id: T, offset: number): T;
export declare function compareChangesetLocalIds(a: ChangesetLocalId, b: ChangesetLocalId): number;
export declare function comparePartialChangesetLocalIds(a: ChangesetLocalId | undefined, b: ChangesetLocalId | undefined): number;
/**
 * A node in a graph of commits. A commit's parent is the commit on which it was based.
 */
export interface GraphCommit<TChange> {
    /**
     * The tag for this commit.
     * @remarks
     * If this commit is rebased, the corresponding rebased commit will retain this tag.
     * With the exception of transaction commits (which all share the same tag), this tag is unique within a given branch history.
     */
    readonly revision: RevisionTag;
    /** The change that will result from applying this commit */
    readonly change: TChange;
    /** The parent of this commit, on whose change this commit's change is based */
    readonly parent?: GraphCommit<TChange>;
}
/**
 * The type of a commit. This is used to describe the context in which the commit was created.
 *
 * @public
 */
export declare enum CommitKind {
    /** A commit corresponding to a change that is not the result of an undo/redo from this client. */
    Default = 0,
    /** A commit that is the result of an undo from this client. */
    Undo = 1,
    /** A commit that is the result of a redo from this client. */
    Redo = 2
}
/**
 * Information about a commit that has been applied.
 *
 * @sealed @public
 */
export interface CommitMetadata {
    /**
     * A {@link CommitKind} enum value describing whether the commit represents an Edit, an Undo, or a Redo.
     */
    readonly kind: CommitKind;
    /**
     * Indicates whether the commit is a local edit
     */
    readonly isLocal: boolean;
}
/**
 * Information about a change that has been applied by the local client.
 * @sealed @alpha
 */
export interface LocalChangeMetadata extends CommitMetadata {
    /**
     * Whether the change was made on the local machine/client or received from a remote client.
     */
    readonly isLocal: true;
    /**
     * Returns a serializable object that encodes the change.
     * @remarks This is only available for local changes.
     * This change object can be {@link TreeBranchAlpha.applyChange | applied to another branch} in the same state as the one which generated it.
     * The change object must be applied to a SharedTree with the same IdCompressor session ID as it was created from.
     * @privateRemarks
     * This is a `SerializedChange` from treeCheckout.ts.
     */
    getChange(): JsonCompatibleReadOnly;
    /**
     * Returns an object (a {@link RevertibleAlpha | "revertible"}) that can be used to revert the change that produced this event.
     * @remarks This is only available for local changes.
     * If the change is not revertible (for example, it was a change to the application schema), then this will return `undefined`.
     * Revertibles should be disposed when they are no longer needed.
     * @param onDisposed - A callback that will be invoked when the `Revertible` is disposed.
     * This happens when the `Revertible` is disposed manually or when the `TreeView` that the `Revertible` belongs to is disposed - whichever happens first.
     * This is typically used to clean up any resources associated with the `Revertible` in the host application.
     * @throws Throws an error if called outside the scope of the `changed` event that provided it.
     */
    getRevertible(onDisposed?: (revertible: RevertibleAlpha) => void): RevertibleAlpha | undefined;
    /**
     * Optional label provided by the user when commit was created.
     * This can be used by undo/redo to group or classify edits.
     */
    readonly label?: unknown;
    /**
     * A set of {@link RunTransactionParams.label | labels} for all transactions (nested or otherwise)
     * that made up this change.
     * This can be used to identify, group, or filter changes — for example, to decide whether a change
     * should be included in an undo/redo stack.
     *
     * @remarks
     * The optional {@link TransactionLabels.tree | tree} property provides the structural nesting
     * of the transactions as a {@link LabelTree}.
     *
     * The `tree` property is present whenever the change was produced by a transaction that
     * includes at least one label. If the change was unlabeled,
     * `tree` is `undefined` and the set is empty.
     *
     * @example
     * Checking whether a change was produced by a specific kind of transaction:
     * ```typescript
     * branch.events.on("changed", (metadata) => {
     *   if (metadata.labels.has("testLabel")) {
     *     // This change came from a transaction labeled "testLabel"
     *   }
     * });
     * ```
     *
     * @example
     * A nested transaction produces a tree that reflects the nesting:
     * ```typescript
     * tree.runTransaction(() => {
     *   tree.runTransaction(() => { ... }, { label: "inner" });
     * }, { label: "outer" });
     * // metadata.labels.has("inner") === true
     * // metadata.labels.tree will be:
     * //   { label: "outer", sublabels: [{ label: "inner", sublabels: [] }] }
     * ```
     */
    readonly labels: TransactionLabels;
}
/**
 * A tree representing the nesting structure of transaction labels.
 *
 * @remarks
 * Each transaction contributes a node whose {@link LabelTree.label} is its
 * {@link RunTransactionParams.label | label} (or `undefined` if no label was provided).
 * When transactions are nested, inner transaction nodes become {@link LabelTree.sublabels | sublabels}
 * of outer ones.
 *
 * @sealed @alpha
 */
export interface LabelTree {
    /**
     * The label for this transaction, or `undefined` if no label was provided.
     */
    label: unknown;
    /**
     * The label trees of any nested transactions within this one.
     */
    sublabels: LabelTree[];
}
/**
 * A set of transaction labels with an optional structural tree.
 *
 * @remarks
 * The set contains all label values from the transactions that produced the change.
 * Use standard {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set | Set}
 * methods to check for specific labels.
 *
 * The optional {@link TransactionLabels.tree | tree} property provides the structural nesting
 * of the transactions as a {@link LabelTree}.
 *
 * @sealed @alpha
 */
export type TransactionLabels = Set<unknown> & {
    tree?: LabelTree;
};
/**
 * Information about a change that has been applied by a remote client.
 * @sealed @alpha
 */
export interface RemoteChangeMetadata extends CommitMetadata {
    /**
     * Whether the change was made on the local machine/client or received from a remote client.
     */
    readonly isLocal: false;
    /**
     * Returns a serializable object that encodes the change.
     * @remarks This is only available for {@link LocalChangeMetadata | local changes}.
     */
    readonly getChange?: undefined;
    /**
     * Returns an object (a {@link RevertibleAlpha | "revertible"}) that can be used to revert the change that produced this event.
     * @remarks This is only available for {@link LocalChangeMetadata | local changes}.
     */
    readonly getRevertible?: undefined;
    /**
     * Label provided by the user when commit was created.
     * @remarks This is only available for {@link LocalChangeMetadata | local changes}.
     */
    readonly label?: undefined;
    /**
     * A set of labels from nested transaction labels.
     * @remarks This is always empty for remote changes. Labels are only available for {@link LocalChangeMetadata | local changes}.
     */
    readonly labels: TransactionLabels;
}
/**
 * Information about a {@link LocalChangeMetadata | local} or {@link RemoteChangeMetadata | remote} change that has been applied.
 * @sealed @alpha
 */
export type ChangeMetadata = LocalChangeMetadata | RemoteChangeMetadata;
/**
 * Creates a new graph commit object. This is useful for creating copies of commits with different parentage.
 * @param parent - the parent of the new commit
 * @param commit - the contents of the new commit object
 * @returns the new commit object
 */
export declare function mintCommit<TChange>(parent: GraphCommit<TChange>, commit: Omit<GraphCommit<TChange>, "parent">): GraphCommit<TChange>;
export type ChangeAtomIdRangeMap<V> = RangeMap<ChangeAtomId, V>;
export declare function newChangeAtomIdRangeMap<V>(offsetValue?: (value: V, offset: number) => V): ChangeAtomIdRangeMap<V>;
export declare function subtractChangeAtomIds(a: ChangeAtomId, b: ChangeAtomId): number;
/**
 * Compares two {@link RevisionTag}s to form a strict total ordering.
 * @remarks This function tolerates arbitrary strings, not just the string "root".
 * It sorts as follows: `undefined` \< `string` \< `number`
 */
export declare function comparePartialRevisions(a: RevisionTag | undefined, b: RevisionTag | undefined): number;
//# sourceMappingURL=types.d.ts.map