import * as _apollo_client from '@apollo/client';
import { ApolloLink, FetchPolicy, ApolloClient as ApolloClient$1, OperationVariables, DocumentNode, TypedDocumentNode, InMemoryCache as InMemoryCache$1, InMemoryCacheConfig, Observable as Observable$1 } from '@apollo/client';
import React, { ReactNode } from 'react';
import { wrapQueryRef } from '@apollo/client/react/internal';
import { QueryRef } from '@apollo/client/react';
import { Observable } from '@apollo/client/utilities';
import * as rxjs from 'rxjs';

/**
 * @internal
 */
type ReadableStreamLinkEvent = {
    type: "next";
    value: ApolloLink.Result;
} | {
    type: "completed";
} | {
    type: "error";
};
/**
 * Called when the link is hit, before the request is forwarded.
 *
 * Should return the controller for the readable stream.
 *
 * This is useful because when starting a query, it's not always
 * clear if the query will hit the network or will be served from
 * cache, deduplicated etc.
 * This allows to inject the "start event" into the stream only
 * when we know that more chunks will actually follow.
 */
type OnLinkHitFunction = () => ReadableStreamDefaultController<ReadableStreamLinkEvent>;
interface InternalContext {
    [teeToReadableStreamKey]?: OnLinkHitFunction;
    [readFromReadableStreamKey]?: ReadableStream<ReadableStreamLinkEvent>;
}
declare const teeToReadableStreamKey: unique symbol;
declare const readFromReadableStreamKey: unique symbol;
/**
 * Apply to a context that will be passed to a link chain containing `TeeToReadableStreamLink`.
 * @public
 */
declare function teeToReadableStream<T extends Record<string, any>>(onLinkHit: OnLinkHitFunction, context: T): T & InternalContext;
/**
 * Apply to a context that will be passed to a link chain containing `ReadFromReadableStreamLink`.
 * @public
 */
declare function readFromReadableStream<T extends Record<string, any>>(readableStream: ReadableStream<ReadableStreamLinkEvent>, context: T): T & InternalContext;
/**
 * A link that allows the request to be cloned into a readable stream, e.g. for
 * transport of multipart responses from RSC or a server loader to the browser.
 * @public
 */
declare class TeeToReadableStreamLink extends ApolloLink {
    constructor();
}
/**
 * A link that allows the response to be read from a readable stream, e.g. for
 * hydration of a multipart response from RSC or a server loader in the browser.
 * @public
 */
declare class ReadFromReadableStreamLink extends ApolloLink {
    constructor();
}

type TransportedOptions = {
    query: string;
    nextFetchPolicy?: FetchPolicy | undefined;
} & Omit<ApolloClient$1.WatchQueryOptions, "query" | "skipPollAttempt" | "nextFetchPolicy">;

type JsonString<Encoded> = string & {
    __jsonString?: [Encoded];
};

type RestrictedPreloadOptions = {
    fetchPolicy?: "network-only" | "cache-and-network" | "cache-first";
    returnPartialData?: false;
    nextFetchPolicy?: undefined;
    pollInterval?: undefined;
};
/** @public */
type PreloadTransportedQueryOptions<TData, TVariables extends OperationVariables> = Omit<ApolloClient$1.QueryOptions<TData, TVariables>, "query"> & RestrictedPreloadOptions;
type TransportedQueryRefOptions = TransportedOptions & RestrictedPreloadOptions;
/**
 * A `TransportedQueryRef` is an opaque object accessible via renderProp within `PreloadQuery`.
 *
 * A child client component reading the `TransportedQueryRef` via useReadQuery will suspend until the promise resolves.
 *
 * @public
 */
