import * as _apollo_client_index_js from '@apollo/client/index.js';
import { FetchResult, ApolloLink, WatchQueryOptions, QueryOptions, OperationVariables, DocumentNode, TypedDocumentNode, ApolloClient as ApolloClient$1, Operation, NextLink, InMemoryCache as InMemoryCache$1, InMemoryCacheConfig, NormalizedCacheObject, Observable as Observable$1, ApolloClientOptions } from '@apollo/client/index.js';
import React, { ReactNode } from 'react';
import { DocumentNode as DocumentNode$1, TypedDocumentNode as TypedDocumentNode$1 } from '@apollo/client';
import { wrapQueryRef } from '@apollo/client/react/internal/index.js';
import { QueryRef } from '@apollo/client/react/index.js';
import { Observable } from '@apollo/client/utilities/index.js';

/**
 * @internal
 */
type ReadableStreamLinkEvent = {
    type: "next";
    value: FetchResult;
} | {
    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;
} & Omit<WatchQueryOptions, "query">;

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<TVariables, TData> = Omit<QueryOptions<TVariables, TData>, "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<NoInfer<TVariables>, TData>): TransportedQueryRef<TData, TVariables>;
}
/** @public */
declare function createTransportedQueryPreloader(client: ApolloClient$1<any>): PreloadTransportedQueryFunction;
/** @public */
declare function reviveTransportedQueryRef(queryRef: TransportedQueryRef, client: ApolloClient$1<any>): asserts queryRef is TransportedQueryRef & ReturnType<typeof wrapQueryRef<any, any>>;
/** @public */
declare function isTransportedQueryRef(queryRef: any): queryRef is TransportedQueryRef;

type PreloadQueryOptions<TVariables, TData> = PreloadTransportedQueryOptions<TVariables, TData> & {
    query: DocumentNode$1 | TypedDocumentNode$1<TData, TVariables>;
};

/**
 * > 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<any>> | ApolloClient$1<any>>(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;
};
/**
 * Props for `PreloadQueryComponent`
 * @see {@link PreloadQueryComponent}
 * @public
 */
interface PreloadQueryProps<TData, TVariables extends OperationVariables> extends PreloadQueryOptions<TVariables, TData> {
    children: ReactNode | ((queryRef: TransportedQueryRef<NoInfer<TData>, NoInfer<TVariables>>) => ReactNode);
}
/**
 * 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: PreloadQueryProps<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: Operation, forward?: NextLink): Observable<FetchResult<Record<string, any>, 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: Operation, forward?: NextLink): 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: WatchQueryOptions<OperationVariables, any>;
};
interface WrappedApolloClientOptions extends Omit<ApolloClientOptions<NormalizedCacheObject>, "cache" | "ssrMode" | "ssrForceFetchDelay"> {
    cache: InMemoryCache;
}
declare class ApolloClientBase extends ApolloClient$1<NormalizedCacheObject> {
    /**
     * 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: WrappedApolloClientOptions);
    setLink(newLink: ApolloLink): void;
}
declare class ApolloClientClientBaseImpl extends ApolloClientBase {
    constructor(options: WrappedApolloClientOptions);
    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: WatchQueryOptions<any, any>): ReadableStreamDefaultController<ReadableStreamLinkEvent>;
    watchQuery<T = any, TVariables extends OperationVariables = OperationVariables>(options: WatchQueryOptions<TVariables, T>): _apollo_client_index_js.ObservableQuery<T, TVariables>;
}
declare const ApolloClient_base: typeof ApolloClientBase;
/**
 * 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<Ignored = NormalizedCacheObject> 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<any>;
    }
}

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 };
