import { Omit } from "@intelligentgraphics/ig.utilities";
export interface GenericResourceCacheResource<T = any, P extends GenericResourceCacheBaseResourceParams = GenericResourceCacheBaseResourceParams> {
    /**
     * Cache identifier of this resource
     *
     * @type {string}
     */
    identifier: string;
    /**
     * All component ids that are using this resources
     *
     * @type {string[]}
     */
    users: string[];
    owner?: string;
    /**
     * All resources that are used by this resource
     *
     * @type {string[]}
     */
    dependencies?: string[];
    data: T;
    params: Omit<P, keyof GenericResourceCacheBaseResourceParams>;
}
export interface GenericResourceCacheBaseResourceParams {
    dependencies?: string[];
    owner?: string;
}
export interface GeometryResourceParams extends GenericResourceCacheBaseResourceParams {
    name: string;
    url: string;
    hash: string | undefined;
}
declare type CustomParams<T extends GenericResourceCacheBaseResourceParams> = Omit<T, keyof GenericResourceCacheBaseResourceParams>;
export interface GenericResourceCacheResourceDefinition<P extends GenericResourceCacheBaseResourceParams, T> {
    createResourceIdentifier(params: P): string;
    isResourceValid(newParams: CustomParams<P>, previousParams: CustomParams<P>): boolean;
    onResourceAdded?(resource: GenericResourceCacheResource<T, P>): void;
    onResourceRemoved?(resoruce: GenericResourceCacheResource<T, P>): void;
}
export declare class GenericResourceCache<P extends GenericResourceCacheBaseResourceParams, T> {
    private readonly resourceDefinition;
    private resources;
    private fetchPromises;
    constructor(resourceDefinition: GenericResourceCacheResourceDefinition<P, T>);
    /**
     * Fetches a resource when it's not yet available or retrieves the existing resource from cache. Keeps track of inflight fetches and prevents multiple fetches
     * for the same resource.
     *
     * Adds the specified component id to the users of the target resource
     *
     * @param {string} componentId
     * @param {P} params
     * @param {(params: P) => Promise<T>} fetchResource
     * @returns {Promise<GenericResourceCacheResource<T>>}
     */
    ensureResource(params: P, fetchResource: (params: P) => Promise<T>): Promise<GenericResourceCacheResource<T, P>>;
    /**
     * Determines wether the specified resource is currently being loaded
     *
     * @param {P} params
     * @returns {boolean}
     */
    isResourceFetching(params: P): boolean;
    findResource(cb: (resource: GenericResourceCacheResource<T, P>) => boolean): GenericResourceCacheResource<T, P> | undefined;
    getAllResources(): GenericResourceCacheResource<T, P>[];
    /**
     * Retrieves the registered resource for the provided parameters
     *
     * @param {P} params
     * @returns {(GenericResourceCacheResource<T> | undefined)}
     */
    getResource(params: P): GenericResourceCacheResource<T, P> | undefined;
    getResourceByIdentifier(identifier: string): GenericResourceCacheResource<T, P> | undefined;
    getResourcesByUser(componentId: string): GenericResourceCacheResource<T, P>[];
    /**
     * Retrieves all resources that are fully or partially owned by the provided component
     *
     * @param {string} componentId
     * @returns {GenericResourceCacheResource<T, P>[]}
     */
    getResourcesByOwner(componentId: string): GenericResourceCacheResource<T, P>[];
    /**
     * Registers a new resource.
     * Overrides existing resources
     *
     * @param {P} params
     * @param {T} data
     * @returns {GenericResourceCacheResource<T>}
     */
    addResource(params: P, data: T): GenericResourceCacheResource<T, P>;
    /**
     * Adds a user for the specified resource, if it's not yet registered as a user
     *
     * @param {string} identifier
     * @param {string} componentId
     */
    addResourceUser(identifier: string, componentId: string): void;
    /**
     * Removes a user from the specified resource
     *
     * @param {string} identifier
     * @param {string} componentId
     * @returns {void}
     */
    removeResourceUser(identifier: string, componentId: string): void;
    /**
     *  Checks wether a resource exists
     *
     * @param {P} params
     * @returns {boolean}
     */
    hasResource(params: P): boolean;
    /**
     * Removes a resource
     *
     * @param {P} params
     */
    removeResource(identifier: string): void;
    /**
     * Removes all resources (also dependency resources) that are only used by this component or children of this component
     *
     * @param {string} componentId
     */
    cleanupResources(componentId: string): void;
    private createResourceName;
    private dropResourceByKey;
}
export {};
