import type { Constructor, Primary, Ref } from '../typings.js';
import { Collection, type InitCollectionOptions, type LoadCountOptions } from '../entity/Collection.js';
import { type EntityManager } from '../EntityManager.js';
import { type LoadReferenceOptions } from '../entity/Reference.js';
type BatchLoadFn<K, V> = (keys: readonly K[]) => PromiseLike<ArrayLike<V | Error>>;
export declare class DataloaderUtils {
    private static DataLoader?;
    /**
     * Groups identified references by entity and returns a Map with the
     * class name as the index and the corresponding primary keys as the value.
     */
    static groupPrimaryKeysByEntityAndOpts(refsWithOpts: readonly [Ref<any>, Omit<LoadReferenceOptions<any, any>, 'dataloader'>?][]): Map<string, Set<Primary<any>>>;
    /**
     * Returns the reference dataloader batchLoadFn, which aggregates references by entity,
     * makes one query per entity and maps each input reference to the corresponding result.
     */
    static getRefBatchLoadFn(em: EntityManager): BatchLoadFn<[Ref<any>, Omit<LoadReferenceOptions<any, any>, 'dataloader'>?], any>;
    /**
     * Groups collections by entity and returns a Map whose keys are the entity names and whose values are filter Maps
     * which we can use to narrow down the find query to return just the items of the collections that have been dataloaded.
     * The entries of the filter Map will be used as the values of an $or operator so we end up with a query per entity.
     */
    static groupInversedOrMappedKeysByEntityAndOpts(collsWithOpts: readonly [Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?][]): Map<string, Map<string, Set<Primary<any>>>>;
    /**
     * Turn the entity+options map into actual queries.
     * The keys are the entity names + a stringified version of the options and the values are filter Maps which will be used as the values of an $or operator so we end up with a query per entity+opts.
     * We must populate the inverse side of the relationship in order to be able to later retrieve the PK(s) from its item(s).
     * Together with the query the promises will also return the key which can be used to narrow down the results pertaining to a certain set of options.
     */
    static entitiesAndOptsMapToQueries(entitiesAndOptsMap: Map<string, Map<string, Set<Primary<any>>>>, em: EntityManager): Promise<[string, any[]]>[];
    /**
     * Creates a filter which returns the results pertaining to a certain collection.
     * First checks if the Entity type matches, then retrieves the inverse side of the relationship
     * where the filtering will be done in order to match the target collection.
     */
    static getColFilter<T, S extends T>(collection: Collection<any>): (result: T) => result is S;
    /**
     * Returns the 1:M collection dataloader batchLoadFn, which aggregates collections by entity,
     * makes one query per entity and maps each input collection to the corresponding result.
     */
    static getColBatchLoadFn(em: EntityManager): BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
    /**
     * Returns the M:N collection dataloader batchLoadFn, which aggregates collections by entity,
     * makes one query per entity and maps each input collection to the corresponding result.
     */
    static getManyToManyColBatchLoadFn(em: EntityManager): BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
    /**
     * Returns the count dataloader batchLoadFn, which aggregates `Collection.loadCount()` calls
     * by entity and relation, issues a single grouped count query per entity+options combination
     * via `em.countBy()`, and maps each input collection to the corresponding count.
     *
     * For 1:M relations, groups by the FK property on the target entity.
     * For M:N relations, groups by the owner FK on the pivot entity.
     */
    static getCountBatchLoadFn(em: EntityManager): BatchLoadFn<[Collection<any>, Omit<LoadCountOptions<any>, 'dataloader' | 'refresh'>?], number>;
    static getDataLoader(): Promise<Constructor<{
        load: (...args: unknown[]) => Promise<unknown>;
    }>>;
}
export {};
