import { AnchorLocator, StoredSchemaRepository, IForestSubscription, AnchorSetRootEvents, Anchor, AnchorNode, IEditableForest, DetachedFieldIndex, Revertible, ChangeFamily } from "../core";
import { HasListeners, IEmitter, ISubscribable } from "../events";
import { IDefaultEditBuilder, DefaultChangeset, DefaultEditBuilder } from "../feature-libraries";
import { SharedTreeBranch } from "../shared-tree-core";
import { TransactionResult } from "../util";
/**
 * Events for {@link ITreeCheckout}.
 * @beta
 */
export interface CheckoutEvents {
    /**
     * A batch of changes has finished processing and the view is in a consistent state.
     * It is once again safe to access the EditableTree, Forest and AnchorSet.
     *
     * @remarks
     * This is mainly useful for knowing when to do followup work scheduled during events from Anchors.
     */
    afterBatch(): void;
    /**
     * A revertible change has been made to this view.
     * Applications which subscribe to this event are expected to revert or discard revertibles they acquire, if they so choose (failure to do so will leak memory).
     * The provided revertible is inherently bound to the view that raised the event, calling `revert` won't apply to forked views.
     *
     * @remarks
     * This event provides a {@link Revertible} object that can be used to revert the change.
     */
    revertible(revertible: Revertible): void;
}
/**
 * Provides a means for interacting with a SharedTree.
 * This includes reading data from the tree and running transactions to mutate the tree.
 * @remarks This interface should not have any implementations other than those provided by the SharedTree package libraries.
 * @privateRemarks
 * API for interacting with a {@link SharedTreeBranch}.
 * Implementations of this interface must implement the {@link branchKey} property.
 * @alpha
 */
export interface ITreeCheckout extends AnchorLocator {
    /**
     * Read and Write access for schema stored in the document.
     *
     * These APIs are temporary and will be replaced with different abstractions (View Schema based) in a different place later.
     *
     * TODO:
     * Editing of this should be moved into transactions with the rest of tree editing to they can be intermixed.
     * This will be done after the relations between views, branches and Indexes are figured out.
     *
     * TODO:
     * Public APIs for dealing with schema should be in terms of View Schema, and schema update policies.
     * The actual stored schema should be hidden (or ar least not be the most prominent way to interact with schema).
     *
     * TODO:
     * Something should ensure the document contents are always in schema.
     */
    readonly storedSchema: StoredSchemaRepository;
    /**
     * Current contents.
     * Updated by edits (local and remote).
     * Use `editor` to create a local edit.
     */
    readonly forest: IForestSubscription;
    /**
     * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.
     * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.
     */
    readonly editor: IDefaultEditBuilder;
    /**
     * A collection of functions for managing transactions.
     */
    readonly transaction: ITransaction;
    /**
     * Spawn a new view which is based off of the current state of this view.
     * Any mutations of the new view will not apply to this view until the new view is merged back into this view via `merge()`.
     */
    fork(): ITreeCheckoutFork;
    /**
     * Apply all the new changes on the given view to this view.
     * @param view - a view which was created by a call to `fork()`.
     * It is automatically disposed after the merge completes.
     * @remarks All ongoing transactions (if any) in `view` will be committed before the merge.
     */
    merge(view: ITreeCheckoutFork): void;
    /**
     * Apply all the new changes on the given view to this view.
     * @param view - a view which was created by a call to `fork()`.
     * @param disposeView - whether or not to dispose `view` after the merge completes.
     * @remarks All ongoing transactions (if any) in `view` will be committed before the merge.
     */
    merge(view: ITreeCheckoutFork, disposeView: boolean): void;
    /**
     * Rebase the given view onto this view.
     * @param view - a view which was created by a call to `fork()`. It is modified by this operation.
     */
    rebase(view: ITreeCheckoutFork): void;
    /**
     * Events about this view.
     */
    readonly events: ISubscribable<CheckoutEvents>;
    /**
     * Events about the root of the tree in this view.
     */
    readonly rootEvents: ISubscribable<AnchorSetRootEvents>;
}
/**
 * Creates a {@link TreeCheckout}.
 * @param args - an object containing optional components that will be used to build the view.
 * Any components not provided will be created by default.
 * @remarks This does not create a {@link SharedTree}, but rather a view with the minimal state
 * and functionality required to implement {@link ITreeCheckout}.
 */
