import type { Command, CommandResult, CoreCommandStack } from '../core';
/**
 * Function type for the `onCommandStackChanged` call-back of a `CommandStackSubscription`.
 *
 * @callback EditingContextChangedCallback
 *
 * @template K the type of key with which a command stack associates models
 *
 * @param eventType the type of change that occurred in the command stack
 * @param [command] the command, if any, related to the change. Only the `'flushed'` event does not include a `command`
 */
export type CommandStackChangedCallback<K> = (eventType: 'executed' | 'undone' | 'redone' | 'flushed', command?: Command<K>) => void;
/**
 * Function type for the `onDirtyStateChanged` call-back of a `CommandStackSubscription`.
 *
 * @callback DirtyStateChangedCallback
 *
 * @template K the type of key with which a command stack associates models
 *
 * @param dirtyStateChanges for each model ID whose dirty state has changed, whether it is now dirty or not
 */
export type DirtyStateChangedCallback<K> = (dirtyStateChanges: Map<K, boolean>) => void;
/**
 * A subscription to changes in the state of a {@link CommandStack}.
 * When the subscription is no longer needed, it should be `close()`d
 * to avoid the overhead of continuing to notify it.
 *
 * @template K the type of key with which a command stack associates models
 */
export interface CommandStackSubscription<K> {
    /**
     * A function to call to notify the client of editing context changes.
     */
    onCommandStackChanged?: CommandStackChangedCallback<K>;
    /**
     * A function to call to notify the client of dirty state changes.
     */
    onDirtyStateChanged?: DirtyStateChangedCallback<K>;
    /**
     * Stop receiving notifications of model changes.
     */
    close(): void;
}
/**
 * Options for configuration of the command stacks obtains from a {@link ModelManager}.
 */
export type CommandStackOptions = {
    /**
     * Whether the command stack keeps a history of commands for undo/redo.
     *
     * @default true
     */
    keepHistory?: boolean;
};
/**
 * An ordered history of the execution of commands on the models managed by a `ModelManager`.
 *
 * @template K the type of model ID used by the Model Manager
 */
