MCPcopy Create free account
hub / github.com/ProtonDriveApps/sdk / asyncIteratorMap

Function asyncIteratorMap

client/js/src/internal/asyncIteratorMap.ts:21–72  ·  view source on GitHub ↗
(
    inputIterator: AsyncGenerator<I>,
    mapper: (item: I) => Promise<O>,
    concurrency: number = DEFAULT_CONCURRENCY,
    signal?: AbortSignal,
)

Source from the content-addressed store, hash-verified

19 * @param concurrency - The concurrency limit. How many parallel async mapper calls are allowed.
20 * @returns An async iterator that yields the mapped values.
21 */
22export async function* asyncIteratorMap<I, O>(
23 inputIterator: AsyncGenerator<I>,
24 mapper: (item: I) => Promise<O>,
25 concurrency: number = DEFAULT_CONCURRENCY,
26 signal?: AbortSignal,
27): AsyncGenerator<O> {
28 let done = false;
29 let hasInputError = false;
30 let inputError: unknown | undefined;
31
32 const executing = new Set<Promise<void>>();
33 const results: Array<Promise<O>> = [];
34
35 const pump = async () => {
36 let next;
37 try {
38 next = await inputIterator.next();
39 } catch (error) {
40 hasInputError = true;
41 inputError = error;
42 done = true;
43 return;
44 }
45
46 if (next.done) {
47 done = true;
48 return;
49 }
50
51 const promise = mapper(next.value)
52 .then((result) => {
53 results.push(Promise.resolve(result));
54 })
55 .catch((error) => {
56 results.push(Promise.reject(error));
57 });
58 executing.add(promise);
59 void promise.finally(() => executing.delete(promise));
60 };
61
62 while (!done || executing.size > 0 || results.length > 0) {
63 if (signal?.aborted) {
64 throw new AbortError(c('Error').t`Operation aborted`);
65 }
66 while (!done && executing.size < concurrency) {
67 await pump();
68 }
69
70 if (results.length > 0) {
71 yield await results.shift()!;
72 } else if (executing.size > 0) {
73 // Wait for at least one task to complete
74 await Promise.race(Array.from(executing));
75 }

Callers 2

Calls 1

pumpFunction · 0.85

Tested by

no test coverage detected