import { ApolloClient, TypedDocumentNode, OperationVariables, ObservableQuery, MaybeMasked } from '@apollo/client';
export { TypedDocumentNode } from '@apollo/client';
import * as i0 from '@angular/core';
import { Provider, NgZone, InjectionToken } from '@angular/core';
import { Observable, OperatorFunction } from 'rxjs';
import { DocumentNode } from 'graphql';
import { ObservableQuery as ObservableQuery$1, ApolloClient as ApolloClient$1, GetDataState } from '@apollo/client/core';

type EmptyObject = {
    [key: string]: any;
};
type ResultOf<T extends TypedDocumentNode> = T extends TypedDocumentNode<infer R> ? R : never;
type VariablesOf<T extends TypedDocumentNode> = T extends TypedDocumentNode<any, infer V> ? V : never;
type NamedOptions = Record<string, ApolloClient.Options>;
type Flags = {
    /**
     * Observable starts with `{ loading: true }`.
     *
     * Disabled by default
     */
    useMutationLoading?: boolean;
};

declare function provideApollo(optionsFactory: () => ApolloClient.Options, flags?: Flags): Provider;
declare function provideNamedApollo(optionsFactory: () => NamedOptions, flags?: Flags): Provider;

type QueryRefFromDocument<T extends TypedDocumentNode> = T extends TypedDocumentNode<infer TData, infer TVariables> ? QueryRef<TData, TVariables & OperationVariables> : never;
declare class QueryRef<TData, TVariables extends OperationVariables = EmptyObject> {
    private readonly obsQuery;
    readonly valueChanges: Observable<ObservableQuery.Result<TData>>;
    constructor(obsQuery: ObservableQuery<TData, TVariables>, ngZone: NgZone);
    get options(): ObservableQuery<TData, TVariables>['options'];
    get variables(): ObservableQuery<TData, TVariables>['variables'];
    getCurrentResult(): ReturnType<ObservableQuery<TData, TVariables>['getCurrentResult']>;
    refetch(variables?: Parameters<ObservableQuery<TData, TVariables>['refetch']>[0]): ReturnType<ObservableQuery<TData, TVariables>['refetch']>;
    fetchMore<TFetchData = TData, TFetchVars extends OperationVariables = TVariables>(fetchMoreOptions: ObservableQuery.FetchMoreOptions<TData, TVariables, TFetchData, TFetchVars>): Promise<ApolloClient.QueryResult<MaybeMasked<TFetchData>>>;
    subscribeToMore<TSubscriptionData = TData, TSubscriptionVariables extends OperationVariables = TVariables>(options: ObservableQuery.SubscribeToMoreOptions<TData, TSubscriptionVariables, TSubscriptionData, TVariables>): ReturnType<ObservableQuery<TData, TVariables>['subscribeToMore']>;
    updateQuery(mapFn: Parameters<ObservableQuery<TData, TVariables>['updateQuery']>[0]): ReturnType<ObservableQuery<TData, TVariables>['updateQuery']>;
    stopPolling(): ReturnType<ObservableQuery<TData, TVariables>['stopPolling']>;
    startPolling(pollInterval: Parameters<ObservableQuery<TData, TVariables>['startPolling']>[0]): ReturnType<ObservableQuery<TData, TVariables>['startPolling']>;
    setVariables(variables: Parameters<ObservableQuery<TData, TVariables>['setVariables']>[0]): ReturnType<ObservableQuery<TData, TVariables>['setVariables']>;
    reobserve(options: ObservableQuery.Options<TData, TVariables>): ReturnType<ObservableQuery<TData, TVariables>['reobserve']>;
}

