Skip to main content
The factory() function is a convenience method that creates a loader function with a stable reference to your LoadFn. This eliminates the need to pass the loader function on every call.

Signature

function factory<T, K = string>(
  loadFn: LoadFn<T, K>
): (key: K, identity?: string | undefined) => Promise<T>

Parameters

loadFn
LoadFn<T, K>
required
A loader function that accepts an array of keys and returns a Promise of values or errors.
type LoadFn<T, K = string> = (keys: K[]) => Promise<(T | Error)[]>
The loader function must provide a value for each key in the given set of keys. Even if this value is an error, it must be provided.

Returns

load function
(key: K, identity?: string) => Promise<T>
A bound function that accepts a key and optional identity, and returns a Promise that resolves to the loaded value.The returned function has the following signature:
(key: K, identity?: string | undefined) => Promise<T>

Why Use Factory?

Instead of passing the loader function every time you call load(), factory() creates a bound function with the loader already attached. This provides:
  • Cleaner API: No need to pass the loader on every call
  • Stable Reference: The loader reference is maintained internally
  • Better DX: More ergonomic for repeated use throughout your application

Basic Example

import { factory } from 'dldr';

const load = factory(async function loader(keys: string[]) {
  return keys.map(key => 'foo' + key);
});

const values = await Promise.all([
  load('bar'),
  load('bar'),
  load('baz'),
]);

console.log(values); // ['foobar', 'foobar', 'foobaz']

Database Example

import { factory } from 'dldr';

const loadPost = factory((keys: string[]) => 
  sql`SELECT id, name FROM posts WHERE id IN (${keys})`
);

const posts = await Promise.all([
  loadPost('123'),
  loadPost('123'),
  loadPost('456'),
]);

// SQL query is called once with ['123', '456']

GraphQL Resolver Example

import { factory } from 'dldr';
import { buildSchema, graphql } from 'graphql';

const schema = buildSchema(`
  type Query {
    me(name: String!): String!
  }
`);

const operation = `{
  a: me(name: "John")
  b: me(name: "Jane")
}`;

const results = await graphql({
  schema,
  source: operation,
  contextValue: {
    getUser: factory(async (names) => {
      // Call your database or API
      const result = names.map((name) => name);
      return result;
    }),
  },
  rootValue: {
    me: ({ name }, ctx) => {
      return ctx.getUser(name);
    },
  },
});

Comparison with load()

import { factory } from 'dldr';

const loadUser = factory(getUsers);

await loadUser('123');
await loadUser('456');
Both approaches work identically under the hood, but factory() provides a cleaner API when you need to call the loader multiple times.

Build docs developers (and LLMs) love