import { ReactNode } from 'react';
import { ApolloLink, FetchPolicy, ApolloClient, OperationVariables } from '@apollo/client';
import { QueryRef } from '@apollo/client/react';

/**
 * @internal
 */
type ReadableStreamLinkEvent = {
    type: "next";
    value: ApolloLink.Result;
} | {
    type: "completed";
} | {
    type: "error";
};

type TransportedOptions = {
    query: string;
    nextFetchPolicy?: FetchPolicy | undefined;
} & Omit<ApolloClient.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;
};
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;
    };
}

declare function SimulatePreloadedQuery$1<T>({ queryRef, children, }: {
    queryRef: TransportedQueryRef<T>;
    children: ReactNode;
}): ReactNode;

declare const SimulatePreloadedQuery: typeof SimulatePreloadedQuery$1;

export { SimulatePreloadedQuery };
