import { Observable } from '../Observable'; import { Mapper, MultiMapper, Observables, OnNext, Observable as IObservable, Args, OnMultiNext, } from '../types'; export class MediatorObservable extends Observable { mapSource(source: Observable, mapNext: Mapper) { this.addSource(source, (next) => { this.value = mapNext(next, this.value as Result) as Result; }); return this; } addSource(source: IObservable, onNext: OnNext) { source.subscribe(onNext); if (source.value !== undefined) { onNext(source.value); } return this; } addSources( sources: Observables, onNext: OnMultiNext, ) { const values = new Array(sources.length) as Args; const initializedIndices = new Set(); sources.forEach((source, index) => { if (source == null) throw new Error(`addSources: source at index ${index} is null or undefined`); this.addSource(source as IObservable, (next) => { if (initializedIndices.has(index) && values[index] === next) return; values[index] = next; initializedIndices.add(index); if (initializedIndices.size === sources.length) { onNext(values); } }); }); return this; } mapSources( sources: Observables, mapNext: MultiMapper, ) { const values = new Array(sources.length) as Args; const initializedIndices = new Set(); sources.forEach((source, index) => { if (source == null) throw new Error(`mapSources: source at index ${index} is null or undefined`); this.addSource(source as IObservable, (next) => { if (initializedIndices.has(index) && values[index] === next) return; values[index] = next; initializedIndices.add(index); if (initializedIndices.size === sources.length) { this.value = mapNext(values, this.value) as T; } }); }); return this; } }