( filePath: string, parts: readonly FeedbackUploadPart[], totalBytes: number, options: UploadArchiveOptions, )
| 93 | } |
| 94 | |
| 95 | async function uploadParts( |
| 96 | filePath: string, |
| 97 | parts: readonly FeedbackUploadPart[], |
| 98 | totalBytes: number, |
| 99 | options: UploadArchiveOptions, |
| 100 | ): Promise<CompletedUploadPart[]> { |
| 101 | const layout = layoutParts(parts); |
| 102 | const results: CompletedUploadPart[] = Array.from({ length: layout.length }); |
| 103 | const concurrency = Math.max(1, Math.min(options.concurrency ?? DEFAULT_CONCURRENCY, layout.length)); |
| 104 | let nextIndex = 0; |
| 105 | let uploadedBytes = 0; |
| 106 | |
| 107 | async function worker(): Promise<void> { |
| 108 | while (true) { |
| 109 | const index = nextIndex; |
| 110 | nextIndex += 1; |
| 111 | if (index >= layout.length) return; |
| 112 | const entry = layout[index]; |
| 113 | if (entry === undefined) return; |
| 114 | const completed = await uploadOnePartWithRetry(filePath, entry, options); |
| 115 | results[index] = completed; |
| 116 | uploadedBytes += entry.part.size; |
| 117 | options.onProgress?.(uploadedBytes, totalBytes); |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | await Promise.all(Array.from({ length: concurrency }, () => worker())); |
| 122 | return results; |
| 123 | } |
| 124 | |
| 125 | async function uploadOnePartWithRetry( |
| 126 | filePath: string, |
no test coverage detected