interface TransportedQueryRef<TData = unknown, TVariables extends OperationVariables = OperationVariables> extends QueryRef<TData, TVariables> {
    /**
     * Temporarily disabled - see https://github.com/apollographql/apollo-client-integrations/issues/332
     *
     * Will now be be `undefined` both in React Server Components and Client Components until we can find a better resolution.
     */
    toPromise?: undefined;
    /** @internal */
    $__apollo_queryRef: {
        options: TransportedQueryRefOptions;
        stream: ReadableStream<JsonString<ReadableStreamLinkEvent>>;
        /**
         * A unique key for this query, to ensure it is only hydrated once,
         * even if it should get transported over the wire in a way that results
         * in multiple objects describing the same queryRef.
         * This key will be used to store the queryRef in the suspence cache.
         *
         * The chances of this happening should be slim (it is handled within
         * React thanks to https://github.com/facebook/react/pull/28996), but
         * as we use transported queryRefs with multiple frameworks with distinct
         * transport mechanisms, this seems like a safe option.
         */
        queryKey: string;
    };
}
/** @public */
interface PreloadTransportedQueryFunction {
    <TData = unknown, TVariables extends OperationVariables = OperationVariables>(query: DocumentNode | TypedDocumentNode<TData, TVariables>, options?: PreloadTransportedQueryOptions<TData, NoInfer<TVariables>>): TransportedQueryRef<TData, TVariables>;
}
/** @public */
declare function createTransportedQueryPreloader(client: ApolloClient$1, { prepareForReuse, notTransportedOptionOverrides, }?: {
    /**
     * Set this to `true` to indicate that this `queryRef` will be reused within the same process with the same Apollo Client instance without being dehydrated and hydrated.
     * In that case, it will already be written to the suspense cache so it doesn't need to be hydrated by re-running the query with a fake network request.
     */
    prepareForReuse?: boolean;
    notTransportedOptionOverrides?: never;
} | {
    prepareForReuse?: never;
    /**
     * Overrides to the options that should happen only in the `preloader` call, but should not be transported/hydrated on the client.
     */
    notTransportedOptionOverrides?: Partial<ApolloClient$1.WatchQueryOptions<any, any>>;
}): PreloadTransportedQueryFunction;
/** @public */
declare function reviveTransportedQueryRef(queryRef: TransportedQueryRef, client: ApolloClient$1): asserts queryRef is TransportedQueryRef & ReturnType<typeof wrapQueryRef>;
/** @public */
declare function isTransportedQueryRef(queryRef: any): queryRef is TransportedQueryRef;

declare namespace PreloadQuery {
    type Options<TData, TVariables extends OperationVariables> = PreloadTransportedQueryOptions<TData, TVariables> & {
        query: DocumentNode | TypedDocumentNode<TData, TVariables>;
    };
    type Props<TData, TVariables extends OperationVariables> = PreloadQuery.Options<TData, TVariables> & {
        children: ReactNode | ((queryRef: TransportedQueryRef<NoInfer<TData>, NoInfer<TVariables>>) => ReactNode);
    };
}
declare function PreloadQuery<TData, TVariables extends OperationVariables>({ getClient, children, query, ...transportedOptions }: PreloadQuery.Props<TData, TVariables> & {
    getClient: () => ApolloClient$1 | Promise<ApolloClient$1>;
}): Promise<React.ReactElement>;

/**
 * > This export is only available in React Server Components
 *
 * Ensures that you can always access the same instance of ApolloClient
 * during RSC for an ongoing request, while always returning
 * a new instance for different requests.
 *
 * @example
 * ```ts
 * export const { getClient, query, PreloadQuery } = registerApolloClient(() => {
 *   return new ApolloClient({
 *     cache: new InMemoryCache(),
 *     link: new HttpLink({
 *       uri: "http://example.com/api/graphql",
 *     }),
 *   });
 * });
 * ```
 *
 * @public
 */
