import type { JSONNode } from '@atlaskit/editor-json-transformer';
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
/**
 * Represents the SSR data for a single provider.
 * It's a map where each key is a unique node data key and the value is the prefetched data for that node.
 *
 * @example
 * {
 *   'node-id-1': { value: 'some data' },
 *   'node-id-2': { value: 'other data' }
 * }
 */
type SSRData<Data> = {
    [dataKey: string]: Data;
};
type CacheRecords<Data> = SSRData<Data>;
/**
 * Represents the cached data for a Node Data Provider.
 * Each key is a unique node data key, and the value is an object containing:
 * - `source`: Indicates whether the data was fetched from SSR or the network.
 * - `data`: The actual data, which can be either a resolved value or a Promise.
 *
 * @example
 * {
 *   'node-id-1': { source: 'ssr', data: { value: 'some data' } },
 *   'node-id-2': { source: 'network', data: { value: 'other data' } }
 * }
 */
type CacheData<Data> = Record<string, {
    data: Data;
    source: 'ssr' | 'network';
}>;
/**
 * Represents the payload passed to the callback function when data is fetched.
 * It can either contain an error or the fetched data.
 */
export type CallbackPayload<Data> = {
    data?: undefined;
    /** An error that occurred while fetching data. */
    error: Error;
} | {
    /** Fetched data for the node. */
    data: Data;
    error?: undefined;
};
/**
 * A Node Data Provider is responsible for fetching and caching data associated with specific ProseMirror nodes.
 * It supports a cache-first-then-network strategy, with initial data potentially provided via SSR.
 *
 * @template Node The specific type of JSONNode this provider supports.
 * @template Data The type of data this provider fetches and manages.
 */
export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
    private cacheVersion;
    private cache;
    private readonly networkRequestsInFlight;
    /**
     * A unique name for the provider. Used for identification in SSR.
     */
    abstract readonly name: string;
    /**
     * A type guard to check if a given JSONNode is supported by this provider.
     * Used to ensure that the provider can handle the node type before attempting to fetch data.
     *
     * @param node The node to check.
     * @returns `true` if the node is of the type supported by this provider, otherwise `false`.
     */
    abstract isNodeSupported(node: JSONNode): node is Node;
    /**
     * Generates a unique key for a given node to be used for caching.
     *
     * @param node The node for which to generate a data key.
     * @returns A unique string key for the node's data.
     */
    abstract nodeDataKey(node: Node): string;
    /**
     * Fetches data for a batch of nodes from the network or another asynchronous source.
     *
     * @param nodes An array of nodes for which to fetch data.
     * @returns A promise that resolves to an array of data corresponding to the input nodes.
     */
    abstract fetchNodesData(nodes: Node[]): Promise<Data[]>;
    protected constructor();
    /**
     * Sets the SSR data for the provider.
     * This pre-populates the cache with data rendered on the server, preventing redundant network requests on the client.
     * Calling this method will invalidate the existing cache.
     *
     * @example
     * ```
     * const ssrData = window.__SSR_NODE_DATA__ || {};
     * nodeDataProvider.setSSRData(ssrData);
     * ```
     *
     * @param ssrData A map of node data keys to their corresponding data.
     */
    setSSRData(ssrData?: SSRData<Data>): void;
    /**
     * Clears all cached data.
     * This increments the internal cache version, invalidating any pending network requests.
     *
     * @example
     * ```
     * function useMyNodeDataProvider(contentId: string) {
     *  const nodeDataProvider = new MyNodeDataProvider();
     *
     *  // Reset the cache when the contentId changes (e.g., when the user navigates to a different page).
     *  useEffect(() => {
     *    nodeDataProvider.resetCache();
     *  }, [contentId]);
     *
     *  return nodeDataProvider;
     * }
     * ```
     */
    resetCache(): void;
    /**
     * Fetches data for a given node using a cache-first-then-network strategy.
     *
     * The provided callback may be called multiple times:
     * 1. Immediately with data from the SSR cache, if available.
     * 2. Asynchronously with data fetched from the network.
     *
     * @example
     * ```
     * const nodeDataProvider = new MyNodeDataProvider();
     *
     * nodeDataProvider.getData(node, (data) => {
     * 	console.log('Node data:', data);
     * });
     * ```
     *
     * @param node The node (or its ProseMirror representation) for which to fetch data.
     * @param callback The callback function to call with the fetched data or an error.
     */
    getData(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): void;
    protected getDataAsync(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): Promise<void>;
    /**
     * Fetches data for a given node and returns it as a Promise.
     * This is a convenience wrapper around the `data` method for use with async/await.
     *
     * Note: This promise resolves with the *first* available data, which could be from the SSR cache or the network.
     * It may not provide the most up-to-date data if a network fetch is in progress.
     *
     * Note: This method is only for migration purposes. Use {@link getData} in new code instead.
     *
     * @private
     * @deprecated Don't use this method, use {@link getData} method instead.
     *             This method is only for migration purposes.
     *
     * @param node The node (or its ProseMirror representation) for which to fetch data.
     * @returns A promise that resolves with the node's data.
     */
    getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS(node: Node | PMNode): Promise<Data>;
    /**
     * Checks the cache for the given node and returns its status.
     *
     * Possible return values:
     * - `false`: No cached data found for the node.
     * - `'ssr'`: Data is cached from server-side rendering (SSR).
     * - `'network'`: Data is cached from a network request.
     *
     * @param node The node (or its ProseMirror representation) to check in the cache.
     * @returns The cache status: `false`, `'ssr'`, or `'network'`.
     */
    getCacheStatusForNode(node: Node | PMNode): false | 'ssr' | 'network';
    /**
     * Retrieves the cached data for a given node, if available.
     *
     * @param node The node (or its ProseMirror representation) for which to retrieve cached data.
     * @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
     */
    getNodeDataFromCache(node: JSONNode | PMNode): CacheData<Data>[string] | undefined;
    /**
     * Returns the keys of the cache.
     *
     * @returns An array of the keys of the cache.
     */
    getNodeDataCacheKeys(): string[];
    /**
     * Updates the cache with new records using merge or replace strategies.
     * This method should be the only way to modify the cache directly.
     * This allow subclasses to use it when needed. e.g. abstract fetchNodesData implementation.
     *
     * @example
     * ```
     * const newRecords = {
     *   'node-id-1': { value: 'updated data' },
     *   'node-id-3': { value: 'new data' }
     * };
     * nodeDataProvider.updateCache(newRecords, { strategy: 'merge', source: 'network' });
     * ```
     *
     * Supports two strategies:
     * - 'merge' (default): Merges new records into the existing cache.
     * - 'replace': Replaces the entire cache with the new records, invalidating any in-flight requests.
     *
     * @param records A map of node data keys to their corresponding data.
     * @param options Optional settings for the update operation.
     * @param options.strategy The strategy to use for updating the cache ('merge' or 'replace'). Defaults to 'merge'.
     * @param options.source The source of the data being added ('ssr' or 'network'). Defaults to 'network'.
     */
    updateCache(records?: CacheRecords<Data>, options?: {
        source?: 'ssr' | 'network';
        strategy?: 'merge' | 'replace';
    }): void;
    /**
     * Removes one or more entries from the cache.
     *
     * @param keys A single data key or array of data keys to remove from the cache.
     */
    removeFromCache(keys: string[]): void;
}
export {};
