All files Apollo.ts

91.67% Statements 55/60
68.75% Branches 11/16
100% Functions 20/20
90.74% Lines 49/54
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 1193x 3x                 3x   3x   3x   3x 13x   3x 4x     3x     3x 3x       4x 4x 4x       3x 1x     3x 19x     3x 11x       11x     3x 12x   12x     3x 12x     3x 12x       3x     3x 12x           12x     3x 12x 1x   11x       3x 2x     3x 2x     2x     3x 11x       11x     3x 1x     1x         3x  
import {Injectable} from '@angular/core';
import {
  ApolloClient,
  WatchQueryOptions,
  MutationOptions,
  ApolloQueryResult,
  SubscriptionOptions,
} from 'apollo-client';
import {FetchResult} from 'apollo-link';
import {Observable} from 'rxjs/Observable';
import {from} from 'rxjs/observable/from';
 
import {QueryRef} from './QueryRef';
import {ApolloOptions} from './types';
import {fromPromise, wrapWithZone} from './utils';
 
export class ApolloBase<TCacheShape> {
  constructor(private _client?: ApolloClient<TCacheShape>) {}
 
  public watchQuery<T>(options: WatchQueryOptions): QueryRef<T> {
    return new QueryRef<T>(this.client.watchQuery<T>({...options}));
  }
 
  public query<T>(
    options: WatchQueryOptions,
  ): Observable<ApolloQueryResult<T>> {
    return fromPromise<ApolloQueryResult<T>>(() =>
      this.client.query<T>({...options}),
    );
  }
 
  public mutate<T>(options: MutationOptions): Observable<FetchResult<T>> {
    return fromPromise<FetchResult<T>>(() =>
      this.client.mutate<T>({...options}),
    );
  }
 
  public subscribe(options: SubscriptionOptions): Observable<any> {
    return wrapWithZone(from(this.client.subscribe({...options})));
  }
 
  public getClient() {
    return this._client;
  }
 
  public setClient(client: ApolloClient<TCacheShape>) {
    Iif (this._client) {
      throw new Error('Client has been already defined');
    }
 
    this._client = client;
  }
 
  private get client(): ApolloClient<TCacheShape> {
    this.beforeEach();
 
    return this._client;
  }
 
  private beforeEach(): void {
    this.checkInstance();
  }
 
  private checkInstance(): void {
    Iif (!this._client) {
      throw new Error('Client has not been defined yet');
    }
  }
}
 
@Injectable()
export class Apollo extends ApolloBase<any> {
  private map: Map<string, ApolloBase<any>> = new Map<
    string,
    ApolloBase<any>
  >();
 
  constructor() {
    super();
  }
 
  public create<TCacheShape>(options: ApolloOptions, name?: string): void {
    if (name && name !== 'default') {
      this.createNamed<TCacheShape>(name, options);
    } else {
      this.createDefault<TCacheShape>(options);
    }
  }
 
  public default(): ApolloBase<any> {
    return this;
  }
 
  public use(name: string): ApolloBase<any> {
    Iif (name === 'default') {
      return this.default();
    }
    return this.map.get(name);
  }
 
  public createDefault<TCacheShape>(options: ApolloOptions): void {
    Iif (this.getClient()) {
      throw new Error('Apollo has been already created.');
    }
 
    return this.setClient(new ApolloClient<TCacheShape>(options as any));
  }
 
  public createNamed<TCacheShape>(name: string, options: ApolloOptions): void {
    Iif (this.map.has(name)) {
      throw new Error(`Client ${name} has been already created`);
    }
    this.map.set(
      name,
      new ApolloBase(new ApolloClient<TCacheShape>(options as any)),
    );
  }
}