declare class ApolloBase {
    protected readonly ngZone: NgZone;
    protected readonly flags?: Flags;
    protected _client?: ApolloClient;
    private useMutationLoading;
    constructor(ngZone: NgZone, flags?: Flags, _client?: ApolloClient);
    watchQuery<TData, TVariables extends OperationVariables = EmptyObject>(options: Apollo.WatchQueryOptions<TData, TVariables>): QueryRef<TData, TVariables>;
    query<TData, TVariables extends OperationVariables = EmptyObject>(options: Apollo.QueryOptions<TData, TVariables>): Observable<Apollo.QueryResult<TData>>;
    mutate<TData, TVariables extends OperationVariables = EmptyObject>(options: Apollo.MutateOptions<TData, TVariables>): Observable<Apollo.MutateResult<TData>>;
    watchFragment<TFragmentData = unknown, TVariables extends OperationVariables = EmptyObject>(options: Apollo.WatchFragmentOptions<TFragmentData, TVariables>): Observable<Apollo.WatchFragmentResult<TFragmentData>>;
    subscribe<TData, TVariables extends OperationVariables = EmptyObject>(options: Apollo.SubscribeOptions<TData, TVariables>): Observable<Apollo.SubscribeResult<TData>>;
    /**
     * Get an instance of ApolloClient
     */
    get client(): ApolloClient;
    /**
     * Set a new instance of ApolloClient
     * Remember to clean up the store before setting a new client.
     *
     * @param client ApolloClient instance
     */
    set client(client: ApolloClient);
    private ensureClient;
    private checkInstance;
}
declare namespace Apollo {
    type WatchQueryOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = ApolloClient.WatchQueryOptions<TData, TVariables>;
    type QueryOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = ApolloClient.QueryOptions<TData, TVariables>;
    type QueryResult<TData = unknown> = ApolloClient.QueryResult<TData>;
    type MutateOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = ApolloClient.MutateOptions<TData, TVariables> & {
        /**
         * Observable starts with `{ loading: true }`.
         *
         * Disabled by default
         */
        useMutationLoading?: boolean;
    };
    type MutateResult<TData = unknown> = ApolloClient.MutateResult<TData> & {
        loading?: boolean;
    };
    type SubscribeOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = ApolloClient.SubscribeOptions<TData, TVariables> & {
        useZone?: boolean;
    };
    type SubscribeResult<TData = unknown> = ApolloClient.SubscribeResult<TData>;
    interface WatchFragmentOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> extends ApolloClient.WatchFragmentOptions<TData, TVariables> {
        useZone?: boolean;
    }
    type WatchFragmentResult<TData = unknown> = ApolloClient.WatchFragmentResult<TData>;
}
declare class Apollo extends ApolloBase {
    private map;
    constructor(ngZone: NgZone, apolloOptions?: ApolloClient.Options, apolloNamedOptions?: NamedOptions, flags?: Flags);
    /**
     * Create an instance of ApolloClient
     * @param options Options required to create ApolloClient
     * @param name client's name
     */
    create(options: ApolloClient.Options, name?: string): void;
    /**
     * Use a default ApolloClient
     */
    default(): ApolloBase;
    /**
     * Use a named ApolloClient
     * @param name client's name
     */
    use(name: string): ApolloBase;
    /**
     * Create a default ApolloClient, same as `apollo.create(options)`
     * @param options ApolloClient's options
     */
    createDefault(options: ApolloClient.Options): void;
    /**
     * Create a named ApolloClient, same as `apollo.create(options, name)`
     * @param name client's name
     * @param options ApolloClient's options
     */
    createNamed(name: string, options: ApolloClient.Options): void;
    /**
     * Remember to clean up the store before removing a client
     * @param name client's name
     */
    removeClient(name?: string): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<Apollo, [null, { optional: true; }, { optional: true; }, { optional: true; }]>;
    static ɵprov: i0.ɵɵInjectableDeclaration<Apollo>;
}

declare namespace Query {
    type WatchOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = Omit<Apollo.WatchQueryOptions<TData, TVariables>, 'query'>;
    type FetchOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = Omit<Apollo.QueryOptions<TData, TVariables>, 'query'>;
}
declare abstract class Query<TData = unknown, TVariables extends OperationVariables = EmptyObject> {
    protected readonly apollo: Apollo;
    abstract readonly document: DocumentNode | TypedDocumentNode<TData, TVariables>;
    client: string;
    constructor(apollo: Apollo);
    watch(...[options]: {} extends TVariables ? [options?: Query.WatchOptions<TData, TVariables>] : [options: Query.WatchOptions<TData, TVariables>]): QueryRef<TData, TVariables>;
    fetch(...[options]: {} extends TVariables ? [options?: Query.FetchOptions<TData, TVariables>] : [options: Query.FetchOptions<TData, TVariables>]): Observable<Apollo.QueryResult<TData>>;
    static ɵfac: i0.ɵɵFactoryDeclaration<Query<any, any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<Query<any, any>>;
}

