Skip to content

Commit a44fb87

Browse files
author
Andrei Bratu
authored
Merge pull request #16 from humanloop/pmap
pMap docstring + error catching
2 parents cd01ac2 + bea162c commit a44fb87

File tree

3 files changed

+51
-11
lines changed

3 files changed

+51
-11
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "humanloop",
3-
"version": "0.8.14-beta5",
3+
"version": "0.8.15",
44
"private": false,
55
"repository": "https://github.com/humanloop/humanloop-node",
66
"main": "./index.js",

src/eval_utils/run.ts

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,57 @@ const GREEN = "\x1b[92m";
4646
const RED = "\x1b[91m";
4747
const RESET = "\x1b[0m";
4848

49+
/**
50+
* Maps over an array of items with a concurrency limit, applying an asynchronous mapper function to each item.
51+
*
52+
* @template T - The type of the items in the input array.
53+
* @template O - The type of the items in the output array.
54+
*
55+
* @param {T[]} iterable - The array of items to be mapped.
56+
* @param {(item: T) => Promise<O>} mapper - The asynchronous function to apply to each item.
57+
* @param {{ concurrency: number }} options - Options for the mapping operation.
58+
* @param {number} options.concurrency - The maximum number of promises to resolve concurrently.
59+
*
60+
* @returns {Promise<O[]>} A promise that resolves to an array of mapped items.
61+
*
62+
* @throws {TypeError} If the first argument is not an array.
63+
* @throws {TypeError} If the second argument is not a function.
64+
* @throws {TypeError} If the concurrency option is not a positive number.
65+
*
66+
* @description
67+
* The `pMap` function processes the input array in chunks, where the size of each chunk is determined by the `concurrency` option.
68+
* This controls how many promises are resolved at a time, which can help avoid issues such as rate limit errors when making server requests.
69+
*/
4970
async function pMap<T, O>(
50-
iterable: Array<T>,
51-
mapper: (obj: T) => Promise<O>,
52-
{ concurrency }: { concurrency: number },
53-
): Promise<Array<O>> {
54-
const result: Array<O> = [];
55-
result: for (let i = 0; i < iterable.length; i += concurrency) {
71+
iterable: T[],
72+
mapper: (item: T) => Promise<O>,
73+
options: { concurrency: number },
74+
): Promise<O[]> {
75+
const { concurrency } = options;
76+
77+
if (!Array.isArray(iterable)) {
78+
throw new TypeError("Expected the first argument to be an array");
79+
}
80+
81+
if (typeof mapper !== "function") {
82+
throw new TypeError("Expected the second argument to be a function");
83+
}
84+
85+
if (typeof concurrency !== "number" || concurrency <= 0) {
86+
throw new TypeError("Expected the concurrency option to be a positive number");
87+
}
88+
89+
const result: O[] = [];
90+
for (let i = 0; i < iterable.length; i += concurrency) {
5691
const chunk = iterable.slice(i, i + concurrency);
57-
const promises = chunk.map(mapper);
58-
const awaitedChunk = await Promise.all(promises);
59-
result.push(...awaitedChunk);
92+
try {
93+
const chunkResults = await Promise.all(chunk.map(mapper));
94+
result.push(...chunkResults);
95+
} catch (error) {
96+
// Handle individual chunk errors if necessary
97+
// For now, rethrow to reject the entire pMap promise
98+
throw error;
99+
}
60100
}
61101
return result;
62102
}

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const SDK_VERSION = "0.8.14-beta5";
1+
export const SDK_VERSION = "0.8.15";

0 commit comments

Comments
 (0)