1 import { Observable } from '../Observable';
2 import { ReplaySubject } from '../ReplaySubject';
3 import { Subscription } from '../Subscription';
4 import { MonoTypeOperatorFunction, SchedulerLike } from '../types';
5 import { Subscriber } from '../Subscriber';
7 export interface ShareReplayConfig {
11 scheduler?: SchedulerLike;
15 * Share source and replay specified number of emissions on subscription.
17 * This operator is a specialization of `replay` that connects to a source observable
18 * and multicasts through a `ReplaySubject` constructed with the specified arguments.
19 * A successfully completed source will stay cached in the `shareReplayed observable` forever,
20 * but an errored source can be retried.
22 * ## Why use shareReplay?
23 * You generally want to use `shareReplay` when you have side-effects or taxing computations
24 * that you do not wish to be executed amongst multiple subscribers.
25 * It may also be valuable in situations where you know you will have late subscribers to
26 * a stream that need access to previously emitted values.
27 * This ability to replay values on subscription is what differentiates {@link share} and `shareReplay`.
29 * ![](shareReplay.png)
33 * import { interval } from 'rxjs';
34 * import { shareReplay, take } from 'rxjs/operators';
36 * const obs$ = interval(1000);
37 * const shared$ = obs$.pipe(
41 * shared$.subscribe(x => console.log('source A: ', x));
42 * shared$.subscribe(y => console.log('source B: ', y));
46 * @see {@link publish}
48 * @see {@link publishReplay}
50 * @param {Number} [bufferSize=Number.POSITIVE_INFINITY] Maximum element count of the replay buffer.
51 * @param {Number} [windowTime=Number.POSITIVE_INFINITY] Maximum time length of the replay buffer in milliseconds.
52 * @param {Scheduler} [scheduler] Scheduler where connected observers within the selector function
54 * @return {Observable} An observable sequence that contains the elements of a sequence produced
55 * by multicasting the source sequence within a selector function.
59 export function shareReplay<T>(config: ShareReplayConfig): MonoTypeOperatorFunction<T>;
60 export function shareReplay<T>(bufferSize?: number, windowTime?: number, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
61 export function shareReplay<T>(
62 configOrBufferSize?: ShareReplayConfig | number,
64 scheduler?: SchedulerLike
65 ): MonoTypeOperatorFunction<T> {
66 let config: ShareReplayConfig;
67 if (configOrBufferSize && typeof configOrBufferSize === 'object') {
68 config = configOrBufferSize as ShareReplayConfig;
71 bufferSize: configOrBufferSize as number | undefined,
77 return (source: Observable<T>) => source.lift(shareReplayOperator(config));
80 function shareReplayOperator<T>({
81 bufferSize = Number.POSITIVE_INFINITY,
82 windowTime = Number.POSITIVE_INFINITY,
83 refCount: useRefCount,
85 }: ShareReplayConfig) {
86 let subject: ReplaySubject<T> | undefined;
88 let subscription: Subscription | undefined;
90 let isComplete = false;
92 return function shareReplayOperation(this: Subscriber<T>, source: Observable<T>) {
94 let innerSub: Subscription;
95 if (!subject || hasError) {
97 subject = new ReplaySubject<T>(bufferSize, windowTime, scheduler);
98 innerSub = subject.subscribe(this);
99 subscription = source.subscribe({
100 next(value) { subject.next(value); },
107 subscription = undefined;
112 innerSub = subject.subscribe(this);
117 innerSub.unsubscribe();
118 if (subscription && !isComplete && useRefCount && refCount === 0) {
119 subscription.unsubscribe();
120 subscription = undefined;