declare namespace Mutation {
    type MutateOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = Omit<Apollo.MutateOptions<TData, TVariables>, 'mutation'>;
}
declare abstract class Mutation<TData = unknown, TVariables extends OperationVariables = EmptyObject> {
    protected readonly apollo: Apollo;
    abstract readonly document: DocumentNode | TypedDocumentNode<TData, TVariables>;
    client: string;
    constructor(apollo: Apollo);
    mutate(...[options]: {} extends TVariables ? [options?: Mutation.MutateOptions<TData, TVariables>] : [options: Mutation.MutateOptions<TData, TVariables>]): Observable<Apollo.MutateResult<TData>>;
    static ɵfac: i0.ɵɵFactoryDeclaration<Mutation<any, any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<Mutation<any, any>>;
}

declare namespace Subscription {
    type SubscribeOptions<TData = unknown, TVariables extends OperationVariables = EmptyObject> = Omit<Apollo.SubscribeOptions<TData, TVariables>, 'query'>;
}
declare abstract class Subscription<TData = unknown, TVariables extends OperationVariables = EmptyObject> {
    protected readonly apollo: Apollo;
    abstract readonly document: DocumentNode | TypedDocumentNode<TData, TVariables>;
    client: string;
    constructor(apollo: Apollo);
    subscribe(...[options]: {} extends TVariables ? [options?: Subscription.SubscribeOptions<TData, TVariables>] : [options: Subscription.SubscribeOptions<TData, TVariables>]): Observable<Apollo.SubscribeResult<TData>>;
    static ɵfac: i0.ɵɵFactoryDeclaration<Subscription<any, any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<Subscription<any, any>>;
}

declare const APOLLO_FLAGS: InjectionToken<Flags>;
declare const APOLLO_OPTIONS: InjectionToken<ApolloClient.Options>;
declare const APOLLO_NAMED_OPTIONS: InjectionToken<NamedOptions>;

declare const gql: <Result, Variables>(literals: ReadonlyArray<string> | Readonly<string>, ...placeholders: any[]) => TypedDocumentNode<Result, Variables>;

type CompleteFragment<TData> = {
    complete: true;
    missing?: never;
} & GetDataState<TData, 'complete'>;
type ForWatchFragment<TData> = OperatorFunction<ApolloClient$1.WatchFragmentResult<TData>, CompleteFragment<TData>>;
/**
 * Filter emitted results to only receive results that are complete (`result.dataState === 'complete'`).
 *
 * This is a small wrapper around rxjs `filter()` for convenience only.
 *
 * If you use this, you should probably combine it with [`notifyOnNetworkStatusChange`](https://www.apollographql.com/docs/react/data/queries#queryhookoptions-interface-notifyonnetworkstatuschange).
 * This tells `@apollo/client` to not emit the first `partial` result, so `apollo-angular` does
 * not need to filter it out. The overall behavior is identical, but it saves some CPU cycles.
 *
 * So something like this:
 *
 * ```ts
 * apollo
 *   .watchQuery({
 *     query: myQuery,
 *     notifyOnNetworkStatusChange: false, // Adding this will save CPU cycles
 *   })
 *   .valueChanges
 *   .pipe(onlyCompleteData())
 *   .subscribe(result => {
 *     // Do something with complete result
 *   });
 * ```
 */
declare function onlyCompleteData<TData>(): OperatorFunction<ObservableQuery$1.Result<TData>, ObservableQuery$1.Result<TData, 'complete'>>;
/**
 * @deprecated Use `onlyCompleteData()` instead.
 */
declare const onlyComplete: typeof onlyCompleteData;
/**
 * Same as `onlyCompleteData()` but for `Apollo.watchFragment()`.
 */
declare function onlyCompleteFragment<TData>(): ForWatchFragment<TData>;

export { APOLLO_FLAGS, APOLLO_NAMED_OPTIONS, APOLLO_OPTIONS, Apollo, ApolloBase, Mutation, Query, QueryRef, Subscription, gql, onlyComplete, onlyCompleteData, onlyCompleteFragment, provideApollo, provideNamedApollo };
export type { Flags, NamedOptions, QueryRefFromDocument, ResultOf, VariablesOf };
