@obsidize/rx-map
Version:
ES6 Map with rxjs extensions for change detection
155 lines (154 loc) • 4.42 kB
JavaScript
import { isUndefined, isFunction, identity, mergeObjects, castArray } from '../common/utility';
/**
* Heavily influenced by @ngrx/entity's entity adapter interface.
* The methods defined here are intended to follow the same paradigm as the ngrx adapter collection methods:
* https://ngrx.io/guide/entity/adapter#adapter-collection-methods
*/
export class EntityMap {
constructor(store, selectKey) {
this.store = store;
this.selectKey = selectKey;
}
onSetEntry(key, value) {
this.store.set(key, value);
}
onDeleteEntry(key) {
return this.store.delete(key);
}
onMergeEntries(a, b) {
return mergeObjects(a, b);
}
get count() {
return this.store.size;
}
keyOf(entity) {
return entity ? this.selectKey(entity) : undefined;
}
isValidKey(key) {
return !isUndefined(key);
}
iterableKeys() {
return this.store.keys();
}
keys() {
return Array.from(this.iterableKeys());
}
iterableValues() {
return this.store.values();
}
values() {
return Array.from(this.iterableValues());
}
iterableEntries() {
return this.store.entries();
}
entries() {
return Array.from(this.iterableEntries());
}
getOne(key) {
return this.store.get(key);
}
getMany(keys) {
return castArray(keys).map(key => this.getOne(key));
}
getManyExisting(keys) {
return this.getMany(keys).filter(identity);
}
hasOne(key) {
return this.store.has(key);
}
hasEvery(keys) {
return castArray(keys).every(key => this.hasOne(key));
}
hasSome(keys) {
return castArray(keys).some(key => this.hasOne(key));
}
addOne(entity) {
return this.upsertOne(entity);
}
addMany(entities) {
return castArray(entities).map(e => this.addOne(e));
}
setOne(entity) {
const key = this.keyOf(entity);
if (this.isValidKey(key)) {
this.onSetEntry(key, entity);
}
return entity;
}
setMany(entities) {
return castArray(entities).map(e => this.setOne(e));
}
setAll(entities) {
this.removeAll();
return this.setMany(entities);
}
removeOne(key) {
return this.onDeleteEntry(key);
}
removeMany(keys) {
return castArray(keys).map(k => this.removeOne(k));
}
removeWhere(predicate) {
let result = [];
if (!isFunction(predicate)) {
return result;
}
this.store.forEach((entity, key) => {
if (!predicate(entity))
return;
this.removeOne(key);
result.push(entity);
});
return result;
}
removeAll() {
this.store.clear();
}
updateOneByKey(key, changes) {
const combinedValue = this.onMergeEntries(this.store.get(key), changes);
this.onSetEntry(key, combinedValue);
return combinedValue;
}
updateOne(update) {
if (!update) {
return undefined;
}
const { key, changes } = update;
return this.updateOneByKey(key, changes);
}
updateMany(updates) {
return castArray(updates).map(u => this.updateOne(u));
}
upsertOne(entity) {
const key = this.keyOf(entity);
if (!this.isValidKey(key)) {
return entity;
}
const entityUpdate = { key, changes: entity };
return this.updateOne(entityUpdate);
}
upsertMany(entities) {
return castArray(entities).map(e => this.upsertOne(e));
}
transformOne(key, transform) {
const entity = this.getOne(key);
if (!entity || !isFunction(transform)) {
return entity;
}
const changes = transform(entity);
return this.updateOne({ key: key, changes });
}
transformMany(transform) {
const result = [];
if (!isFunction(transform)) {
return result;
}
this.store.forEach((entity, key) => {
const changes = transform(entity);
const v = this.updateOne({ key, changes });
result.push(v);
});
return result;
}
}