export declare function createTreeCheckout(args?: {
    branch?: SharedTreeBranch<DefaultEditBuilder, DefaultChangeset>;
    changeFamily?: ChangeFamily<DefaultEditBuilder, DefaultChangeset>;
    schema?: StoredSchemaRepository;
    forest?: IEditableForest;
    events?: ISubscribable<CheckoutEvents> & IEmitter<CheckoutEvents> & HasListeners<CheckoutEvents>;
    removedRoots?: DetachedFieldIndex;
}): TreeCheckout;
/**
 * A collection of functions for managing transactions.
 * Transactions allow edits to be batched into atomic units.
 * Edits made during a transaction will update the local state of the tree immediately, but will be squashed into a single edit when the transaction is committed.
 * If the transaction is aborted, the local state will be reset to what it was before the transaction began.
 * Transactions may nest, meaning that a transaction may be started while a transaction is already ongoing.
 *
 * To avoid updating observers of the view state with intermediate results during a transaction,
 * use {@link ITreeCheckout#fork} and {@link ISharedTreeFork#merge}.
 * @alpha
 */
export interface ITransaction {
    /**
     * Start a new transaction.
     * If a transaction is already in progress when this new transaction starts, then this transaction will be "nested" inside of it,
     * i.e. the outer transaction will still be in progress after this new transaction is committed or aborted.
     */
    start(): void;
    /**
     * Close this transaction by squashing its edits and committing them as a single edit.
     * If this is the root view and there are no ongoing transactions remaining, the squashed edit will be submitted to Fluid.
     */
    commit(): TransactionResult.Commit;
    /**
     * Close this transaction and revert the state of the tree to what it was before this transaction began.
     */
    abort(): TransactionResult.Abort;
    /**
     * True if there is at least one transaction currently in progress on this view, otherwise false.
     */
    inProgress(): boolean;
}
/**
 * Branch (like in a version control system) of SharedTree.
 *
 * {@link ITreeCheckout} that has forked off of the main trunk/branch.
 * @alpha
 */
export interface ITreeCheckoutFork extends ITreeCheckout {
    /**
     * Rebase the changes that have been applied to this view over all the new changes in the given view.
     * @param view - Either the root view or a view that was created by a call to `fork()`. It is not modified by this operation.
     */
    rebaseOnto(view: ITreeCheckout): void;
}
/**
 * An implementation of {@link ITreeCheckoutFork}.
 */
export declare class TreeCheckout implements ITreeCheckoutFork {
    readonly transaction: ITransaction;
    private readonly branch;
    private readonly changeFamily;
    readonly storedSchema: StoredSchemaRepository;
    readonly forest: IEditableForest;
    readonly events: ISubscribable<CheckoutEvents> & IEmitter<CheckoutEvents> & HasListeners<CheckoutEvents>;
    private readonly removedRoots;
    constructor(transaction: ITransaction, branch: SharedTreeBranch<DefaultEditBuilder, DefaultChangeset>, changeFamily: ChangeFamily<DefaultEditBuilder, DefaultChangeset>, storedSchema: StoredSchemaRepository, forest: IEditableForest, events: ISubscribable<CheckoutEvents> & IEmitter<CheckoutEvents> & HasListeners<CheckoutEvents>, removedRoots?: DetachedFieldIndex);
    get rootEvents(): ISubscribable<AnchorSetRootEvents>;
    get editor(): IDefaultEditBuilder;
    locate(anchor: Anchor): AnchorNode | undefined;
    fork(): TreeCheckout;
    rebase(view: TreeCheckout): void;
    rebaseOnto(view: ITreeCheckout): void;
    merge(view: TreeCheckout): void;
    merge(view: TreeCheckout, disposeView: boolean): void;
    /**
     * Dispose this view, freezing its state and allowing the SharedTree to release resources required by it.
     * Attempts to further mutate or dispose this view will error.
     */
    dispose(): void;
}
/**
 * Run a synchronous transaction on the given shared tree view.
 * This is a convenience helper around the {@link SharedTreeFork#transaction} APIs.
 * @param view - the view on which to run the transaction
 * @param transaction - the transaction function. This will be executed immediately. It is passed `view` as an argument for convenience.
 * If this function returns an `Abort` result then the transaction will be aborted. Otherwise, it will be committed.
 * @returns whether or not the transaction was committed or aborted
 * @alpha
 */
export declare function runSynchronous(view: ITreeCheckout, transaction: (view: ITreeCheckout) => TransactionResult | void): TransactionResult;
//# sourceMappingURL=treeCheckout.d.ts.map