-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(multicast): add higher-order lettable variant of multicast
Also adds MonoTypeOperatorFunction
- Loading branch information
Showing
4 changed files
with
78 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { Subject } from '../Subject'; | ||
import { Operator } from '../Operator'; | ||
import { Subscriber } from '../Subscriber'; | ||
import { Observable } from '../Observable'; | ||
import { ConnectableObservable, connectableObservableDescriptor } from '../observable/ConnectableObservable'; | ||
import { FactoryOrValue, MonoTypeOperatorFunction } from '../interfaces'; | ||
|
||
/* tslint:disable:max-line-length */ | ||
export function multicast<T>(subjectOrSubjectFactory: FactoryOrValue<Subject<T>>): MonoTypeOperatorFunction<T>; | ||
export function multicast<T>(SubjectFactory: (this: Observable<T>) => Subject<T>, selector?: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T>; | ||
/* tslint:enable:max-line-length */ | ||
|
||
/** | ||
* Returns an Observable that emits the results of invoking a specified selector on items | ||
* emitted by a ConnectableObservable that shares a single subscription to the underlying stream. | ||
* | ||
* <img src="./img/multicast.png" width="100%"> | ||
* | ||
* @param {Function|Subject} subjectOrSubjectFactory - Factory function to create an intermediate subject through | ||
* which the source sequence's elements will be multicast to the selector function | ||
* or Subject to push source elements into. | ||
* @param {Function} [selector] - Optional selector function that can use the multicasted source stream | ||
* as many times as needed, without causing multiple subscriptions to the source stream. | ||
* Subscribers to the given source will receive all notifications of the source from the | ||
* time of the subscription forward. | ||
* @return {Observable} An Observable that emits the results of invoking the selector | ||
* on the items emitted by a `ConnectableObservable` that shares a single subscription to | ||
* the underlying stream. | ||
* @method multicast | ||
* @owner Observable | ||
*/ | ||
export function multicast<T>(subjectOrSubjectFactory: Subject<T> | (() => Subject<T>), | ||
selector?: (source: Observable<T>) => Observable<T>): MonoTypeOperatorFunction<T> { | ||
return function multicastOperatorFunction(source: Observable<T>): Observable<T> { | ||
let subjectFactory: () => Subject<T>; | ||
if (typeof subjectOrSubjectFactory === 'function') { | ||
subjectFactory = <() => Subject<T>>subjectOrSubjectFactory; | ||
} else { | ||
subjectFactory = function subjectFactory() { | ||
return <Subject<T>>subjectOrSubjectFactory; | ||
}; | ||
} | ||
|
||
if (typeof selector === 'function') { | ||
return source.lift(new MulticastOperator(subjectFactory, selector)); | ||
} | ||
|
||
const connectable: any = Object.create(source, connectableObservableDescriptor); | ||
connectable.source = source; | ||
connectable.subjectFactory = subjectFactory; | ||
|
||
return <ConnectableObservable<T>> connectable; | ||
}; | ||
} | ||
|
||
export class MulticastOperator<T> implements Operator<T, T> { | ||
constructor(private subjectFactory: () => Subject<T>, | ||
private selector: (source: Observable<T>) => Observable<T>) { | ||
} | ||
call(subscriber: Subscriber<T>, source: any): any { | ||
const { selector } = this; | ||
const subject = this.subjectFactory(); | ||
const subscription = selector(subject).subscribe(subscriber); | ||
subscription.add(source.subscribe(subject)); | ||
return subscription; | ||
} | ||
} |