undo-peasy
Version:
undo/redo for easy peasy
79 lines (78 loc) • 2.94 kB
TypeScript
import { Action, State } from "easy-peasy";
import { AnyAction } from "redux";
import { HistoryStore } from "./HistoryStore";
import { AnyObject } from "./Utils";
/** Implementation strategy overview for undo/redo
*
* Add easy-peasy actions for undo and redo. (Also add actions for reset and save, though these
* aren't typically needed by users.)
*
* Store a stack of undo/current/redo states. These are stored as json
* strings in the browser's localStorage key value store.
*
* Middleware to automatically trigger the save action after other
* easy-peasy or redux actions.
*
* Note that computed properties and view properties specified by the programmer are not
* saved. Computed and view properties are merged into the current app state
* on undo/redo.
*/
/**
* WithUndo specifies some actions and state to support Undo/Redo on your easy-peasy
* model type.
*
* The root application model interface should extend WithUndo.
*/
export interface WithUndo {
undoSave: Action<WithUndo, ActionAndState | void>;
undoReset: Action<WithUndo>;
undoUndo: Action<WithUndo>;
undoRedo: Action<WithUndo>;
undoGroupStart: Action<WithUndo, string | void | undefined>;
undoGroupComplete: Action<WithUndo>;
undoGroupIgnore: Action<WithUndo>;
}
interface ActionAndState {
action: AnyAction;
prevState?: AnyObject;
}
export declare type KeyPathFilter = (key: string, path: string[]) => boolean;
export interface UndoOptions<M extends AnyObject> {
/** save no more than this many undo states */
maxHistory?: number;
/** don't save state keys matching this filter (e.g. transient view in the state) */
noSaveKeys?: KeyPathFilter;
/** set to true to log each saved state */
logDiffs?: boolean;
/** set to true to log grouping levels */
logGroups?: boolean;
/** return true for actions that should not be saved into undo history */
skipAction?: ActionStateFilter<M>;
}
export declare type ActionStateFilter<M extends AnyObject> = (state: State<M>, action: AnyAction) => boolean;
/**
* Extend a model instance with undo actions and metadata
*
* The root application model should be wrapped in undoable().
* @param model application model
*/
export declare function undoable<M extends AnyObject>(model: M, historyOptions?: UndoOptions<M>): ModelWithUndo<M>;
export interface EnrichedModel<M> {
model: ModelWithUndo<M>;
history: HistoryStore;
}
export interface ControlApi {
undoGroup: <T>(fn: () => T) => T;
undoPause: () => void;
undoContinue: () => void;
}
/** (internal api for undoable(), exposes more for testing)
*
* extend a model instance with undo actions and metadata, and also return
* the history store.
*/
export declare function undoableModelAndHistory<M extends AnyObject>(model: M, options?: UndoOptions<M>): EnrichedModel<M>;
export declare type ModelWithUndo<T> = {
[P in keyof T]: T[P];
} & WithUndo;
export {};