@mavenoid/dataloader
Utilities for caching, batching and deduping requests in GraphQL. Inspired by dataloader but extended using WeakMap to create a more convenient API for GraphQL

Installation
yarn add @mavenoid/dataloader
Usage
import {
getDataLoadersForContextType,
RequestsBatch,
} from '@mavenoid/dataloader';
const {batch, dedupe} = getDataLoadersForContextType<ResolverContextType>();
const getUserDeduped = dedupe(
async (userID: number, _resolverContext: ResolverContextType) => {
return await getUserUncached(userID);
},
);
const getUserBatched = batch(
async (userIDs: number[], _resolverContext: ResolverContextType) => {
const users = await db_users.find({id: anyOf(userIDs)}).all();
return new Map(users.map((user) => [user.id, user]));
},
{maxBatchSize: 100},
);
Handling undefined
The batch methods return undefined for any requested records that are not included in the results. If this is not what you want, you can add a fallback using:
import {
handleUndefinedResult,
errorOnUndefinedResult,
} from '@mavenoid/dataloader';
const getUserOrNull = handleUndefinedResult(getUserBatched, () => null);
const getUserOrError = errorOnUndefinedResult(
getUserBatched,
(id) => `Could not find user: ${id}`,
);
Handling requests for lists of dependent records
The groupRecordsByKey can be used to group a list of records by a foreign key. It will preserve the order of the records within each group.
const getUserMessagesBatched = handleUndefinedResult(
batch(
async (userIDs: number[], _resolverContext: ResolverContextType) => {
const messages = await db_messages
.find({sender_id: anyOf(userIDs)})
.all();
return groupRecordsByKey(messages, (m) => m.sender_id);
},
{maxBatchSize: 100},
),
() => [],
);