function trackUndo()

in src/legacy/createUndo.ts [144:183]


function trackUndo<T>(
    actionName: string,
    action: () => T,
    undoVerifiesChanges: boolean
): UndoResult<T> {
    initializeSpy();
    undoWindows.push({ steps: [] });

    try {
        let returnValue: T = action();

        let undoWindow: UndoWindow = undoWindows[undoWindows.length - 1];
        let undoPreviouslyExecuted = false;

        // Reverse the steps, as changes made later in the action may depend on changes earlier in the action
        undoWindow.steps.reverse();

        let undo: UndoResult<T> = satcheljsAction(`undo-${actionName}`)(() => {
            if (undoPreviouslyExecuted) {
                throw `This instance of undo-${actionName} has already been executed`;
            }
            if (undoVerifiesChanges) {
                undoWindow.steps.forEach(step => {
                    if (!step.verify()) {
                        throw `Property "${step.propertyName} on store object "${step.objectName} changed since action was performed.`;
                    }
                });
            }
            undoWindow.steps.forEach(step => step.undo());
            undoPreviouslyExecuted = true;
        });

        undo.actionReturnValue = returnValue;

        return undo;
    } finally {
        undoWindows.pop();
        disposeSpy();
    }
}