mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
317 lines (316 loc) • 9.51 kB
TypeScript
import { ActionMiddlewareDisposer } from '../action/middleware';
import { Path } from '../parent/pathTypes';
import { Patch } from '../patch';
/**
* An undo/redo event without attached state.
*/
export type UndoEventWithoutAttachedState = UndoSingleEvent | UndoEventGroup;
/**
* An undo/redo event.
*/
export type UndoEvent = UndoEventWithoutAttachedState & {
/**
* The state saved before the event actions started / after the event actions finished.
*/
attachedState: {
/**
* The state saved before the event actions started.
*/
beforeEvent?: unknown;
/**
* The state saved after the event actions finished.
*/
afterEvent?: unknown;
};
};
/**
* Undo event type.
*/
export declare enum UndoEventType {
Single = "single",
Group = "group"
}
/**
* An undo/redo single event.
*/
export interface UndoSingleEvent {
/**
* Expresses this is a single event.
*/
readonly type: UndoEventType.Single;
/**
* Path to the object that invoked the action from its root.
*/
readonly targetPath: Path;
/**
* Name of the action that was invoked.
*/
readonly actionName: string;
/**
* Patches with changes done inside the action.
* Use `redo()` in the `UndoManager` to apply them.
*/
readonly patches: ReadonlyArray<Patch>;
/**
* Patches to undo the changes done inside the action.
* Use `undo()` in the `UndoManager` to apply them.
*/
readonly inversePatches: ReadonlyArray<Patch>;
}
/**
* An undo/redo event group.
*/
export interface UndoEventGroup {
/**
* Expresses this is an event group.
*/
readonly type: UndoEventType.Group;
/**
* Name of the group (if any).
*/
readonly groupName?: string;
/**
* Events that conform this group (might be single events or other nested groups).
*/
readonly events: ReadonlyArray<UndoEventWithoutAttachedState>;
}
declare const UndoStore_base: import('../model/Model')._Model<unknown, {
undoEvents: import('..').OptionalModelProp<UndoEvent[]>;
redoEvents: import('..').OptionalModelProp<UndoEvent[]>;
}, never, never>;
/**
* Store model instance for undo/redo actions.
* Do not manipulate directly, other that creating it.
*/
export declare class UndoStore extends UndoStore_base {
/**
* @ignore
*/
_clearUndo(): void;
/**
* @ignore
*/
_clearRedo(): void;
/**
* @ignore
*/
enforceMaxLevels({ maxUndoLevels, maxRedoLevels, }: {
maxUndoLevels?: number;
maxRedoLevels?: number;
}): void;
/**
* @ignore
*/
_undo({ maxRedoLevels }: {
maxRedoLevels: number | undefined;
}): void;
/**
* @ignore
*/
_redo({ maxUndoLevels }: {
maxUndoLevels: number | undefined;
}): void;
/**
* @ignore
*/
_addUndo({ event, maxUndoLevels }: {
event: UndoEvent;
maxUndoLevels: number | undefined;
}): void;
private _groupStack;
/**
* @ignore
*/
_addUndoToParentGroup(parentGroup: UndoEventGroup, event: UndoEventWithoutAttachedState): void;
/**
* @ignore
*/
get _currentGroup(): UndoEventGroup | undefined;
/**
* @ignore
*/
_startGroup(groupName: string | undefined, startRunning: boolean, options: UndoMiddlewareOptions<unknown> | undefined): {
pause: () => void;
resume: () => void;
end: () => void;
};
}
/**
* Manager class returned by `undoMiddleware` that allows you to perform undo/redo actions.
*/
export declare class UndoManager {
private readonly disposer;
private readonly subtreeRoot;
private readonly options;
/**
* The store currently being used to store undo/redo action events.
*/
readonly store: UndoStore;
/**
* The undo stack, where the first operation to undo will be the last of the array.
* Do not manipulate this array directly.
*/
get undoQueue(): ReadonlyArray<UndoEvent>;
/**
* The redo stack, where the first operation to redo will be the last of the array.
* Do not manipulate this array directly.
*/
get redoQueue(): ReadonlyArray<UndoEvent>;
/**
* The number of undo actions available.
*/
get undoLevels(): number;
/**
* If undo can be performed (if there is at least one undo action available).
*/
get canUndo(): boolean;
/**
* Clears the undo queue.
*/
clearUndo(): void;
/**
* The number of redo actions available.
*/
get redoLevels(): number;
/**
* If redo can be performed (if there is at least one redo action available)
*/
get canRedo(): boolean;
/**
* Clears the redo queue.
*/
clearRedo(): void;
/**
* Undoes the last action.
* Will throw if there is no action to undo.
*/
undo(): void;
/**
* Redoes the previous action.
* Will throw if there is no action to redo.
*/
redo(): void;
/**
* Disposes the undo middleware.
*/
dispose(): void;
private _isUndoRecordingDisabled;
/**
* Returns if undo recording is currently disabled or not for this particular `UndoManager`.
*/
get isUndoRecordingDisabled(): boolean;
/**
* Skips the undo recording mechanism for the code block that gets run synchronously inside.
*
* @template T Code block return type.
* @param fn Code block to run.
* @returns The value returned by the code block.
*/
withoutUndo<T>(fn: () => T): T;
/**
* Creates a custom group that can be continued multiple times and then ended.
* @param groupName Optional group name.
* @returns An API to continue/end the group.
*/
createGroup(groupName?: string): {
continue<T>(fn: () => T): T;
end(): void;
};
/**
* Runs a synchronous code block as an undo group.
* Note that nested groups are allowed.
*
* @param groupName Group name.
* @param fn Code block.
* @returns Code block return value.
*/
withGroup<T>(groupName: string, fn: () => T): T;
/**
* Runs a synchronous code block as an undo group.
* Note that nested groups are allowed.
*
* @param fn Code block.
* @returns Code block return value.
*/
withGroup<T>(fn: () => T): T;
/**
* Runs an asynchronous code block as an undo group.
* Note that nested groups are allowed.
*
* @param groupName Group name.
* @param fn Flow function.
* @returns Flow function return value.
*/
withGroupFlow<R>(groupName: string, fn: () => Generator<any, R, any>): Promise<R>;
/**
* Runs an asynchronous code block as an undo group.
* Note that nested groups are allowed.
*
* @param fn Flow function.
* @returns Flow function return value.
*/
withGroupFlow<R>(fn: () => Generator<any, R, any>): Promise<R>;
/**
* Creates an instance of `UndoManager`.
* Do not use directly, use `undoMiddleware` instead.
*
* @param disposer
* @param subtreeRoot
* @param [store]
*/
constructor(disposer: ActionMiddlewareDisposer, subtreeRoot: object, store: UndoStore | undefined, options: UndoMiddlewareOptions<unknown> | undefined);
}
/**
* Undo middleware options.
*/
export interface UndoMiddlewareOptions<S> {
/**
* Max number of undo levels to keep, or undefined for infinite.
*/
maxUndoLevels?: number;
/**
* Max number of redo levels to keep, or undefined for infinite.
*/
maxRedoLevels?: number;
/**
* Attached states are states that are saved/restored when undoing/redoing.
* Usually used to restore state that is not part of the document model such as focus, selection, scroll position, etc.
*/
attachedState?: {
/**
* Saves a certain state and associates it with the undo step. This state can be restored when undoing/redoing.
*/
save(): S;
/**
* Restores a certain state previously saved.
* @param s State to restore.
*/
restore(s: S): void;
};
}
/**
* Creates an undo middleware.
*
* @param subtreeRoot Subtree root target object.
* @param store Optional `UndoStore` where to store the undo/redo queues. Use this if you want to
* store such queues somewhere in your models. If none is provided it will reside in memory.
* @param options Extra options, such as how to save / restore certain snapshot of the state to be restored when undoing/redoing.
* @returns An `UndoManager` which allows you to do the manage the undo/redo operations and dispose of the middleware.
*/
export declare function undoMiddleware<S>(subtreeRoot: object, store?: UndoStore, options?: UndoMiddlewareOptions<S>): UndoManager;
/**
* Returns if the undo recording mechanism is currently disabled.
*
* @returns `true` if it is currently disabled, `false` otherwise.
*/
export declare function isGlobalUndoRecordingDisabled(): boolean;
/**
* Globally skips the undo recording mechanism for the code block that gets run synchronously inside.
* Consider using the `withoutUndo` method of a particular `UndoManager` instead.
*
* @template T Code block return type.
* @param fn Code block to run.
* @returns The value returned by the code block.
*/
export declare function withoutUndo<T>(fn: () => T): T;
export {};