@odoo/o-spreadsheet
Version:
A spreadsheet component
177 lines (176 loc) • 5.99 kB
TypeScript
import { OperationSequenceNode, TransformationFactory } from "../types/history";
import { UID } from "../types/misc";
import { Branch } from "./branch";
import { Operation } from "./operation";
import { OperationSequence } from "./operation_sequence";
/**
* The tree is a data structure used to maintain the different branches of the
* SelectiveHistory.
*
* Branches can be "stacked" on each other and an execution path can be derived
* from any stack of branches. The rules to derive this path is explained below.
*
* An operation can be cancelled/undone by inserting a new branch below
* this operation.
* e.g
* Given the branch A B C
* To undo B, a new branching branch is inserted at operation B.
* ```txt
* A B C D
* > C' D'
* ```
* A new execution path can now be derived. At each operation:
* - if there is a lower branch, don't execute it and go to the operation below
* - if not, execute it and go to the operation on the right.
* The execution path is A C' D'
* Operation C and D have been adapted (transformed) in the lower branch
* since operation B is not executed in this branch.
*
*/
export declare class Tree<T = unknown> {
private readonly buildTransformation;
private readonly branches;
private branchingOperationIds;
constructor(buildTransformation: TransformationFactory<T>, initialBranch: Branch<T>);
/**
* Return the last branch of the entire stack of branches.
*/
getLastBranch(): Branch<T>;
/**
* Return the sequence of operations from this branch
* until the very last branch.
*/
execution(branch: Branch<T>): OperationSequence<T>;
/**
* Return the sequence of operations from this branch
* to the very first branch.
*/
revertedExecution(branch: Branch<T>): OperationSequence<T>;
/**
* Append an operation to the end of the tree.
* Also insert the (transformed) operation in all previous branches.
*
* Adding operation `D` to the last branch
* ```txt
* A1 B1 C1
* > B2 C2
* ```
* will give
* ```txt
* A1 B1 C1 D' with D' = D transformed with A1
* > B2 C2 D
* ```
*/
insertOperationLast(branch: Branch<T>, operation: Operation<T>): void;
/**
* Insert a new operation after an other operation.
* The operation will be inserted in this branch, in next branches (transformed)
* and in previous branches (also transformed).
*
* Given
* ```txt
* 1: A1 B1 C1
* 2: > B2 C2
* 3: > C3
* ```
* Inserting D to branch 2 gives
* ```txt
* 1: A1 B1 C1 D1 D1 = D transformed with A1
* 2: > B2 C2 D with D = D
* 3: > C3 D2 D2 = D transformed without B2 (B2⁻¹)
* ```
*/
insertOperationAfter(branch: Branch<T>, operation: Operation<T>, predecessorOpId: UID): void;
/**
* Create a new branching branch at the given operation.
* This cancels the operation from the execution path.
*/
undo(branch: Branch<T>, operation: Operation<T>): void;
/**
* Remove the branch just after this one. This un-cancels (redo) the branching
* operation. Lower branches will be transformed accordingly.
*
* Given
* ```txt
* 1: A1 B1 C1
* 2: > B2 C2
* 3: > C3
* ```
* removing the next branch of 1 gives
*
* ```txt
* 1: A1 B1 C1
* 2: > C3' with C3' = C1 transformed without B1 (B1⁻¹)
* ```
*/
redo(branch: Branch<T>): void;
/**
* Drop the operation and all following operations in every
* branches
*/
drop(operationId: UID): void;
/**
* Find the operation in the execution path.
*/
findOperation(branch: Branch<T>, operationId: UID): OperationSequenceNode<T>;
/**
* Rebuild transformed operations of this branch based on the upper branch.
*
* Given the following structure:
* ```txt
* 1: A1 B1 C1
* 2: > B2 C2
* 3: > C3
* ```
* Rebasing branch "2" gives
* ```txt
* 1: A1 B1 C1
* 2: > B2' C2' With B2' = B1 transformed without A1 and C2' = C1 transformed without A1
* 3: > C3' C3' = C2' transformed without B2'
* ```
*/
private rebaseUp;
private removeBranchFromTree;
private insertBranchAfter;
/**
* Update the branching branch of this branch, either by (1) inserting the new
* operation in it or (2) by transforming it.
* (1) If the operation is positioned before the branching branch, the branching
* branch should be transformed with this operation.
* (2) If it's positioned after, the operation should be inserted in the
* branching branch.
*/
private updateNextWith;
private addToNextBranch;
private getTransformedOperation;
/**
* Check if this branch should execute the given operation.
* i.e. If the operation is not cancelled by a branching branch.
*/
private shouldExecute;
private transform;
/**
* Insert a new operation in previous branches. The operations which are
* positioned after the inserted operations are transformed with the newly
* inserted operations. This one is also transformed, with the branching
* operation.
*/
private insertPrevious;
private findPreviousBranchingOperation;
/**
* Retrieve the next branch of the given branch
*/
private nextBranch;
/**
* Retrieve the previous branch of the given branch
*/
private previousBranch;
/**
* Yields the sequence of operations to execute, in reverse order.
*/
private _revertedExecution;
/**
* Yields the sequence of operations to execute
*/
private _execution;
}