Code coverage report for src/Subscriber.ts

Statements: 100% (94 / 94)      Branches: 90.91% (30 / 33)      Functions: 100% (18 / 18)      Lines: 100% (90 / 90)      Ignored: none     

All files » src/ » Subscriber.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 1601   1 1 1   1   1     28     10625     1     10625   10625   5193 5193   3029 282 282   2747 2746 2562   184   2746     2404 2404       1 36086 36078       1 1260 1247 1247       1 4385 4333 4333       1 12741 3555   9186 9186     1 6568     1 875 874     1 1669 1667     1 1   1   1       2588       2588   2588 2588   2588 2337 251 204 204 204 204     2588 2588 2588 2588     1 5886 5858       1 7718 7718   11 11       1 638 638 638   637       1 1298 1298 1222   1296       1 1944 1944 1944 1944   1
import {isFunction} from './util/isFunction';
import {Observer} from './Observer';
import {Subscription} from './Subscription';
import {rxSubscriber} from './symbol/rxSubscriber';
import {empty as emptyObserver} from './Observer';
 
export class Subscriber<T> extends Subscription implements Observer<T> {
 
  static create<T>(next?: (x?: T) => void,
                   error?: (e?: any) => void,
                   complete?: () => void): Subscriber<T> {
    return new Subscriber(next, error, complete);
  }
 
  protected isStopped: boolean = false;
  protected destination: Observer<any>;
 
  constructor(destinationOrNext?: Observer<any> | ((value: T) => void),
              error?: (e?: any) => void,
              complete?: () => void) {
    super();
 
    switch (arguments.length) {
      case 0:
        this.destination = emptyObserver;
        break;
      case 1:
        if (!destinationOrNext) {
          this.destination = emptyObserver;
          break;
        }
        if (typeof destinationOrNext === 'object') {
          if (destinationOrNext instanceof Subscriber) {
            this.destination = (<Observer<any>> destinationOrNext);
          } else {
            this.destination = new SafeSubscriber<T>(this, <Observer<any>> destinationOrNext);
          }
          break;
        }
      default:
        this.destination = new SafeSubscriber<T>(this, <((value: T) => void)> destinationOrNext, error, complete);
        break;
    }
  }
 
  next(value?: T): void {
    if (!this.isStopped) {
      this._next(value);
    }
  }
 
  error(err?: any): void {
    if (!this.isStopped) {
      this.isStopped = true;
      this._error(err);
    }
  }
 
  complete(): void {
    if (!this.isStopped) {
      this.isStopped = true;
      this._complete();
    }
  }
 
  unsubscribe(): void {
    if (this.isUnsubscribed) {
      return;
    }
    this.isStopped = true;
    super.unsubscribe();
  }
 
  protected _next(value: T): void {
    this.destination.next(value);
  }
 
  protected _error(err: any): void {
    this.destination.error(err);
    this.unsubscribe();
  }
 
  protected _complete(): void {
    this.destination.complete();
    this.unsubscribe();
  }
 
  [rxSubscriber]() {
    return this;
  }
}
 
class SafeSubscriber<T> extends Subscriber<T> {
 
  private _context: any;
 
  constructor(private _parent: Subscriber<T>,
              observerOrNext?: Observer<T> | ((value: T) => void),
              error?: (e?: any) => void,
              complete?: () => void) {
    super();
 
    let next: ((value: T) => void);
    let context: any = this;
 
    if (isFunction(observerOrNext)) {
      next = (<((value: T) => void)> observerOrNext);
    } else if (observerOrNext) {
      context = observerOrNext;
      next = (<Observer<T>> observerOrNext).next;
      error = (<Observer<T>> observerOrNext).error;
      complete = (<Observer<T>> observerOrNext).complete;
    }
 
    this._context = context;
    this._next = next;
    this._error = error;
    this._complete = complete;
  }
 
  next(value?: T): void {
    if (!this.isStopped && this._next) {
      this.__tryOrUnsub(this._next, value);
    }
  }
 
  __tryOrUnsub(fn: Function, value?: any): void {
    try {
      fn.call(this._context, value);
    } catch (err) {
      this.unsubscribe();
      throw err;
    }
  }
 
  error(err?: any): void {
    Eif (!this.isStopped) {
      Eif (this._error) {
        this.__tryOrUnsub(this._error, err);
      }
      this.unsubscribe();
    }
  }
 
  complete(): void {
    Eif (!this.isStopped) {
      if (this._complete) {
        this.__tryOrUnsub(this._complete);
      }
      this.unsubscribe();
    }
  }
 
  protected _unsubscribe(): void {
    const { _parent } = this;
    this._context = null;
    this._parent = null;
    _parent.unsubscribe();
  }
}