UNPKG

@obsidize/rx-map

Version:

ES6 Map with rxjs extensions for change detection

73 lines (72 loc) 2.81 kB
import { filter, map, scan } from 'rxjs/operators'; import { detectAccumulatedChanges, identity } from './utility'; import { isActionableChangeDetectionResultType } from '../events/change-detection-event'; /** * Variant of filter() that uses a Set to increase lookup speed when checking emissions for a single property value. * NOTE: this variant is top-heavy, and more expensive on smaller value lists; only use this when * the 'values' collection can become large. */ export function spreadFilterBy(values, extractValue) { const lookup = new Set(values); return source => source.pipe(filter(v => lookup.has(extractValue(v)))); } /** * filter by map change event types (useful if you only want to watch ADD or UPDATE changes) */ export function ofType(...types) { return source => source.pipe(spreadFilterBy(types, ev => ev.type)); } /** * filter by entity primary key */ export function forKey(key) { return source => source.pipe(filter(ev => ev.key === key)); } /** * filter by a set of entity primary keys */ export function forKeyIn(keys) { return source => source.pipe(spreadFilterBy(keys, ev => ev.key)); } /** * Narrows the scope of raw map change events into property-specific events. */ export function pluckValueChanges(selectValue) { const selectSafe = (v) => v ? selectValue(v) : undefined; return source => source.pipe(filter(ev => !!ev), map(ev => ({ entityId: ev.key, currentValue: selectSafe(ev.value), previousValue: selectSafe(ev.previousValue), }))); } /** * map change events to their corresponding entity value */ export function pluckValue() { return source => source.pipe(map(ev => ev.value), filter(identity)); } /** * map change events to their corresponding entity update differences (will be a partial entity object) */ export function pluckChanges() { return source => source.pipe(map(ev => ev.changes), filter(identity)); } /** * capture emitted values and store them in the provided map reference by side-effect */ export function storeEntityIn(entityMap) { return source => source.pipe(map(v => entityMap.setOne(v))); } /** * capture emitted values and store them in the provided map reference by side-effect */ export function storeEntityArrayIn(entityMap) { return source => source.pipe(map(v => entityMap.setMany(v))); } /** * Emits change detection diffs between each emission and the one previous of it. * NOTE: if the detection result type is NO_CHANGE, then the emission will be dropped. */ export function accumulateChanges() { return source => source.pipe(scan((acc, current) => detectAccumulatedChanges(acc, current)), filter((next) => !!next && isActionableChangeDetectionResultType(next.type))); }