declare function registerApolloClient<ApolloClientOrPromise extends Promise<ApolloClient$1> | ApolloClient$1>(makeClient: () => ApolloClientOrPromise): {
    getClient: () => ApolloClientOrPromise;
    query: Awaited<ApolloClientOrPromise>["query"];
    /**
     * Preloads data in React Server Components to be hydrated
     * in Client Components.
     *
     * ### Example with `queryRef`
     * `ClientChild` would call `useReadQuery` with the `queryRef`, the `Suspense` boundary is optional:
     * ```jsx
     * <PreloadQuery
     *    query={QUERY}
     *    variables={{
     *      foo: 1
     *    }}
     *  >
     *   {(queryRef) => (
     *     <Suspense fallback={<>loading</>}>
     *       <ClientChild queryRef={queryRef} />
     *     </Suspense>
     *   )}
     * </PreloadQuery>
     * ```
     *
     * ### Example for `useSuspenseQuery`
     * `ClientChild` would call the same query with `useSuspenseQuery`, the `Suspense` boundary is optional:
     * ```jsx
     *  <PreloadQuery
     *    query={QUERY}
     *    variables={{
     *      foo: 1
     *    }}
     *  >
     *    <Suspense fallback={<>loading</>}>
     *      <ClientChild />
     *    </Suspense>
     *  </PreloadQuery>
     * ```
     */
    PreloadQuery: PreloadQueryComponent;
};
/**
 * @deprecated use `PreloadQuery.Props` instead
 * @public
 */
type PreloadQueryProps<TData, TVariables extends OperationVariables> = PreloadQuery.Props<TData, TVariables>;
/**
 * Preloads data in React Server Components to be hydrated
 * in Client Components.
 *
 * ### Example with `queryRef`
 * `ClientChild` would call `useReadQuery` with the `queryRef`, the `Suspense` boundary is optional:
 * ```jsx
 * <PreloadQuery
 *    query={QUERY}
 *    variables={{
 *      foo: 1
 *    }}
 *  >
 *   {(queryRef) => (
 *     <Suspense fallback={<>loading</>}>
 *       <ClientChild queryRef={queryRef} />
 *     </Suspense>
 *   )}
 * </PreloadQuery>
 * ```
 *
 * ### Example for `useSuspenseQuery`
 * `ClientChild` would call the same query with `useSuspenseQuery`, the `Suspense` boundary is optional:
 * ```jsx
 *  <PreloadQuery
 *    query={QUERY}
 *    variables={{
 *      foo: 1
 *    }}
 *  >
 *    <Suspense fallback={<>loading</>}>
 *      <ClientChild />
 *    </Suspense>
 *  </PreloadQuery>
 * ```
 *
 * @public
 */
interface PreloadQueryComponent {
    <TData, TVariables extends OperationVariables>(props: PreloadQuery.Props<TData, TVariables>): React.ReactElement;
}

interface AccumulateMultipartResponsesConfig {
    /**
     * The maximum delay in milliseconds
     * from receiving the first response
     * until the accumulated data will be flushed
     * and the connection will be closed.
     */
    cutoffDelay: number;
}
/**
 *
 * This link can be used to "debounce" the initial response of a multipart request. Any incremental data received during the `cutoffDelay` time will be merged into the initial response.
 *
 * After `cutoffDelay`, the link will return the initial response, even if there is still incremental data pending, and close the network connection.
 *
 * If `cutoffDelay` is `0`, the link will immediately return data as soon as it is received, without waiting for incremental data, and immediately close the network connection.
 *
 * @example
 * ```ts
 * new AccumulateMultipartResponsesLink({
 *   // The maximum delay in milliseconds
 *   // from receiving the first response
 *   // until the accumulated data will be flushed
 *   // and the connection will be closed.
 *   cutoffDelay: 100,
 *  });
 * ```
 *
 * @public
 */
declare class AccumulateMultipartResponsesLink extends ApolloLink {
    private maxDelay;
    constructor(config: AccumulateMultipartResponsesConfig);
    request(operation: ApolloLink.Operation, forward?: ApolloLink.ForwardFunction): Observable<ApolloLink.Result<Record<string, any>, Record<string, any>>>;
}

