import DataLoader from 'dataloader'; import type { ModelDefinition } from './types'; import type { RelationKey } from './batch-load-config'; export { getBatchLoadConfig, batchLoadBelongsTo, batchLoadHasOne, batchLoadHasMany, batchLoadHasManyThrough, } from './batch-load-config'; export type { RelationKey, BatchLoadConfig } from './batch-load-config'; /** * Query executor function type */ export type QueryExecutor = (query: { text: string; values: unknown[]; }) => Promise[]>; /** * Normalize a relation key to a string. * * Grouping and lookup MUST go through this: a parent row's `id` of `1` (number) * has to match a child row's `user_id` of `1`, and `Map` uses SameValueZero, so * `1` and `'1'` would otherwise be distinct buckets. */ export declare function normalizeKey(value: unknown): string; /** * Group array items by a key. * * Keys are normalized to strings so numeric and string representations of the * same id land in the same bucket. * * @param items - Array of items to group * @param key - Key to group by * @returns Map of stringified key -> items */ export declare function groupByKey>(items: T[], key: string): Map; /** * Create a DataLoader for a relation * * Use this when relation loads originate from independent call sites (GraphQL * resolvers, for instance) that must coalesce into one query, or when the * per-key cache is worth keeping for the length of a request. When every key is * already known upfront, prefer `loadRelation()` — it skips DataLoader. * * @param model - Model definition * @param relationName - Name of the relation * @param executor - Function to execute queries * @returns DataLoader instance * * @example * ```typescript * const postsLoader = createRelationLoader(League, 'posts', async (query) => { * return db.query(query.text, query.values); * }); * * // Will batch multiple loads into single query * const posts1 = await postsLoader.load('league-1'); * const posts2 = await postsLoader.load('league-2'); * ``` */ export declare function createRelationLoader(model: ModelDefinition, relationName: string, executor: QueryExecutor): DataLoader[]>; /** * Create loaders for all relations of a model * * @param model - Model definition * @param executor - Query executor function * @returns Map of relation name -> DataLoader */ export declare function createAllRelationLoaders(model: ModelDefinition, executor: QueryExecutor): Map[]>>; /** * Load relations for a set of records * * Pass an existing `loader` to reuse its cache across several `loadRelation` * calls in the same request. Without one, DataLoader is skipped entirely — * every key is already known here, so its tick scheduling and per-key promises * would be pure overhead. * * A failing executor rejects rather than yielding empty relations, so a dead * connection can never masquerade as "this parent has no children". * * @param records - Parent records * @param model - Parent model definition * @param relationName - Relation to load * @param executor - Query executor * @param loader - Optional pre-built loader to reuse * @returns Records with loaded relations */ export declare function loadRelation>(records: T[], model: ModelDefinition, relationName: string, executor: QueryExecutor, loader?: DataLoader[]>): Promise; //# sourceMappingURL=loader.d.ts.map