( items: T[], limit: number, worker: (item: T, index: number) => Promise<R> )
| 88 | * partial failures explicitly. |
| 89 | */ |
| 90 | export const runWithConcurrency = async <T, R>( |
| 91 | items: T[], |
| 92 | limit: number, |
| 93 | worker: (item: T, index: number) => Promise<R> |
| 94 | ): Promise<Array<PromiseSettledResult<R>>> => { |
| 95 | const results: Array<PromiseSettledResult<R>> = Array(items.length) |
| 96 | if (items.length === 0) return results |
| 97 | |
| 98 | const concurrency = Math.max(1, Math.min(limit, items.length)) |
| 99 | let nextIndex = 0 |
| 100 | |
| 101 | const runners = Array.from({ length: concurrency }, async () => { |
| 102 | while (true) { |
| 103 | const currentIndex = nextIndex++ |
| 104 | if (currentIndex >= items.length) break |
| 105 | try { |
| 106 | const value = await worker(items[currentIndex], currentIndex) |
| 107 | results[currentIndex] = { status: 'fulfilled', value } |
| 108 | } catch (error) { |
| 109 | results[currentIndex] = { status: 'rejected', reason: error } |
| 110 | } |
| 111 | } |
| 112 | }) |
| 113 | |
| 114 | await Promise.all(runners) |
| 115 | return results |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * Normalize a presigned-upload server response into a {@link PresignedUploadInfo}. |
no test coverage detected