interface RemoveMultipartDirectivesConfig {
    /**
     * Whether to strip fragments with `@defer` directives
     * from queries before sending them to the server.
     *
     * Defaults to `true`.
     *
     * Can be overwritten by adding a label starting
     * with either `"SsrDontStrip"` or `"SsrStrip"` to the
     * directive.
     */
    stripDefer?: boolean;
}
/**
 * This link will (if called with `stripDefer: true`) strip all `@defer` fragments from your query.
 *
 * This is used to prevent the server from doing additional work in SSR scenarios where multipart responses cannot be handled anyways.
 *
 * You can exclude certain fragments from this behavior by giving them a label starting with `"SsrDontStrip"`.
 * The "starting with" is important, because labels have to be unique per operation. So if you have multiple directives where you want to override the default stipping behaviour,
 * you can do this by annotating them like
 * ```graphql
 * query myQuery {
 *   fastField
 *   ... @defer(label: "SsrDontStrip1") {
 *     slowField1
 *   }
 *   ... @defer(label: "SsrDontStrip2") {
 *     slowField2
 *   }
 * }
 * ```
 *
 * You can also use the link with `stripDefer: false` and mark certain fragments to be stripped by giving them a label starting with `"SsrStrip"`.
 *
 * @example
 * ```ts
 * new RemoveMultipartDirectivesLink({
 *   // Whether to strip fragments with `@defer` directives
 *   // from queries before sending them to the server.
 *   //
 *   // Defaults to `true`.
 *   //
 *   // Can be overwritten by adding a label starting
 *   // with either `"SsrDontStrip"` or `"SsrStrip"` to the
 *   // directive.
 *   stripDefer: true,
 * });
 * ```
 *
 * @public
 */
declare class RemoveMultipartDirectivesLink extends ApolloLink {
    private stripDirectives;
    constructor(config: RemoveMultipartDirectivesConfig);
    request(operation: ApolloLink.Operation, forward?: ApolloLink.ForwardFunction): rxjs.Observable<{}>;
}

interface SSRMultipartLinkConfig {
    /**
     * Whether to strip fragments with `@defer` directives
     * from queries before sending them to the server.
     *
     * Defaults to `true`.
     *
     * Can be overwritten by adding a label starting
     * with either `"SsrDontStrip"` or `"SsrStrip"` to the
     * directive.
     */
    stripDefer?: boolean;
    /**
     * The maximum delay in milliseconds
     * from receiving the first response
     * until the accumulated data will be flushed
     * and the connection will be closed.
     *
     * Defaults to `0`.
     */
    cutoffDelay?: number;
}
/**
 * A convenient combination of `RemoveMultipartDirectivesLink` and `AccumulateMultipartResponsesLink`.
 *
 * @example
 * ```ts
 * new SSRMultipartLink({
 *   // Whether to strip fragments with `@defer` directives
 *   // from queries before sending them to the server.
 *   //
 *   // Defaults to `true`.
 *   //
 *   // Can be overwritten by adding a label starting
 *   // with either `"SsrDontStrip"` or `"SsrStrip"` to the
 *   // directive.
 *   stripDefer: true,
 *   // The maximum delay in milliseconds
 *   // from receiving the first response
 *   // until the accumulated data will be flushed
 *   // and the connection will be closed.
 *   //
 *   // Defaults to `0`.
 *   //
 *   cutoffDelay: 100,
 * });
 * ```
 *
 * @public
 */
declare class SSRMultipartLink extends ApolloLink {
    constructor(config?: SSRMultipartLinkConfig);
}

declare const sourceSymbol: unique symbol;

/**
 * A version of `InMemoryCache` to be used with streaming SSR.
 *
 * For more documentation, please see {@link https://www.apollographql.com/docs/react/api/cache/InMemoryCache | the Apollo Client API documentation}.
 *
 * @public
 */
declare class InMemoryCache extends InMemoryCache$1 {
    /**
     * Information about the current package and it's export names, for use in error messages.
     *
     * @internal
     */
    static readonly info: {
        pkg: string;
    };
    [sourceSymbol]: string;
    constructor(config?: InMemoryCacheConfig | undefined);
}

type TransportIdentifier = string & {
    __transportIdentifier: true;
};
/**
 * Events that will be emitted by a wrapped ApolloClient instance during
 * SSR on `DataTransportProviderImplementation.registerDispatchRequestStarted`,
 * to be transported to the browser and replayed there using
 * `DataTransportProviderImplementation.onQueryEvent`.
 *
 * @public
 */
type QueryEvent = {
    type: "started";
    options: TransportedOptions;
    id: TransportIdentifier;
} | (ReadableStreamLinkEvent & {
    id: TransportIdentifier;
});
type ProgressEvent = Exclude<QueryEvent, {
    type: "started";
}>;