export interface CommandStack<K = string> {
    /**
     * Execute a command on the stack.
     * If successful, that command becomes the next available to {@link undo}.
     *
     * The result is a mapping of commands to the changes that they applied to their target models,
     * which accounts for the case that the `command` is a compound.
     *
     * @param command a command to execute
     * @returns a description of the changes performed by the `command`, if available
     * @throws if the `command` is not executable
     */
    execute(command: Command<K>): CommandResult<K>;
    /**
     * Execute a command and append it to the command most recently executed.
     * If successful, that command is integrated into the appended command for {@link undo} and {@link redo}.
     *
     * As for {@link execute}, the result is a mapping of commands to the changes that they applied to their
     * target models, which accounts for the case that the `command` is a compound.
     *
     * @param command a command to execute and append onto the last executed command
     * @returns a description of the changes performed by the `command`, if available
     * @throws if the `command` is not executable or if there has been no command
     *  executed to append to
     */
    executeAndAppend(command: Command<K>): CommandResult<K>;
    /**
     * Undo the command most recently executed/redone.
     * If successful, that command becomes the next available to {@link redo}.
     *
     * @returns a description of the changes performed by undo, if available
     * @throws if there is no command to undo or if that command is not undoable
     *
     * @see {@link getUndoCommand}
     * @see {@link canUndo}
     */
    undo(): CommandResult<K>;
    /**
     * Redo the command most recently undone.
     * If successful, that command becomes the next available to {@link undo}.
     *
     * @returns a description of the changes performed by redo, if available
     * @throws if there is no command to redo or if that command is not redoable
     *
     * @see {@link getRedoCommand}
     * @see {@link canRedo}
     */
    redo(): CommandResult<K>;
    /**
     * Query whether a `command` can be executed.
     *
     * @param command a command to be executed
     * @returns whether the `command` can be executed
     * @see {@link execute}
     */
    canExecute(command: Command<K>): Promise<boolean>;
    /**
     * Query whether there is some command available to undo that can be undone.
     *
     * @returns whether the stack has a command to undo and that command is undoable
     * @see {@link getUndoCommand}
     */
    canUndo(): Promise<boolean>;
    /**
     * Query whether there is some command available to redo that can be redone.
     *
     * @returns whether the editing `context` has a command to redo and that command is redoable
     * @see {@link getRedoCommand}
     */
    canRedo(): Promise<boolean>;
    /**
     * Query what is the next command that would be undone by a request to {@link undo}.
     *
     * @returns the next undoable command, or `undefined` if none
     */
    getUndoCommand(): Command<K> | undefined;
    /**
     * Query what is the next command that would be redone by a request to {@link redo}.
     *
     * @returns the next redoable command, or `undefined` if none
     */
    getRedoCommand(): Command<K> | undefined;
    /**
     * Flush the stack.
     * All commands in the undo and redo history are removed and are returned
     * in the (temporal) order in which they were originally executed.
     *
     * @return the commands that were purged from the stack, or an empty array if none
     */
    flush(): Command<K>[];
    /**
     * Mark the the current top of the stack as the point where the models that
     * are edited in this context have been saved.
     * This should be done by a client that has saved those models to
     * persistent storage.
     *
     * @see {@link isDirty}
     * @see {@link getDirtyModels}
     */
    markSaved(): void;
    /**
     * Queries whether any commands have been executed, undone, or redone since
     * the last {@link markSaved save}.
     *
     * @returns whether I am dirty
     *
     * @see {@link markSaved}
     * @see {@link getDirtyModelIds}
     */
    isDirty(): boolean;
    /**
     * Query the IDs of models that have been modified by execution, undo, and redo
     * of commands since the last {@link markSaved save}.
     * This may include models that are assumed to be dirty because they were
     * modified at the time this `context` was last flushed.
     *
     * @see {@link markSaved}
     * @see {@link isDirty}
     */
    getDirtyModelIds(): K[];
    /**
     * Create a subscription to changes occurring in the command stack.
     * Each call creates a new subscription that, when no longer needed, {@link CommandStackSubscription.close should be closed} separately.
     *
     * @returns the command-stack subscription
     */
    subscribe(): CommandStackSubscription<K>;
    /**
     * Get the core stack underlying this command stack, for access to its advanced capabilities.
     *
     * @returns the core stack
     */
    getCoreCommandStack(): CoreCommandStack<K>;
}
/**
 * The implementation of the command stack wraps a {@link CoreCommandStack} and adds a private
 * {@link EditingContext} to all operation delegation.
 *
 * @template K the type of model ID used by the Model Manager
 */
export declare class CommandStackImpl<K = string> implements CommandStack<K> {
    private readonly delegate;
    /** The editing context that represent me in the shared delegate stack. */
    private readonly editingContext;
    /** My configuration options, defaulted where necessary to provide them all. */
    private readonly options;
    /**
     * Initializes me with the core command stack to which I `delegate` my implementation
     * and my unique `id` that I use as my editing context in the core command stack.
     *
     * @param delegate the core command stack to which I delegate my API with my editing context
     * @param id my identifier, which I use as my editing context
     */
    constructor(delegate: CoreCommandStack<K>, options: CommandStackOptions & {
        id: string;
    });
    execute(command: Command<K>): CommandResult<K>;
    executeAndAppend(command: Command<K>): CommandResult<K>;
    undo(): CommandResult<K>;
    redo(): CommandResult<K>;
    canExecute(command: Command<K>): Promise<boolean>;
    canUndo(): Promise<boolean>;
    canRedo(): Promise<boolean>;
    getUndoCommand(): Command<K> | undefined;
    getRedoCommand(): Command<K> | undefined;
    flush(): Command<K>[];
    markSaved(): void;
    isDirty(): boolean;
    getDirtyModelIds(): K[];
    subscribe(): CommandStackSubscription<K>;
    getCoreCommandStack(): CoreCommandStack<K>;
}
//# sourceMappingURL=command-stack.d.ts.map