import { Injectable , Optional , Inject , NgZone } from '@angular/core' ; import type { QueryOptions , ApolloQueryResult , SubscriptionOptions , ApolloClientOptions , ObservableQuery , FetchResult , } from '@apollo/client/core' ; import { ApolloClient } from '@apollo/client/core' ; import { Observable , from } from 'rxjs' ; import { QueryRef } from './query-ref' ; import { WatchQueryOptions , ExtraSubscriptionOptions , EmptyObject , NamedOptions , Flags , MutationResult , MutationOptions , } from './types' ; import { APOLLO_OPTIONS , APOLLO_NAMED_OPTIONS , APOLLO_FLAGS } from './tokens' ; import { fromPromise , useMutationLoading , wrapWithZone , fixObservable , pickFlag , } from './utils' ; export class ApolloBase < TCacheShape = any > { private useInitialLoading : boolean ; private useMutationLoading : boolean ; constructor ( protected ngZone , protected flags ? , protected _client ? ) { this . useInitialLoading = pickFlag ( flags , 'useInitialLoading' , false ) ; this . useMutationLoading = pickFlag ( flags , 'useMutationLoading' , false ) ; } public watchQuery < TData , TVariables = EmptyObject > ( options ) { return new QueryRef < TData , TVariables > ( this . ensureClient ( ) . watchQuery < TData , TVariables > ( { ... options , } ) as ObservableQuery < TData , TVariables > , this . ngZone , { useInitialLoading : this . useInitialLoading , ... options , } ) ; } public query < T , V = EmptyObject > ( options ) { return fromPromise < ApolloQueryResult < T > > ( ( ) => this . ensureClient ( ) . query < T , V > ( { ... options } ) ) ; } public mutate < T , V = EmptyObject > ( options ) { return useMutationLoading ( fromPromise ( ( ) => this . ensureClient ( ) . mutate < T , V > ( { ... options } ) ) , options . useMutationLoading ?? this . useMutationLoading ) ; } public subscribe < T , V = EmptyObject > ( options , extra ? ) { const obs = from ( fixObservable ( this . ensureClient ( ) . subscribe < T , V > ( { ... options } ) ) ) ; return extra && extra . useZone !== true ? obs : wrapWithZone ( obs , this . ngZone ) ; } deprecated public getClient ( ) { return this . client ; } deprecated param client public setClient ( client ) { this . client = client ; } /**
     * Get an access to an instance of ApolloClient
     */ public get client ( ) : ApolloClient < TCacheShape > { return this . _client ; } param client public set client ( client ) { if ( this . _client ) { throw new Error ( 'Client has been already defined' ) ; } this . _client = client ; } private ensureClient ( ) { this . checkInstance ( ) ; return this . _client ; } private checkInstance ( ) { if ( ! 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 ( private _ngZone , @ Optional ( ) @ Inject ( APOLLO_OPTIONS ) apolloOptions ? , @ Optional ( ) @ Inject ( APOLLO_NAMED_OPTIONS ) apolloNamedOptions ? , @ Optional ( ) @ Inject ( APOLLO_FLAGS ) flags ? ) { super ( _ngZone , flags ) ; if ( apolloOptions ) { this . createDefault ( apolloOptions ) ; } if ( apolloNamedOptions && typeof apolloNamedOptions === 'object' ) { for ( let name in apolloNamedOptions ) { if ( apolloNamedOptions . hasOwnProperty ( name ) ) { const options = apolloNamedOptions [ name ] ; this . createNamed ( name , options ) ; } } } } param options param name public create < TCacheShape > ( options , name ? ) { if ( isDefault ( name ) ) { this . createDefault < TCacheShape > ( options ) ; } else { this . createNamed < TCacheShape > ( name , options ) ; } } /**
     * Use a default ApolloClient
     */ public default ( ) { return this ; } param name public use ( name ) { if ( isDefault ( name ) ) { return this . default ( ) ; } return this . map . get ( name ) ; } param options public createDefault < TCacheShape > ( options ) { if ( this . getClient ( ) ) { throw new Error ( 'Apollo has been already created.' ) ; } return this . setClient ( new ApolloClient < TCacheShape > ( options ) ) ; } param name param options public createNamed < TCacheShape > ( name , options ) { if ( this . map . has ( name ) ) { throw new Error ( `Client ${ name } has been already created` ) ; } this . map . set ( name , new ApolloBase ( this . _ngZone , this . flags , new ApolloClient < TCacheShape > ( options ) ) ) ; } param name public removeClient ( name ? ) { if ( isDefault ( name ) ) { this . _client = undefined ; } else { this . map . delete ( name ) ; } } } function isDefault ( name ? ) { return ! name || name === 'default' ; }