import { ApolloClient } from '@apollo/client/core';
import { APOLLO_STATE_PROP_NAME } from '../constants';
import type { InitCacheConfig, InvalidationCacheConfig } from './cache';
import type { CachePersistor } from './cachePersistor';
import type { NormalizedCacheObject, ApolloCache, ApolloLink, RequestHandler } from '@apollo/client';
type ApolloClientOptions = {
    /** Apollo server url, can be static string or obtained from function on the fly */
    uri: (() => string) | string;
    /** Headers to include in each request, can be helpful in SSR environments */
    headers?: Record<string, string>;
    /** Client's cache config */
    cacheConfig?: InvalidationCacheConfig;
    /** Middleware to process / enrich requests */
    middlewares?: Array<ApolloLink | RequestHandler>;
};
export type InitApolloClientOptions = Partial<Omit<ApolloClientOptions, 'cacheConfig'>> & {
    /** Results in cache being initialized with skipOnRead */
    networkOnly?: boolean;
};
export type ApolloHelperOptions = Omit<ApolloClientOptions, 'cacheConfig'> & {
    /** Cache initializer */
    cacheConfig?: InitCacheConfig;
};
type SSRResult<PropsType> = {
    props: PropsType & {
        [APOLLO_STATE_PROP_NAME]?: NormalizedCacheObject;
    };
};
type UseApolloHookResult<TClient> = {
    client: TClient;
    cachePersistor: CachePersistor<NormalizedCacheObject> | undefined;
};
export type InitializeApollo<TClient> = (options?: InitApolloClientOptions) => TClient;
export type UseApollo<TClient> = <PropsType>(pageProps: SSRResult<PropsType>['props']) => UseApolloHookResult<TClient>;
interface ApolloHelperInterface {
    initializeApollo: InitializeApollo<ApolloClient<NormalizedCacheObject>>;
    generateUseApolloHook: () => UseApollo<ApolloClient<NormalizedCacheObject>>;
}
type ClientWithExtractableCache = {
    cache: Pick<ApolloCache<NormalizedCacheObject>, 'extract'>;
};
/**
 * Extracts apollo cache from client and modify page props to include it,
 * so all data prefetched in SSR can be passed to client.
 * @example
 * export const getServerSideProps = async ({ req }) => {
 *     const headers = extractHeaders(req)
 *     const client = initializeApollo({ headers })
 *
 *     const { data } = await client.query({ ... })
 *
 *     return extractApolloState(client, {
 *         props: { ... }
 *     })
 * }
 */
export declare function extractApolloState<PropsType>(client: ClientWithExtractableCache, pageParams: SSRResult<PropsType>): SSRResult<PropsType>;
/**
 * Apollo helper which is used to generate utils for CSR / SSR, based on common client configuration
 *
 * @example Init helper and export utils for app
 * import { ListHelper, ApolloHelper } from '@open-condo/apollo'
 * import { TracingMiddleware } from '@open-condo/miniapp-utils/apollo'
 * import type { InitCacheConfig } from '@open-condo/apollo'
 *
 * const cacheConfig: InitCacheConfig = (cacheOptions) => {
 *     const defaultListHelper = new ListHelper({ cacheOptions })
 *
 *     return {
 *         typePolicies: {
 *             Query: {
 *                 fields: {
 *                     allContacts: {
 *                         keyArgs: ['where'],
 *                         read: defaultListHelper.getReadFunction('paginate'),
 *                         merge: defaultListHelper.mergeLists,
 *                     },
 *                 },
 *             },
 *         },
 *     }
 * }
 *
 * const apolloHelper = new ApolloHelper({
 *     middlewares: [
 *         new TracingMiddleware()
 *     ],
 *     uri: 'http://localhost:3000',
 *     cacheConfig,
 * })
 *
 * export const initializeApollo = apolloHelper.initializeApollo
 * export const useApollo = apolloHelper.generateUseApolloHook()
 * export { extractApolloState } from '@open-condo/apollo'
 *
 * @example Use in SSR
 * import { initializeApollo, extractApolloState } from '@/domains/common/utils/apollo'
 *
 * export const getServerSideProps = async ({ req }) => {
 *     const headers = extractHeaders(req)
 *     const client = initializeApollo({ headers })
 *
 *     const { data } = await client.query({ ... })
 *
 *     return extractApolloState(client, {
 *         props: { ... }
 *     })
 * }
 *
 * @example Init on client in _app.tsx
 * export default function App ({ Component, pageProps }: AppProps): ReactNode {
 *     const { client, cachePersistor } = useApollo(pageProps)
 *
 *     return (
 *         <ApolloProvider client={client}>
 *             <CachePersistorContext.Provider value={{ persistor: cachePersistor }}>
 *                 <Component {...pageProps} />
 *             </CachePersistorContext.Provider>
 *         </ApolloProvider>
 *     )
 * }
 */
export declare class ApolloHelper implements ApolloHelperInterface {
    /** Initial options */
    private readonly _initialApolloOptions;
    /** Cache initializer */
    private readonly _cacheConfig?;
    /** Apollo client to reuse on CSR */
    private _apolloClient;
    constructor(options: ApolloHelperOptions);
    /**
     * Generates cache config to init cache,
     * based on cache initializer and some client options
     */
    private _getCacheConfig;
    /**
     * Creates new apollo client, if necessary with specified cache configuration
     *
     * When in SSR, generates new apollo client via createApolloClient util on each initializeApollo call
     * When in CSR, generate new apollo client once and then reuses it on subsequent initializeApollo calls
     *
     * You should probably use it only in SSR utils, such as getServerSideProps,
     * on client you should use useApollo hook instead
     *
     * @example Use in SSR
     * export const getServerSideProps = async ({ req }) => {
     *     const headers = extractHeaders(req)
     *     const client = initializeApollo({ headers })
     *
     *     const { data } = await client.query({ ... })
     *
     *     return extractApolloState(client, {
     *         props: { ... }
     *     })
     * }
     */
    initializeApollo(options?: InitApolloClientOptions): ApolloClient<NormalizedCacheObject>;
    /**
     * Generates useApollo hook to init apollo in react tree and pass it to whole app using default ApolloProvider
     *
     * @example
     * export default function App ({ Component, pageProps }: AppProps): ReactNode {
     *     const { client, cachePersistor } = useApollo(pageProps)
     *
     *     return (
     *         <ApolloProvider client={client}>
     *             <CachePersistorContext.Provider value={{ persistor: cachePersistor }}>
     *                 <Component {...pageProps} />
     *             </CachePersistorContext.Provider>
     *         </ApolloProvider>
     *     )
     * }
     */
    generateUseApolloHook(): <PropsType>(pageProps: SSRResult<PropsType>['props']) => UseApolloHookResult<ApolloClient<NormalizedCacheObject>>;
}
export {};
