Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / rxjs / src / internal / operators / distinct.ts
1 import { Observable } from '../Observable';
2 import { Operator } from '../Operator';
3 import { Subscriber } from '../Subscriber';
4 import { OuterSubscriber } from '../OuterSubscriber';
5 import { InnerSubscriber } from '../InnerSubscriber';
6 import { subscribeToResult } from '../util/subscribeToResult';
7 import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
8
9 /**
10  * Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from previous items.
11  *
12  * If a keySelector function is provided, then it will project each value from the source observable into a new value that it will
13  * check for equality with previously projected values. If a keySelector function is not provided, it will use each value from the
14  * source observable directly with an equality check against previous values.
15  *
16  * In JavaScript runtimes that support `Set`, this operator will use a `Set` to improve performance of the distinct value checking.
17  *
18  * In other runtimes, this operator will use a minimal implementation of `Set` that relies on an `Array` and `indexOf` under the
19  * hood, so performance will degrade as more values are checked for distinction. Even in newer browsers, a long-running `distinct`
20  * use might result in memory leaks. To help alleviate this in some scenarios, an optional `flushes` parameter is also provided so
21  * that the internal `Set` can be "flushed", basically clearing it of values.
22  *
23  * ## Examples
24  * A simple example with numbers
25  * ```ts
26  * import { of } from 'rxjs';
27  * import { distinct } from 'rxjs/operators';
28  *
29  * of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1).pipe(
30  *     distinct(),
31  *   )
32  *   .subscribe(x => console.log(x)); // 1, 2, 3, 4
33  * ```
34  *
35  * An example using a keySelector function
36  * ```typescript
37  * import { of } from 'rxjs';
38  * import { distinct } from 'rxjs/operators';
39  *
40  * interface Person {
41  *    age: number,
42  *    name: string
43  * }
44  *
45  * of<Person>(
46  *     { age: 4, name: 'Foo'},
47  *     { age: 7, name: 'Bar'},
48  *     { age: 5, name: 'Foo'},
49  *   ).pipe(
50  *     distinct((p: Person) => p.name),
51  *   )
52  *   .subscribe(x => console.log(x));
53  *
54  * // displays:
55  * // { age: 4, name: 'Foo' }
56  * // { age: 7, name: 'Bar' }
57  * ```
58  * @see {@link distinctUntilChanged}
59  * @see {@link distinctUntilKeyChanged}
60  *
61  * @param {function} [keySelector] Optional function to select which value you want to check as distinct.
62  * @param {Observable} [flushes] Optional Observable for flushing the internal HashSet of the operator.
63  * @return {Observable} An Observable that emits items from the source Observable with distinct values.
64  * @method distinct
65  * @owner Observable
66  */
67 export function distinct<T, K>(keySelector?: (value: T) => K,
68                                flushes?: Observable<any>): MonoTypeOperatorFunction<T> {
69   return (source: Observable<T>) => source.lift(new DistinctOperator(keySelector, flushes));
70 }
71
72 class DistinctOperator<T, K> implements Operator<T, T> {
73   constructor(private keySelector: (value: T) => K, private flushes: Observable<any>) {
74   }
75
76   call(subscriber: Subscriber<T>, source: any): TeardownLogic {
77     return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes));
78   }
79 }
80
81 /**
82  * We need this JSDoc comment for affecting ESDoc.
83  * @ignore
84  * @extends {Ignored}
85  */
86 export class DistinctSubscriber<T, K> extends OuterSubscriber<T, T> {
87   private values = new Set<K>();
88
89   constructor(destination: Subscriber<T>, private keySelector: (value: T) => K, flushes: Observable<any>) {
90     super(destination);
91
92     if (flushes) {
93       this.add(subscribeToResult(this, flushes));
94     }
95   }
96
97   notifyNext(outerValue: T, innerValue: T,
98              outerIndex: number, innerIndex: number,
99              innerSub: InnerSubscriber<T, T>): void {
100     this.values.clear();
101   }
102
103   notifyError(error: any, innerSub: InnerSubscriber<T, T>): void {
104     this._error(error);
105   }
106
107   protected _next(value: T): void {
108     if (this.keySelector) {
109       this._useKeySelector(value);
110     } else {
111       this._finalizeNext(value, value);
112     }
113   }
114
115   private _useKeySelector(value: T): void {
116     let key: K;
117     const { destination } = this;
118     try {
119       key = this.keySelector(value);
120     } catch (err) {
121       destination.error(err);
122       return;
123     }
124     this._finalizeNext(key, value);
125   }
126
127   private _finalizeNext(key: K|T, value: T) {
128     const { values } = this;
129     if (!values.has(<K>key)) {
130       values.add(<K>key);
131       this.destination.next(value);
132     }
133   }
134
135 }