{"id":10752,"library":"dldr","title":"dldr: Batching and Caching Utility","description":"dldr (pronounced \"dataloader\") is a minimalist JavaScript utility, currently at version 0.0.10, designed for efficiently batching and caching operations. It is particularly useful in data fetching scenarios, such as optimizing queries within GraphQL resolvers. The library distinguishes itself by its extremely small footprint (367B gzipped) and its use of `queueMicrotask` to schedule and execute batched load functions within the current event loop tick. This mechanism ensures that multiple requests for the same or different keys, made in quick succession within the same microtask queue, are consolidated into a single call to the underlying data fetching function. dldr offers both a basic batching mechanism and an extended version accessible via `dldr/cache` that incorporates an in-memory `Map`-based cache, preventing redundant data fetches for previously loaded keys. Its primary goal is to improve performance by reducing the number of requests to databases or APIs, positioning it as a lightweight alternative to more feature-rich dataloading solutions. While in early development, its API is straightforward, centered around `load` functions that accept an array of keys and return corresponding results.","status":"active","version":"0.0.10","language":"javascript","source_language":"en","source_url":"https://github.com/maraisr/dldr","tags":["javascript","dataloader","batch","graphql","utility","typescript"],"install":[{"cmd":"npm install dldr","lang":"bash","label":"npm"},{"cmd":"yarn add dldr","lang":"bash","label":"yarn"},{"cmd":"pnpm add dldr","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the primary named export for batching operations. It processes all queued calls within the current microtask.","wrong":"const load = require('dldr').load;","symbol":"load","correct":"import { load } from 'dldr';"},{"note":"This variant of the `load` function includes an in-memory cache. It accepts an optional `Map` instance for caching results by key, preventing redundant fetches for already loaded data.","wrong":"const load = require('dldr/cache').load;","symbol":"load","correct":"import { load } from 'dldr/cache';"}],"quickstart":{"code":"import { load } from 'dldr';\n\n// Mock a simple database interaction\nconst mockDb = {\n  posts: new Map([\n    ['123', { id: '123', name: 'Post One' }],\n    ['456', { id: '456', name: 'Post Two' }],\n    ['789', { id: '789', name: 'Post Three' }]\n  ]),\n  // Simulates a database call that takes an array of keys\n  execute: async (query: string, keys: string[]): Promise<Array<{ id: string, name: string }>> => {\n    console.log(`[DB] Executing query for keys: ${keys.join(', ')}`);\n    // Simulate network delay\n    await new Promise(resolve => setTimeout(resolve, 50));\n    return keys.map(key => mockDb.posts.get(key) || { id: key, name: 'Unknown Post' });\n  }\n};\n\n// Define the core data loading function that dldr will batch\nconst getPosts = async (keys: string[]): Promise<Array<{ id: string, name: string }>> => {\n  // In a real application, this would be a single database call\n  // that fetches multiple records based on the provided keys.\n  return mockDb.execute('SELECT id, name FROM posts WHERE id IN (?)', keys);\n};\n\nasync function main() {\n  console.log('Demonstrating batching with dldr:\\n');\n\n  // Request multiple posts concurrently. dldr will batch these into a single call to `getPosts`.\n  const post123Promise = load(getPosts, '123');\n  const post456Promise = load(getPosts, '456');\n\n  // Even if requested again, it's still part of the same batch operation if in the same tick.\n  const post123AgainPromise = load(getPosts, '123');\n\n  // Add another request later in the same event loop tick (e.g., from another resolver)\n  // This will still be part of the initial batch\n  await Promise.resolve(); // Ensures other microtasks run, still within the same tick conceptually\n  const post789Promise = load(getPosts, '789');\n\n  const loadedPosts = await Promise.all([\n    post123Promise,\n    post123AgainPromise,\n    post456Promise,\n    post789Promise\n  ]);\n\n  console.log('\\nResults from batched load:');\n  console.log(loadedPosts);\n\n  console.log('\\nDemonstrating `load.bind` for convenience:');\n  const loadPost = load.bind(null, getPosts);\n  const boundPostPromise = loadPost('123');\n  const anotherBoundPostPromise = loadPost('456');\n  const boundLoadedPosts = await Promise.all([boundPostPromise, anotherBoundPostPromise]);\n  console.log(boundLoadedPosts);\n}\n\nmain().catch(console.error);","lang":"typescript","description":"This example demonstrates how to use `dldr` to batch multiple data fetching calls into a single underlying function execution and shows the `load.bind` pattern for convenience."},"warnings":[{"fix":"Ensure all batchable `load` calls are initiated within the same synchronous execution context or within the same microtask queue phase.","message":"dldr batches operations within the current microtask queue. Requests made across different event loop ticks (e.g., separated by `setTimeout` or `setImmediate` calls without an intervening microtask) will not be batched together, leading to multiple calls to your underlying `loadFn`.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Pin to exact versions (`\"dldr\": \"0.0.10\"`) and carefully review the GitHub repository for changes when upgrading, particularly if new versions are released.","message":"As dldr is in an early development stage (version 0.0.10), its API surface may undergo changes without adhering to strict semantic versioning. Early minor or patch releases could potentially introduce breaking changes.","severity":"breaking","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the first argument to `load` (your data fetching function) is a valid, callable function that accepts an array of keys.","cause":"The first argument passed to `load` was not a function, or was null/undefined.","error":"TypeError: loadFn is not a function"},{"fix":"Verify that `import { load } from 'dldr';` or `import { load } from 'dldr/cache';` is correctly specified and executed before calling `load.bind`.","cause":"Attempting to use `load.bind` when `load` itself is not correctly imported or is undefined.","error":"TypeError: Cannot read properties of undefined (reading 'bind')"}],"ecosystem":"npm"}