UNPKG

rxdeep

Version:
68 lines 2.51 kB
import { Observable, Subject } from 'rxjs'; import { filter, map, tap, multicast, refCount } from 'rxjs/operators'; import { isLeaf } from './types/changes'; import { postTrace } from './util/post-trace'; export class State extends Observable { constructor(initial, downstream = new Subject(), upstream) { super((observer) => { observer.next(this.value); return this.downstream.pipe(map(change => change.value)).subscribe(observer); }); this._value = initial; this._changesub = new Subject(); this.downstream = downstream.pipe(postTrace(), tap(change => { if (change.value !== this._value) { this._value = change.value; } }), multicast(() => this._changesub), refCount()); this.upstream = upstream || downstream; } next(t) { this.upstream.next({ value: t, trace: { from: this.value, to: t } }); } error(err) { this.upstream.error(err); } complete() { this.upstream.complete(); this._changesub.complete(); } get value() { return this._value; } set value(t) { this.next(t); } sub(key) { const _sub = new State(this.value ? this.value[key] : undefined, this.subDownstream(key, () => _sub.value), this.subUpstream(key)); return _sub; } subDownstream(key, current) { return this.downstream.pipe(map(change => ({ value: change.value ? change.value[key] : undefined, trace: change.trace, })), filter(change => { if (isLeaf(change.trace)) { return current() !== change.value; } else { return key in change.trace.subs; } }), map(change => ({ value: change.value, trace: isLeaf(change.trace) ? undefined : change.trace.subs[key] }))); } subUpstream(key) { return { next: change => { if (this.value) { this.value[key] = change.value; } this.upstream.next({ value: this.value, trace: { subs: { [key]: change.trace } } }); }, error: err => this.upstream.error(err), complete: () => { }, }; } } export function state(initial) { return new State(initial); } //# sourceMappingURL=state.js.map