@igo2/common
Version:
172 lines (171 loc) • 6.45 kB
TypeScript
import { Observable } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { EntityOperationType } from './entity.enums';
import { EntityKey, EntityOperationState, EntityTransactionOptions } from './entity.interfaces';
import { EntityStore } from './store';
export interface EntityOperation<E extends object = object> {
key: EntityKey;
type: EntityOperationType;
previous: E | undefined;
current: E | undefined;
store?: EntityStore<E>;
meta?: Record<string, any>;
}
export type EntityTransactionCommitHandler = (transaction: EntityTransaction, operations: EntityOperation[]) => Observable<any>;
/**
* This class holds a reference to the insert, update and delete
* operations performed on a store. This is useful to commit
* these operations in a single pass or to cancel them.
*/
export declare class EntityTransaction {
/**
* Store holding the operations on another store
*/
readonly operations: EntityStore<EntityOperation, EntityOperationState>;
/**
* Method to get an entity's id
*/
readonly getKey: (E: any) => EntityKey;
/**
* Whether there are pending operations
*/
get empty$(): BehaviorSubject<boolean>;
/**
* Whether there are pending operations
*/
get empty(): boolean;
/**
* Whether thise store is in commit phase
*/
get inCommitPhase(): boolean;
readonly inCommitPhase$: BehaviorSubject<boolean>;
constructor(options?: EntityTransactionOptions);
destroy(): void;
/**
* Insert an entity into a store. If no store is specified, an insert
* operation is still created but the transaction won't add the new
* entity to the store.
* @param current The entity to insert
* @param store Optional: The store to insert the entity into
* @param meta Optional: Any metadata on the operation
*/
insert(current: object, store?: EntityStore<object>, meta?: Record<string, any>): void;
/**
* Update an entity in a store. If no store is specified, an update
* operation is still created but the transaction won't update the
* entity into the store.
* @param previous The entity before update
* @param current The entity after update
* @param store Optional: The store to update the entity into
* @param meta Optional: Any metadata on the operation
*/
update(previous: object, current: object, store?: EntityStore<object>, meta?: Record<string, any>): void;
/**
* Delete an entity from a store. If no store is specified, a delete
* operation is still created but the transaction won't remove the
* entity from the store.
* @param previous The entity before delete
* @param store Optional: The store to delete the entity from
* @param meta Optional: Any metadata on the operation
*/
delete(previous: object, store?: EntityStore<object>, meta?: Record<string, any>): void;
/**
* Commit operations the transaction. This method doesn't do much
* in itself. The handler it receives does the hard work and it's
* implementation is left to the caller. This method simply wraps
* the handler into an error catching mechanism to update
* the transaction afterward. The caller needs to subscribe to this
* method's output (observable) for the commit to be performed.
* @param operations Operations to commit
* @param handler Function that handles the commit operation
* @returns The handler output (observable)
*/
commit(operations: EntityOperation[], handler: EntityTransactionCommitHandler): Observable<any>;
/**
* Commit all the operations of the transaction.
* @param handler Function that handles the commit operation
* @returns The handler output (observable)
*/
commitAll(handler: EntityTransactionCommitHandler): Observable<any>;
/**
* Rollback this transaction
*/
rollback(): void;
/**
* Rollback specific operations
*/
rollbackOperations(operations: EntityOperation[]): void;
/**
* Clear this transaction
* @todo Raise event and synchronize stores?
*/
clear(): void;
/**
* Get any existing operation on an entity
* @param entity Entity
* @returns Either an insert, update or delete operation
*/
getOperationByEntity(entity: object): EntityOperation;
/**
* Merge another transaction in this one
* @param transaction Another transaction
*/
mergeTransaction(transaction: EntityTransaction): void;
/**
* Create an insert operation and add an entity to the store
* @param current The entity to insert
* @param store Optional: The store to insert the entity into
* @param meta Optional: Any metadata on the operation
*/
private doInsert;
/**
* Create an update operation and update an entity into the store
* @param previous The entity before update
* @param current The entity after update
* @param store Optional: The store to update the entity into
* @param meta Optional: Any metadata on the operation
*/
private doUpdate;
/**
* Create a delete operation and delete an entity from the store
* @param previous The entity before delete
* @param store Optional: The store to delete the entity from
* @param meta Optional: Any metadata on the operation
*/
private doDelete;
/**
* Remove committed operations from store
* @param operations Commited operations
* @todo Raise event and synchronize stores?
*/
private resolveOperations;
/**
* On commit success, resolve commited operations and exit commit phase
* @param operations Commited operations
*/
private onCommitSuccess;
/**
* On commit error, abort transaction
* @param operations Commited operations
*/
private onCommitError;
/**
* Add an operation to the operations store
* @param operation Operation to add
*/
private addOperation;
/**
* Remove an operation from the operations store
* @param operation Operation to remove
*/
private removeOperation;
/**
* Get all the operations to commit
* @returns Operations to commit
*/
private getOperationsInCommit;
/**
* Check if the transaction is in the commit phase and throw an error if it is
*/
private checkInCommitPhase;
}