type SimulatedQueryInfo = {
    controller: ReadableStreamDefaultController<ReadableStreamLinkEvent>;
    options: ApolloClient$1.WatchQueryOptions<any, OperationVariables>;
};
declare class ApolloClientBase extends ApolloClient$1 {
    /**
     * Information about the current package and it's export names, for use in error messages.
     *
     * @internal
     */
    static readonly info: {
        pkg: string;
    };
    [sourceSymbol]: string;
    constructor(options: ApolloClient.Options);
    setLink(newLink: ApolloLink): void;
}
declare class ApolloClientClientBaseImpl extends ApolloClientBase {
    constructor(options: ApolloClient.Options);
    private simulatedStreamingQueries;
    onQueryStarted({ options, id }: Extract<QueryEvent, {
        type: "started";
    }>): void;
    onQueryProgress: (event: ProgressEvent) => void;
    /**
     * Can be called when the stream closed unexpectedly while there might still be unresolved
     * simulated server-side queries going on.
     * Those queries will be cancelled and then re-run in the browser.
     */
    rerunSimulatedQueries: () => void;
    rerunSimulatedQuery: (queryInfo: SimulatedQueryInfo) => void;
}
declare class ApolloClientSSRImpl extends ApolloClientClientBaseImpl {
    watchQueryQueue: {
        push: (value: {
            event: Extract<QueryEvent, {
                type: "started";
            }>;
            observable: Observable$1<Exclude<QueryEvent, {
                type: "started";
            }>>;
        }) => void;
        register: (callback: ((value: {
            event: Extract<QueryEvent, {
                type: "started";
            }>;
            observable: Observable$1<Exclude<QueryEvent, {
                type: "started";
            }>>;
        }) => void) | null) => void;
    };
    pushEventStream(options: ApolloClient$1.WatchQueryOptions<any, any>): ReadableStreamDefaultController<ReadableStreamLinkEvent>;
    watchQuery<TData = any, TVariables extends OperationVariables = OperationVariables>(options: ApolloClient$1.WatchQueryOptions<TData, TVariables>): _apollo_client.ObservableQuery<TData, TVariables>;
}
declare const ApolloClient_base: typeof ApolloClientBase;
/** @public */
declare namespace ApolloClient {
    /** @public */
    interface Options extends Omit<ApolloClient$1.Options, "cache" | "ssrMode" | "ssrForceFetchDelay"> {
        cache: InMemoryCache;
    }
}
/**
 * A version of `ApolloClient` to be used with streaming SSR or in React Server Components.
 *
 * For more documentation, please see {@link https://www.apollographql.com/docs/react/api/core/ApolloClient | the Apollo Client API documentation}.
 *
 * @public
 */
declare class ApolloClient extends ApolloClient_base implements Partial<ApolloClientSSRImpl> {
    /** @internal */
    onQueryStarted?: ApolloClientSSRImpl["onQueryStarted"];
    /** @internal */
    onQueryProgress?: ApolloClientSSRImpl["onQueryProgress"];
    /** @internal */
    rerunSimulatedQueries?: ApolloClientSSRImpl["rerunSimulatedQueries"];
    /** @internal */
    rerunSimulatedQuery?: ApolloClientSSRImpl["rerunSimulatedQuery"];
    /** @internal */
    watchQueryQueue?: ApolloClientSSRImpl["watchQueryQueue"];
}

declare const ApolloClientSingleton: unique symbol;

declare global {
    interface Window {
        [ApolloClientSingleton]?: ApolloClient;
    }
}

export { ApolloClient, AccumulateMultipartResponsesLink as DebounceMultipartResponsesLink, InMemoryCache, type PreloadQueryComponent, type PreloadQueryProps, type PreloadTransportedQueryFunction, type PreloadTransportedQueryOptions, ReadFromReadableStreamLink, type ReadableStreamLinkEvent, RemoveMultipartDirectivesLink, SSRMultipartLink, TeeToReadableStreamLink, type TransportedQueryRef, createTransportedQueryPreloader, isTransportedQueryRef, readFromReadableStream, registerApolloClient, reviveTransportedQueryRef, teeToReadableStream };
