UNPKG

@ugo-code/streamline.js

Version:

A utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript

54 lines (53 loc) 2.46 kB
/** * A serializable value that can be used as a key. It can be a primitive, * a plain object, or an array that can be safely stringified with JSON. */ type SerializableKey = unknown; /** * Ensures that an asynchronous task is only executed once at a time for a given key. * * If this function is called while a task with the same key is already running, * it will return the promise of the existing task instead of starting a new one. * This is useful for preventing duplicate network requests or other expensive * operations. Once a task is complete (either resolves or rejects), its promise is * removed, and the next call with the same key will trigger a new execution. * * @template TResult The expected result type of the asynchronous task. * @param {() => Promise<TResult>} taskFn The asynchronous function to execute. * @param {SerializableKey} [key] An optional unique identifier for the task. * If it's an object or array, it will be JSON-stringified and hashed. * If not provided, the task function's source code (`taskFn.toString()`) is * hashed to generate a key. Note that this may not be unique for different * function instances with identical source code. * @returns {Promise<TResult>} A promise that resolves or rejects with the result of the task. * @example * ```ts * // Example 1: Basic deduplication with a string key * async function fetchUser(userId: string) { * // This function will only be executed once, even if called multiple times in parallel. * return singleExecution( * () => { * console.log(`Fetching user ${userId}...`); * return api.fetch(`/users/${userId}`); * }, * `user-${userId}` // A simple, descriptive key * ); * } * * Promise.all([fetchUser('123'), fetchUser('123')]); // "Fetching user 123..." is logged only once. * * // Example 2: Using an object as a key * async function searchProducts(filters: object) { * return singleExecution( * () => api.post('/products/search', filters), * filters // The filters object is hashed to create a unique key * ); * } * * // Example 3: No key provided (hashes the function's source) * const fetchConfig = () => singleExecution(() => api.fetch('/config')); * Promise.all([fetchConfig(), fetchConfig()]); // The config is fetched only once. * ``` */ export declare function singleExecution<TResult>(taskFn: () => Promise<TResult>, key?: SerializableKey): Promise<TResult>; export {};