Skip to content

Commit

Permalink
feat(store): add an empty$ and count$ observables
Browse files Browse the repository at this point in the history
  • Loading branch information
cbourget committed Jun 13, 2019
1 parent 4d98eb7 commit f0de496
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 16 deletions.
35 changes: 25 additions & 10 deletions packages/common/src/lib/entity/shared/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ export class EntityStore<E extends object, S extends EntityState = EntityState>
*/
readonly entities$ = new BehaviorSubject<E[]>([]);

/**
* Number of entities
*/
readonly count$ = new BehaviorSubject<number>(0);
get count(): number { return this.count$.value; }

/**
* Whether the store is empty
*/
readonly empty$ = new BehaviorSubject<boolean>(true);
get empty(): boolean { return this.empty$.value; }

/**
* Entity store state
*/
Expand Down Expand Up @@ -54,16 +66,6 @@ export class EntityStore<E extends object, S extends EntityState = EntityState>
get pristine(): boolean { return this._pristine; }
private _pristine: boolean = true;

/**
* Number of entities
*/
get count(): number { return this.entities$.value.length; }

/**
* Whether there are entities in the store
*/
get empty(): boolean { return this.count === 0; }

constructor(entities: E[], options: EntityStoreOptions = {}) {
this.getKey = options.getKey ? options.getKey : getEntityId;
this.getProperty = options.getProperty ? options.getProperty : getEntityProperty;
Expand Down Expand Up @@ -124,6 +126,8 @@ export class EntityStore<E extends object, S extends EntityState = EntityState>
this.index.clear();
this._pristine = true;
this.next();
} else if (this.index) {
this.updateCount();
}
}

Expand Down Expand Up @@ -212,6 +216,17 @@ export class EntityStore<E extends object, S extends EntityState = EntityState>
*/
private next() {
this.entities$.next(Array.from(this.index.values()));
this.updateCount();
}

/**
* Update the store's count and empty
*/
private updateCount() {
const count = this.index.size;
const empty = count === 0;
this.count$.next(count);
this.empty$.next(empty);
}

}
33 changes: 27 additions & 6 deletions packages/common/src/lib/entity/shared/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ export class EntityTransaction {
* Rollback this transaction
*/
rollback() {
this.rollbackOperations(this.operations.all());
}

/**
* Rollback specific operations
*/
rollbackOperations(operations: EntityOperation[]) {
this.checkInCommitPhase();

const operationsFactory = () => new Map([
Expand All @@ -170,7 +177,7 @@ export class EntityTransaction {
// Group operations by store and by operation type.
// Grouping operations allows us to revert them in bacth, thus, triggering
// observables only one per operation type.
for (const operation of this.operations.all()) {
for (const operation of operations) {
const store = operation.store;
if (operation.store === undefined) { continue; }

Expand All @@ -183,19 +190,20 @@ export class EntityTransaction {
}

Array.from(storesOperations.keys()).forEach((store: EntityStore<object>) => {
const operations = storesOperations.get(store);
const storeOperations = storesOperations.get(store);

const deletes = operations.get(EntityOperationType.Delete);
const deletes = storeOperations.get(EntityOperationType.Delete);
store.insertMany(deletes.map((_delete: EntityOperation) => _delete.previous));

const updates = operations.get(EntityOperationType.Update);
const updates = storeOperations.get(EntityOperationType.Update);
store.updateMany(updates.map((_update: EntityOperation) => _update.previous));

const inserts = operations.get(EntityOperationType.Insert);
const inserts = storeOperations.get(EntityOperationType.Insert);
store.deleteMany(inserts.map((_insert: EntityOperation) => _insert.current));
});

this.clear();
this.operations.deleteMany(operations);
this._inCommitPhase = false;
}

/**
Expand All @@ -207,6 +215,19 @@ export class EntityTransaction {
this._inCommitPhase = false;
}

/**
* Merge another transaction in this one
* @param transaction Another transaction
*/
mergeTransaction(transaction: EntityTransaction) {
this.checkInCommitPhase();

const operations = transaction.operations.all();
operations.forEach((operation: EntityOperation) => {
this.addOperation(operation);
});
}

/**
* Create an insert operation and add an entity to the store
* @param current The entity to insert
Expand Down

0 comments on commit f0de496

Please sign in to comment.