@backblaze-labs/b2-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
@@ -1,198 +1,322 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const hash = require("../streams/hash.cjs");
4
- const progress = require("../streams/progress.cjs");
5
- const defaults = require("../util/defaults.cjs");
6
- const toError = require("../util/to-error.cjs");
7
- const cancel = require("./cancel.cjs");
8
- const concurrency = require("./concurrency.cjs");
1
+ const require_abort_scope = require("./abort-scope.cjs");
2
+ const require_cancel = require("./cancel.cjs");
3
+ const require_concurrency = require("./concurrency.cjs");
4
+ const require_finish = require("./finish.cjs");
5
+ require("../util/defaults.cjs");
6
+ const require_progress = require("../streams/progress.cjs");
7
+ const require_hash = require("../streams/hash.cjs");
8
+ const require_retry = require("./retry.cjs");
9
+ const require_to_error = require("../util/to-error.cjs");
10
+ //#region src/upload/stream.ts
11
+ /**
12
+ * Creates a {@link WritableStream} that streams data into a B2 multipart upload.
13
+ *
14
+ * Buffers incoming chunks until `partSize` bytes are accumulated, ships each
15
+ * complete part through the standard multipart engine, and finalizes the file
16
+ * once the stream is closed. Honours backpressure via the queue's bounded
17
+ * concurrency. Streaming uploads do not support resume because the total size
18
+ * and per-part hashes aren't known in advance; use {@link uploadLargeFile} with
19
+ * a buffered source when resume is required.
20
+ *
21
+ * @param raw - Low-level B2 API client.
22
+ * @param accountInfo - Authorized account state (tokens, URLs, part URL pool).
23
+ * @param options - Streaming upload parameters.
24
+ *
25
+ * @returns A {@link UploadWriteHandle} with the writable sink and a completion promise.
26
+ */
9
27
  function createWriteStream(raw, accountInfo, options) {
10
- const minPartSize = accountInfo.getAbsoluteMinimumPartSize();
11
- const recommendedPartSize = accountInfo.getRecommendedPartSize();
12
- const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize);
13
- const concurrency$1 = options.concurrency ?? defaults.DEFAULT_TRANSFER_CONCURRENCY;
14
- const tracker = new progress.ProgressTracker(options.onProgress, null, null);
15
- const sem = new concurrency.Semaphore(concurrency$1);
16
- let largeFileId = null;
17
- let startPromise = null;
18
- let nextPartNumber = 1;
19
- let pendingBytes = 0;
20
- const pending = [];
21
- const partSha1s = [];
22
- const inflight = [];
23
- let errored = null;
24
- const {
25
- promise: done,
26
- resolve: resolveDone,
27
- reject: rejectDone
28
- } = Promise.withResolvers();
29
- done.catch(() => {
30
- });
31
- function ensureStarted() {
32
- if (largeFileId !== null) return Promise.resolve(largeFileId);
33
- if (startPromise !== null) return startPromise;
34
- startPromise = (async () => {
35
- const resp = await raw.startLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
36
- bucketId: options.bucketId,
37
- fileName: options.fileName,
38
- contentType: options.contentType ?? defaults.DEFAULT_CONTENT_TYPE,
39
- fileInfo: options.fileInfo ?? {},
40
- ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
41
- });
42
- largeFileId = resp.fileId;
43
- return largeFileId;
44
- })();
45
- return startPromise;
46
- }
47
- async function shipPart(data, partNumber) {
48
- const fileId = await ensureStarted();
49
- const sha1 = new hash.IncrementalSha1();
50
- await sha1.update(data);
51
- const sha1Hex = await sha1.digest();
52
- let uploadEntry = accountInfo.checkoutPartUploadUrl(fileId);
53
- if (!uploadEntry) {
54
- const resp = await raw.getUploadPartUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
55
- fileId
56
- });
57
- uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken };
58
- }
59
- try {
60
- const result = await raw.uploadPart(
61
- uploadEntry.uploadUrl,
62
- {
63
- authorization: uploadEntry.authorizationToken,
64
- partNumber,
65
- contentLength: data.byteLength,
66
- contentSha1: sha1Hex,
67
- ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
68
- },
69
- data,
70
- options.signal
71
- );
72
- accountInfo.returnPartUploadUrl(fileId, uploadEntry);
73
- partSha1s[partNumber - 1] = result.contentSha1;
74
- tracker.addBytes(data.byteLength);
75
- tracker.completePart();
76
- } catch (err) {
77
- accountInfo.evictPartUploadUrl(fileId, uploadEntry);
78
- throw err;
79
- }
80
- }
81
- function dispatchPart() {
82
- if (pending.length === 0) return;
83
- let data;
84
- if (pending.length === 1) {
85
- const head = pending[0];
86
- if (!head) return;
87
- data = head;
88
- } else {
89
- const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0);
90
- data = new Uint8Array(total);
91
- let offset = 0;
92
- for (const chunk of pending) {
93
- data.set(chunk, offset);
94
- offset += chunk.byteLength;
95
- }
96
- }
97
- pending.length = 0;
98
- pendingBytes = 0;
99
- const partNumber = nextPartNumber++;
100
- const task = (async () => {
101
- await sem.acquire();
102
- try {
103
- await shipPart(data, partNumber);
104
- } catch (err) {
105
- errored = toError.toError(err);
106
- throw err;
107
- } finally {
108
- sem.release();
109
- }
110
- })();
111
- inflight.push(task);
112
- task.catch(() => {
113
- });
114
- }
115
- const writable = new WritableStream({
116
- async write(chunk) {
117
- if (errored) throw errored;
118
- options.signal?.throwIfAborted();
119
- pending.push(chunk);
120
- pendingBytes += chunk.byteLength;
121
- while (pendingBytes >= partSize) {
122
- const carved = carveExact(pending, partSize);
123
- const partNumber = nextPartNumber++;
124
- pendingBytes -= partSize;
125
- const task = (async () => {
126
- await sem.acquire();
127
- try {
128
- await shipPart(carved, partNumber);
129
- } catch (err) {
130
- errored = toError.toError(err);
131
- throw err;
132
- } finally {
133
- sem.release();
134
- }
135
- })();
136
- inflight.push(task);
137
- task.catch(() => {
138
- });
139
- }
140
- },
141
- async close() {
142
- try {
143
- if (errored) throw errored;
144
- options.signal?.throwIfAborted();
145
- if (pendingBytes > 0) {
146
- dispatchPart();
147
- }
148
- await Promise.all(inflight);
149
- if (errored) throw errored;
150
- if (largeFileId === null) {
151
- throw new Error("createWriteStream closed without any data written.");
152
- }
153
- const result = await raw.finishLargeFile(
154
- accountInfo.getApiUrl(),
155
- accountInfo.getAuthToken(),
156
- { fileId: largeFileId, partSha1Array: partSha1s }
157
- );
158
- resolveDone(result);
159
- } catch (err) {
160
- const fileIdToCancel = largeFileId;
161
- if (fileIdToCancel !== null) {
162
- await cancel.cancelLargeFileBestEffort(raw, accountInfo, fileIdToCancel);
163
- }
164
- rejectDone(err);
165
- throw err;
166
- }
167
- },
168
- async abort(reason) {
169
- const fileIdToCancel = largeFileId;
170
- if (fileIdToCancel !== null) {
171
- await cancel.cancelLargeFileBestEffort(raw, accountInfo, fileIdToCancel);
172
- }
173
- rejectDone(toError.toError(reason));
174
- }
175
- });
176
- return { writable, done };
28
+ const minPartSize = accountInfo.getAbsoluteMinimumPartSize();
29
+ const recommendedPartSize = accountInfo.getRecommendedPartSize();
30
+ const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize);
31
+ const concurrency = options.concurrency ?? 4;
32
+ const tracker = new require_progress.ProgressTracker(options.onProgress, null, null);
33
+ const sem = new require_concurrency.Semaphore(concurrency);
34
+ const abortScope = require_abort_scope.createAbortScope(options.signal);
35
+ let largeFileId = null;
36
+ let startPromise = null;
37
+ let cancelAfterStartScheduled = false;
38
+ let nextPartNumber = 1;
39
+ let pendingBytes = 0;
40
+ const pending = [];
41
+ const partSha1s = [];
42
+ const inflight = [];
43
+ let errored = null;
44
+ const { promise: done, resolve: resolveDone, reject: rejectDone } = Promise.withResolvers();
45
+ done.catch(() => {});
46
+ function ensureStarted() {
47
+ if (largeFileId !== null) return Promise.resolve(largeFileId);
48
+ if (startPromise === null) startPromise = raw.startLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
49
+ bucketId: options.bucketId,
50
+ fileName: options.fileName,
51
+ contentType: options.contentType ?? "b2/x-auto",
52
+ fileInfo: options.fileInfo ?? {},
53
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
54
+ }, {
55
+ signal: abortScope.signal,
56
+ ...options.retry !== void 0 ? { retry: options.retry } : {}
57
+ }).then((resp) => {
58
+ largeFileId = resp.fileId;
59
+ if (abortScope.signal.aborted || errored !== null) cancelStartedLargeFile(largeFileId);
60
+ return largeFileId;
61
+ });
62
+ const started = startPromise;
63
+ return require_abort_scope.raceWithAbort(started, abortScope.signal).catch((err) => {
64
+ if (abortScope.signal.aborted) scheduleCancelLargeFileAfterStart(started);
65
+ throw err;
66
+ });
67
+ }
68
+ async function shipPart(data, partNumber) {
69
+ if (errored !== null) throw errored;
70
+ abortScope.signal.throwIfAborted();
71
+ const fileId = await ensureStarted();
72
+ if (errored !== null) throw errored;
73
+ abortScope.signal.throwIfAborted();
74
+ const sha1 = new require_hash.IncrementalSha1();
75
+ await sha1.update(data);
76
+ const sha1Hex = await sha1.digest();
77
+ abortScope.signal.throwIfAborted();
78
+ const result = await require_retry.uploadPartWithFreshUrl(raw, accountInfo, fileId, {
79
+ fileName: options.fileName,
80
+ partNumber,
81
+ data,
82
+ contentLength: data.byteLength,
83
+ contentSha1: sha1Hex,
84
+ retry: options.retry,
85
+ signal: abortScope.signal,
86
+ onUploadRetry: options.onUploadRetry,
87
+ retryResponseBodyFailures: require_retry.resolveRetryResponseBodyFailures(options.retryResponseBodyFailures),
88
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
89
+ });
90
+ partSha1s[partNumber - 1] = result.contentSha1;
91
+ tracker.addBytes(data.byteLength);
92
+ tracker.completePart();
93
+ }
94
+ function markErrored(err) {
95
+ const error = require_to_error.toError(err);
96
+ errored = error;
97
+ abortScope.abort(error);
98
+ return error;
99
+ }
100
+ function cancelStartedLargeFile(fileId) {
101
+ if (cancelAfterStartScheduled) return;
102
+ cancelAfterStartScheduled = true;
103
+ require_cancel.cancelLargeFileBestEffort(raw, accountInfo, fileId, cleanupWriteStreamOptions(options));
104
+ }
105
+ function scheduleCancelLargeFileAfterStart(started) {
106
+ started.then((fileId) => cancelStartedLargeFile(fileId)).catch(() => {});
107
+ }
108
+ async function settleInflightForClose() {
109
+ const settled = Promise.allSettled(inflight);
110
+ if (startPromise === null || largeFileId !== null) return await settled;
111
+ const abortWaiter = waitForAbort(abortScope.signal);
112
+ try {
113
+ if (await Promise.race([
114
+ settled.then(() => "settled"),
115
+ startPromise.then(() => "start-settled", () => "start-settled"),
116
+ abortWaiter.promise.then(() => "aborted")
117
+ ]) === "aborted" && largeFileId === null) throw require_abort_scope.abortReason(abortScope.signal);
118
+ return await settled;
119
+ } finally {
120
+ abortWaiter.dispose();
121
+ }
122
+ }
123
+ function startPartWithAcquiredSlot(data, partNumber) {
124
+ const task = (async () => {
125
+ try {
126
+ await shipPart(data, partNumber);
127
+ } catch (err) {
128
+ markErrored(err);
129
+ throw err;
130
+ } finally {
131
+ sem.release();
132
+ }
133
+ })();
134
+ inflight.push(task);
135
+ task.catch(() => {});
136
+ }
137
+ async function acquirePartSlot() {
138
+ await sem.acquire();
139
+ if (errored !== null) {
140
+ sem.release();
141
+ throw errored;
142
+ }
143
+ try {
144
+ abortScope.signal.throwIfAborted();
145
+ } catch (err) {
146
+ sem.release();
147
+ throw err;
148
+ }
149
+ }
150
+ async function waitForInflightPartsToSettle(timeoutMs = require_cancel.DEFAULT_CLEANUP_TIMEOUT_MS) {
151
+ if (inflight.length === 0) return;
152
+ let timeout;
153
+ try {
154
+ await Promise.race([Promise.allSettled(inflight).then(() => void 0), new Promise((resolve) => {
155
+ timeout = setTimeout(resolve, timeoutMs);
156
+ })]);
157
+ } finally {
158
+ if (timeout !== void 0) clearTimeout(timeout);
159
+ }
160
+ }
161
+ async function dispatchPart() {
162
+ if (pending.length === 0) return;
163
+ await acquirePartSlot();
164
+ let data;
165
+ if (pending.length === 1) {
166
+ const head = pending[0];
167
+ if (!head) {
168
+ sem.release();
169
+ return;
170
+ }
171
+ data = head;
172
+ } else {
173
+ const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0);
174
+ data = new Uint8Array(total);
175
+ let offset = 0;
176
+ for (const chunk of pending) {
177
+ data.set(chunk, offset);
178
+ offset += chunk.byteLength;
179
+ }
180
+ }
181
+ pending.length = 0;
182
+ pendingBytes = 0;
183
+ const partNumber = nextPartNumber++;
184
+ startPartWithAcquiredSlot(data, partNumber);
185
+ }
186
+ return {
187
+ writable: new WritableStream({
188
+ async write(chunk) {
189
+ if (errored) throw errored;
190
+ abortScope.signal.throwIfAborted();
191
+ if (chunk.byteLength === 0) return;
192
+ pending.push(chunk);
193
+ pendingBytes += chunk.byteLength;
194
+ while (pendingBytes >= partSize) {
195
+ await acquirePartSlot();
196
+ if (errored) {
197
+ sem.release();
198
+ throw errored;
199
+ }
200
+ const carved = carveExact(pending, partSize);
201
+ const partNumber = nextPartNumber++;
202
+ pendingBytes -= partSize;
203
+ startPartWithAcquiredSlot(carved, partNumber);
204
+ }
205
+ },
206
+ async close() {
207
+ try {
208
+ if (errored) throw errored;
209
+ abortScope.signal.throwIfAborted();
210
+ if (pendingBytes > 0) await dispatchPart();
211
+ const rejected = (await settleInflightForClose()).find((result) => result.status === "rejected");
212
+ if (rejected !== void 0 && errored === null) markErrored(rejected.reason);
213
+ if (errored) throw errored;
214
+ if (largeFileId === null) throw new Error("createWriteStream closed without any data written.");
215
+ const result = await require_finish.finishLargeFileWithAbortReconciliation(raw, accountInfo, {
216
+ fileId: largeFileId,
217
+ bucketId: options.bucketId,
218
+ fileName: options.fileName,
219
+ partSha1s,
220
+ signal: abortScope.signal,
221
+ ...options.retry !== void 0 ? { retry: options.retry } : {}
222
+ });
223
+ abortScope.dispose();
224
+ resolveDone(result);
225
+ } catch (err) {
226
+ const closeError = require_to_error.toError(err);
227
+ if (errored === null) errored = closeError;
228
+ abortScope.abort(errored);
229
+ const observedError = errored;
230
+ const fileIdToCancel = largeFileId;
231
+ if (fileIdToCancel === null && startPromise !== null) {
232
+ scheduleCancelLargeFileAfterStart(startPromise);
233
+ abortScope.dispose();
234
+ rejectDone(observedError);
235
+ throw observedError;
236
+ }
237
+ await Promise.allSettled(inflight);
238
+ let finalError = observedError;
239
+ if (fileIdToCancel !== null) finalError = await require_cancel.resolveLargeFileErrorAfterCleanup(observedError, raw, accountInfo, {
240
+ fileId: fileIdToCancel,
241
+ bucketId: options.bucketId,
242
+ fileName: options.fileName,
243
+ signal: options.signal,
244
+ onCleanupFailure: options.onCleanupFailure
245
+ });
246
+ abortScope.dispose();
247
+ rejectDone(finalError);
248
+ throw finalError;
249
+ }
250
+ },
251
+ async abort(reason) {
252
+ const abortError = markErrored(reason);
253
+ pending.length = 0;
254
+ pendingBytes = 0;
255
+ const fileIdToCancel = largeFileId;
256
+ if (fileIdToCancel === null && startPromise !== null) scheduleCancelLargeFileAfterStart(startPromise);
257
+ if (fileIdToCancel !== null) {
258
+ await waitForInflightPartsToSettle();
259
+ await require_cancel.cancelLargeFileBestEffort(raw, accountInfo, fileIdToCancel, cleanupWriteStreamOptions(options));
260
+ }
261
+ abortScope.dispose();
262
+ rejectDone(abortError);
263
+ }
264
+ }),
265
+ done
266
+ };
177
267
  }
268
+ function cleanupWriteStreamOptions(options) {
269
+ return {
270
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
271
+ ...options.onCleanupFailure !== void 0 ? { onCleanupFailure: options.onCleanupFailure } : {}
272
+ };
273
+ }
274
+ /**
275
+ * Removes exactly `size` bytes from the front of `chunks` (mutates) and returns
276
+ * them as a contiguous Uint8Array. Any trailing remainder of the last chunk
277
+ * stays at the front of `chunks` for the next part.
278
+ *
279
+ * @param chunks - Queue of pending chunks. Modified in place.
280
+ * @param size - Number of bytes to carve off the front.
281
+ *
282
+ * @returns A new Uint8Array containing exactly `size` bytes.
283
+ */
178
284
  function carveExact(chunks, size) {
179
- const out = new Uint8Array(size);
180
- let written = 0;
181
- while (written < size && chunks.length > 0) {
182
- const head = chunks[0];
183
- if (!head) break;
184
- const need = size - written;
185
- if (head.byteLength <= need) {
186
- out.set(head, written);
187
- written += head.byteLength;
188
- chunks.shift();
189
- } else {
190
- out.set(head.subarray(0, need), written);
191
- chunks[0] = head.subarray(need);
192
- written += need;
193
- }
194
- }
195
- return out;
285
+ const out = new Uint8Array(size);
286
+ let written = 0;
287
+ while (written < size && chunks.length > 0) {
288
+ const head = chunks[0];
289
+ if (!head) break;
290
+ const need = size - written;
291
+ if (head.byteLength <= need) {
292
+ out.set(head, written);
293
+ written += head.byteLength;
294
+ chunks.shift();
295
+ } else {
296
+ out.set(head.subarray(0, need), written);
297
+ chunks[0] = head.subarray(need);
298
+ written += need;
299
+ }
300
+ }
301
+ return out;
302
+ }
303
+ function waitForAbort(signal) {
304
+ if (signal.aborted) return {
305
+ promise: Promise.resolve(require_abort_scope.abortReason(signal)),
306
+ dispose() {}
307
+ };
308
+ let onAbort;
309
+ return {
310
+ promise: new Promise((resolve) => {
311
+ onAbort = () => resolve(require_abort_scope.abortReason(signal));
312
+ signal.addEventListener("abort", onAbort, { once: true });
313
+ }),
314
+ dispose() {
315
+ if (onAbort !== void 0) signal.removeEventListener("abort", onAbort);
316
+ }
317
+ };
196
318
  }
319
+ //#endregion
197
320
  exports.createWriteStream = createWriteStream;
198
- //# sourceMappingURL=stream.cjs.map
321
+
322
+ //# sourceMappingURL=stream.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.cjs","sources":["../../src/upload/stream.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport type { ProgressListener } from '../streams/progress.ts'\nimport { ProgressTracker } from '../streams/progress.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { DEFAULT_CONTENT_TYPE, DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { toError } from '../util/to-error.ts'\nimport { cancelLargeFileBestEffort } from './cancel.ts'\nimport { Semaphore } from './concurrency.ts'\n\n/** Options for creating a streaming multipart upload sink. */\nexport interface CreateWriteStreamOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Destination file name in the bucket. */\n readonly fileName: string\n /** MIME type. Defaults to `b2/x-auto`. */\n readonly contentType?: string\n /** Custom file info stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption applied to each part. */\n readonly serverSideEncryption?: EncryptionSetting\n /**\n * Target part size in bytes. The stream buffers writes until this many bytes\n * are accumulated, then ships a part. Must be at least the account's\n * absolute minimum part size; the implementation will raise it if too small.\n */\n readonly partSize?: number\n /** Maximum number of parts uploaded in parallel. Defaults to 4. */\n readonly concurrency?: number\n /** Callback invoked with upload progress events. `totalBytes` is `null` (size unknown). */\n readonly onProgress?: ProgressListener\n /** Aborts the upload and cancels the unfinished large file. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Handle returned by `B2Object.createWriteStream`: the Web `WritableStream` to\n * pipe data into, plus a promise that resolves with the finished\n * {@link FileVersion} once the stream is closed and all parts have been\n * uploaded.\n */\nexport interface UploadWriteHandle {\n /** Web `WritableStream` sink to pipe data into. */\n readonly writable: WritableStream<Uint8Array>\n /** Resolves with the finalized file version when the stream closes successfully. */\n readonly done: Promise<FileVersion>\n}\n\n/**\n * Creates a {@link WritableStream} that streams data into a B2 multipart upload.\n *\n * Buffers incoming chunks until `partSize` bytes are accumulated, ships each\n * complete part through the standard multipart engine, and finalizes the file\n * once the stream is closed. Honours backpressure via the queue's bounded\n * concurrency. Streaming uploads do not support resume because the total size\n * and per-part hashes aren't known in advance; use {@link uploadLargeFile} with\n * a buffered source when resume is required.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, part URL pool).\n * @param options - Streaming upload parameters.\n *\n * @returns A {@link UploadWriteHandle} with the writable sink and a completion promise.\n */\nexport function createWriteStream(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: CreateWriteStreamOptions,\n): UploadWriteHandle {\n const minPartSize = accountInfo.getAbsoluteMinimumPartSize()\n const recommendedPartSize = accountInfo.getRecommendedPartSize()\n const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize)\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const tracker = new ProgressTracker(options.onProgress, null, null)\n const sem = new Semaphore(concurrency)\n\n let largeFileId: LargeFileId | null = null\n let startPromise: Promise<LargeFileId> | null = null\n let nextPartNumber = 1\n let pendingBytes = 0\n const pending: Uint8Array[] = []\n const partSha1s: string[] = []\n const inflight: Promise<void>[] = []\n let errored: Error | null = null\n\n // ES2024 `Promise.withResolvers()` exposes the resolve/reject pair as\n // properties of the returned object, avoiding the `let resolve!:` /\n // `let reject!:` non-null-assertion pattern needed before this API\n // existed. Available in Node 22 (our minimum), Bun, Deno, modern\n // browsers, and Cloudflare Workers.\n const {\n promise: done,\n resolve: resolveDone,\n reject: rejectDone,\n } = Promise.withResolvers<FileVersion>()\n // Attach a no-op rejection handler so a `done` that rejects before the\n // caller observes it never surfaces as a process-level unhandled rejection.\n // The error is not swallowed: `close()`/`abort()` also reject the writable\n // (so `pipeTo`/`getWriter().close()` throw), and any later `await done` /\n // `done.then(onRejected)` the caller attaches still sees the rejection —\n // extra handlers on the same promise all fire. Mirrors the\n // `task.catch(() => {})` pattern used for inflight part uploads below, and\n // keeps the engine well-behaved under Bun and Node's strict\n // unhandled-rejection mode.\n done.catch(() => {})\n\n function ensureStarted(): Promise<LargeFileId> {\n if (largeFileId !== null) return Promise.resolve(largeFileId)\n if (startPromise !== null) return startPromise\n startPromise = (async () => {\n const resp = await raw.startLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n bucketId: options.bucketId,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n fileInfo: options.fileInfo ?? {},\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n })\n largeFileId = resp.fileId\n return largeFileId\n })()\n return startPromise\n }\n\n async function shipPart(data: Uint8Array, partNumber: number): Promise<void> {\n const fileId = await ensureStarted()\n\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n\n let uploadEntry = accountInfo.checkoutPartUploadUrl(fileId)\n if (!uploadEntry) {\n const resp = await raw.getUploadPartUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n fileId,\n })\n uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n }\n\n try {\n const result = await raw.uploadPart(\n uploadEntry.uploadUrl,\n {\n authorization: uploadEntry.authorizationToken,\n partNumber,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n data as BodyInit,\n options.signal,\n )\n accountInfo.returnPartUploadUrl(fileId, uploadEntry)\n partSha1s[partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n } catch (err) {\n accountInfo.evictPartUploadUrl(fileId, uploadEntry)\n throw err\n }\n }\n\n function dispatchPart(): void {\n if (pending.length === 0) return\n let data: Uint8Array\n if (pending.length === 1) {\n const head = pending[0]\n if (!head) return\n data = head\n } else {\n const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0)\n data = new Uint8Array(total)\n let offset = 0\n for (const chunk of pending) {\n data.set(chunk, offset)\n offset += chunk.byteLength\n }\n }\n pending.length = 0\n pendingBytes = 0\n const partNumber = nextPartNumber++\n const task = (async () => {\n await sem.acquire()\n try {\n await shipPart(data, partNumber)\n } catch (err) {\n errored = toError(err)\n throw err\n } finally {\n sem.release()\n }\n })()\n inflight.push(task)\n // Swallow rejection here; we check `errored` later.\n task.catch(() => {})\n }\n\n const writable = new WritableStream<Uint8Array>({\n async write(chunk: Uint8Array): Promise<void> {\n if (errored) throw errored\n options.signal?.throwIfAborted()\n\n pending.push(chunk)\n pendingBytes += chunk.byteLength\n while (pendingBytes >= partSize) {\n // Pull exactly partSize bytes off the front\n const carved = carveExact(pending, partSize)\n const partNumber = nextPartNumber++\n pendingBytes -= partSize\n const task = (async () => {\n await sem.acquire()\n try {\n await shipPart(carved, partNumber)\n } catch (err) {\n errored = toError(err)\n throw err\n } finally {\n sem.release()\n }\n })()\n inflight.push(task)\n task.catch(() => {})\n }\n },\n\n async close(): Promise<void> {\n try {\n if (errored) throw errored\n options.signal?.throwIfAborted()\n\n // Ship any remaining bytes as the last part. If the total fit in one\n // single buffered batch (no parts shipped yet), we have to use the\n // multipart path anyway since we already called startLargeFile lazily.\n if (pendingBytes > 0) {\n dispatchPart()\n }\n\n await Promise.all(inflight)\n if (errored) throw errored\n\n if (largeFileId === null) {\n // Stream closed before any data was written. Start an empty large\n // file? B2 requires at least 2 parts. Reject — callers shouldn't\n // close an empty stream.\n throw new Error('createWriteStream closed without any data written.')\n }\n\n const result = await raw.finishLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n { fileId: largeFileId, partSha1Array: partSha1s },\n )\n resolveDone(result)\n } catch (err) {\n // Capture into a const so the cancel closure sees a non-null\n // `fileId`; closures don't observe the outer `!== null` narrowing\n // because the variable is mutable across the lambda boundary.\n const fileIdToCancel = largeFileId\n if (fileIdToCancel !== null) {\n await cancelLargeFileBestEffort(raw, accountInfo, fileIdToCancel)\n }\n rejectDone(err)\n throw err\n }\n },\n\n async abort(reason: unknown): Promise<void> {\n const fileIdToCancel = largeFileId\n if (fileIdToCancel !== null) {\n await cancelLargeFileBestEffort(raw, accountInfo, fileIdToCancel)\n }\n rejectDone(toError(reason))\n },\n })\n\n return { writable, done }\n}\n\n/**\n * Removes exactly `size` bytes from the front of `chunks` (mutates) and returns\n * them as a contiguous Uint8Array. Any trailing remainder of the last chunk\n * stays at the front of `chunks` for the next part.\n *\n * @param chunks - Queue of pending chunks. Modified in place.\n * @param size - Number of bytes to carve off the front.\n *\n * @returns A new Uint8Array containing exactly `size` bytes.\n */\nfunction carveExact(chunks: Uint8Array[], size: number): Uint8Array {\n const out = new Uint8Array(size)\n let written = 0\n while (written < size && chunks.length > 0) {\n const head = chunks[0]\n if (!head) break\n const need = size - written\n if (head.byteLength <= need) {\n out.set(head, written)\n written += head.byteLength\n chunks.shift()\n } else {\n out.set(head.subarray(0, need), written)\n chunks[0] = head.subarray(need)\n written += need\n }\n }\n return out\n}\n"],"names":["concurrency","DEFAULT_TRANSFER_CONCURRENCY","ProgressTracker","Semaphore","DEFAULT_CONTENT_TYPE","IncrementalSha1","toError","cancelLargeFileBestEffort"],"mappings":";;;;;;;;AAoEO,SAAS,kBACd,KACA,aACA,SACmB;AACnB,QAAM,cAAc,YAAY,2BAAA;AAChC,QAAM,sBAAsB,YAAY,uBAAA;AACxC,QAAM,WAAW,KAAK,IAAI,QAAQ,YAAY,qBAAqB,WAAW;AAC9E,QAAMA,gBAAc,QAAQ,eAAeC,SAAAA;AAC3C,QAAM,UAAU,IAAIC,SAAAA,gBAAgB,QAAQ,YAAY,MAAM,IAAI;AAClE,QAAM,MAAM,IAAIC,YAAAA,UAAUH,aAAW;AAErC,MAAI,cAAkC;AACtC,MAAI,eAA4C;AAChD,MAAI,iBAAiB;AACrB,MAAI,eAAe;AACnB,QAAM,UAAwB,CAAA;AAC9B,QAAM,YAAsB,CAAA;AAC5B,QAAM,WAA4B,CAAA;AAClC,MAAI,UAAwB;AAO5B,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,EAAA,IACN,QAAQ,cAAA;AAUZ,OAAK,MAAM,MAAM;AAAA,EAAC,CAAC;AAEnB,WAAS,gBAAsC;AAC7C,QAAI,gBAAgB,KAAM,QAAO,QAAQ,QAAQ,WAAW;AAC5D,QAAI,iBAAiB,KAAM,QAAO;AAClC,oBAAgB,YAAY;AAC1B,YAAM,OAAO,MAAM,IAAI,eAAe,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,QACzF,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,aAAa,QAAQ,eAAeI,SAAAA;AAAAA,QACpC,UAAU,QAAQ,YAAY,CAAA;AAAA,QAC9B,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,yBAChC,CAAA;AAAA,MAAC,CACN;AACD,oBAAc,KAAK;AACnB,aAAO;AAAA,IACT,GAAA;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,SAAS,MAAkB,YAAmC;AAC3E,UAAM,SAAS,MAAM,cAAA;AAErB,UAAM,OAAO,IAAIC,qBAAA;AACjB,UAAM,KAAK,OAAO,IAAI;AACtB,UAAM,UAAU,MAAM,KAAK,OAAA;AAE3B,QAAI,cAAc,YAAY,sBAAsB,MAAM;AAC1D,QAAI,CAAC,aAAa;AAChB,YAAM,OAAO,MAAM,IAAI,iBAAiB,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,QAC3F;AAAA,MAAA,CACD;AACD,oBAAc,EAAE,WAAW,KAAK,WAAW,oBAAoB,KAAK,mBAAA;AAAA,IACtE;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,IAAI;AAAA,QACvB,YAAY;AAAA,QACZ;AAAA,UACE,eAAe,YAAY;AAAA,UAC3B;AAAA,UACA,eAAe,KAAK;AAAA,UACpB,aAAa;AAAA,UACb,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,yBAChC,CAAA;AAAA,QAAC;AAAA,QAEP;AAAA,QACA,QAAQ;AAAA,MAAA;AAEV,kBAAY,oBAAoB,QAAQ,WAAW;AACnD,gBAAU,aAAa,CAAC,IAAI,OAAO;AACnC,cAAQ,SAAS,KAAK,UAAU;AAChC,cAAQ,aAAA;AAAA,IACV,SAAS,KAAK;AACZ,kBAAY,mBAAmB,QAAQ,WAAW;AAClD,YAAM;AAAA,IACR;AAAA,EACF;AAEA,WAAS,eAAqB;AAC5B,QAAI,QAAQ,WAAW,EAAG;AAC1B,QAAI;AACJ,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,CAAC,KAAM;AACX,aAAO;AAAA,IACT,OAAO;AACL,YAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,YAAY,CAAC;AACtE,aAAO,IAAI,WAAW,KAAK;AAC3B,UAAI,SAAS;AACb,iBAAW,SAAS,SAAS;AAC3B,aAAK,IAAI,OAAO,MAAM;AACtB,kBAAU,MAAM;AAAA,MAClB;AAAA,IACF;AACA,YAAQ,SAAS;AACjB,mBAAe;AACf,UAAM,aAAa;AACnB,UAAM,QAAQ,YAAY;AACxB,YAAM,IAAI,QAAA;AACV,UAAI;AACF,cAAM,SAAS,MAAM,UAAU;AAAA,MACjC,SAAS,KAAK;AACZ,kBAAUC,QAAAA,QAAQ,GAAG;AACrB,cAAM;AAAA,MACR,UAAA;AACE,YAAI,QAAA;AAAA,MACN;AAAA,IACF,GAAA;AACA,aAAS,KAAK,IAAI;AAElB,SAAK,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACrB;AAEA,QAAM,WAAW,IAAI,eAA2B;AAAA,IAC9C,MAAM,MAAM,OAAkC;AAC5C,UAAI,QAAS,OAAM;AACnB,cAAQ,QAAQ,eAAA;AAEhB,cAAQ,KAAK,KAAK;AAClB,sBAAgB,MAAM;AACtB,aAAO,gBAAgB,UAAU;AAE/B,cAAM,SAAS,WAAW,SAAS,QAAQ;AAC3C,cAAM,aAAa;AACnB,wBAAgB;AAChB,cAAM,QAAQ,YAAY;AACxB,gBAAM,IAAI,QAAA;AACV,cAAI;AACF,kBAAM,SAAS,QAAQ,UAAU;AAAA,UACnC,SAAS,KAAK;AACZ,sBAAUA,QAAAA,QAAQ,GAAG;AACrB,kBAAM;AAAA,UACR,UAAA;AACE,gBAAI,QAAA;AAAA,UACN;AAAA,QACF,GAAA;AACA,iBAAS,KAAK,IAAI;AAClB,aAAK,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,MAAM,QAAuB;AAC3B,UAAI;AACF,YAAI,QAAS,OAAM;AACnB,gBAAQ,QAAQ,eAAA;AAKhB,YAAI,eAAe,GAAG;AACpB,uBAAA;AAAA,QACF;AAEA,cAAM,QAAQ,IAAI,QAAQ;AAC1B,YAAI,QAAS,OAAM;AAEnB,YAAI,gBAAgB,MAAM;AAIxB,gBAAM,IAAI,MAAM,oDAAoD;AAAA,QACtE;AAEA,cAAM,SAAS,MAAM,IAAI;AAAA,UACvB,YAAY,UAAA;AAAA,UACZ,YAAY,aAAA;AAAA,UACZ,EAAE,QAAQ,aAAa,eAAe,UAAA;AAAA,QAAU;AAElD,oBAAY,MAAM;AAAA,MACpB,SAAS,KAAK;AAIZ,cAAM,iBAAiB;AACvB,YAAI,mBAAmB,MAAM;AAC3B,gBAAMC,iCAA0B,KAAK,aAAa,cAAc;AAAA,QAClE;AACA,mBAAW,GAAG;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,QAAgC;AAC1C,YAAM,iBAAiB;AACvB,UAAI,mBAAmB,MAAM;AAC3B,cAAMA,iCAA0B,KAAK,aAAa,cAAc;AAAA,MAClE;AACA,iBAAWD,QAAAA,QAAQ,MAAM,CAAC;AAAA,IAC5B;AAAA,EAAA,CACD;AAED,SAAO,EAAE,UAAU,KAAA;AACrB;AAYA,SAAS,WAAW,QAAsB,MAA0B;AAClE,QAAM,MAAM,IAAI,WAAW,IAAI;AAC/B,MAAI,UAAU;AACd,SAAO,UAAU,QAAQ,OAAO,SAAS,GAAG;AAC1C,UAAM,OAAO,OAAO,CAAC;AACrB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,OAAO;AACpB,QAAI,KAAK,cAAc,MAAM;AAC3B,UAAI,IAAI,MAAM,OAAO;AACrB,iBAAW,KAAK;AAChB,aAAO,MAAA;AAAA,IACT,OAAO;AACL,UAAI,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,OAAO;AACvC,aAAO,CAAC,IAAI,KAAK,SAAS,IAAI;AAC9B,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;;"}
1
+ {"version":3,"file":"stream.cjs","names":[],"sources":["../../src/upload/stream.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport type { ProgressListener } from '../streams/progress.ts'\nimport { ProgressTracker } from '../streams/progress.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { DEFAULT_CONTENT_TYPE, DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { toError } from '../util/to-error.ts'\nimport { abortReason, createAbortScope, raceWithAbort } from './abort-scope.ts'\nimport {\n type CleanupFailureOptions,\n cancelLargeFileBestEffort,\n DEFAULT_CLEANUP_TIMEOUT_MS,\n resolveLargeFileErrorAfterCleanup,\n} from './cancel.ts'\nimport { Semaphore } from './concurrency.ts'\nimport { finishLargeFileWithAbortReconciliation } from './finish.ts'\nimport {\n resolveRetryResponseBodyFailures,\n type UploadRetryOptions,\n uploadPartWithFreshUrl,\n} from './retry.ts'\n\n/** Options for creating a streaming multipart upload sink. */\nexport interface CreateWriteStreamOptions extends UploadRetryOptions, CleanupFailureOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Destination file name in the bucket. */\n readonly fileName: string\n /** MIME type. Defaults to `b2/x-auto`. */\n readonly contentType?: string\n /** Custom file info stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption applied to each part. */\n readonly serverSideEncryption?: EncryptionSetting\n /**\n * Target part size in bytes. The stream buffers writes until this many bytes\n * are accumulated, then ships a part. Must be at least the account's\n * absolute minimum part size; the implementation will raise it if too small.\n */\n readonly partSize?: number\n /** Maximum number of parts uploaded in parallel. Defaults to 4. */\n readonly concurrency?: number\n /** Callback invoked with upload progress events. `totalBytes` is `null` (size unknown). */\n readonly onProgress?: ProgressListener\n /** Aborts the upload and cancels the unfinished large file. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Handle returned by `B2Object.createWriteStream`: the Web `WritableStream` to\n * pipe data into, plus a promise that resolves with the finished\n * {@link FileVersion} once the stream is closed and all parts have been\n * uploaded.\n */\nexport interface UploadWriteHandle {\n /** Web `WritableStream` sink to pipe data into. */\n readonly writable: WritableStream<Uint8Array>\n /** Resolves with the finalized file version when the stream closes successfully. */\n readonly done: Promise<FileVersion>\n}\n\n/**\n * Creates a {@link WritableStream} that streams data into a B2 multipart upload.\n *\n * Buffers incoming chunks until `partSize` bytes are accumulated, ships each\n * complete part through the standard multipart engine, and finalizes the file\n * once the stream is closed. Honours backpressure via the queue's bounded\n * concurrency. Streaming uploads do not support resume because the total size\n * and per-part hashes aren't known in advance; use {@link uploadLargeFile} with\n * a buffered source when resume is required.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, part URL pool).\n * @param options - Streaming upload parameters.\n *\n * @returns A {@link UploadWriteHandle} with the writable sink and a completion promise.\n */\nexport function createWriteStream(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: CreateWriteStreamOptions,\n): UploadWriteHandle {\n const minPartSize = accountInfo.getAbsoluteMinimumPartSize()\n const recommendedPartSize = accountInfo.getRecommendedPartSize()\n const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize)\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const tracker = new ProgressTracker(options.onProgress, null, null)\n const sem = new Semaphore(concurrency)\n const abortScope = createAbortScope(options.signal)\n\n let largeFileId: LargeFileId | null = null\n let startPromise: Promise<LargeFileId> | null = null\n let cancelAfterStartScheduled = false\n let nextPartNumber = 1\n let pendingBytes = 0\n const pending: Uint8Array[] = []\n const partSha1s: string[] = []\n const inflight: Promise<void>[] = []\n let errored: Error | null = null\n\n // ES2024 `Promise.withResolvers()` exposes the resolve/reject pair as\n // properties of the returned object, avoiding the `let resolve!:` /\n // `let reject!:` non-null-assertion pattern needed before this API\n // existed. Available in Node 22 (our minimum), Bun, Deno, modern\n // browsers, and Cloudflare Workers.\n const {\n promise: done,\n resolve: resolveDone,\n reject: rejectDone,\n } = Promise.withResolvers<FileVersion>()\n // Attach a no-op rejection handler so a `done` that rejects before the\n // caller observes it never surfaces as a process-level unhandled rejection.\n // The error is not swallowed: `close()`/`abort()` also reject the writable\n // (so `pipeTo`/`getWriter().close()` throw), and any later `await done` /\n // `done.then(onRejected)` the caller attaches still sees the rejection —\n // extra handlers on the same promise all fire. Mirrors the\n // `task.catch(() => {})` pattern used for inflight part uploads below, and\n // keeps the engine well-behaved under Bun and Node's strict\n // unhandled-rejection mode.\n done.catch(() => {})\n\n function ensureStarted(): Promise<LargeFileId> {\n if (largeFileId !== null) return Promise.resolve(largeFileId)\n if (startPromise === null) {\n const rawStart = raw.startLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n {\n bucketId: options.bucketId,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n fileInfo: options.fileInfo ?? {},\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n {\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n )\n startPromise = rawStart.then((resp) => {\n largeFileId = resp.fileId\n if (abortScope.signal.aborted || errored !== null) {\n cancelStartedLargeFile(largeFileId)\n }\n return largeFileId\n })\n }\n const started = startPromise\n return raceWithAbort(started, abortScope.signal).catch((err) => {\n if (abortScope.signal.aborted) scheduleCancelLargeFileAfterStart(started)\n throw err\n })\n }\n\n async function shipPart(data: Uint8Array, partNumber: number): Promise<void> {\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n const fileId = await ensureStarted()\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n abortScope.signal.throwIfAborted()\n\n const result = await uploadPartWithFreshUrl(raw, accountInfo, fileId, {\n fileName: options.fileName,\n partNumber,\n data: data as BodyInit,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n retry: options.retry,\n signal: abortScope.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: resolveRetryResponseBodyFailures(\n options.retryResponseBodyFailures,\n ),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n })\n partSha1s[partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n }\n\n function markErrored(err: unknown): Error {\n const error = toError(err)\n errored = error\n abortScope.abort(error)\n return error\n }\n\n function cancelStartedLargeFile(fileId: LargeFileId): void {\n if (cancelAfterStartScheduled) return\n cancelAfterStartScheduled = true\n void cancelLargeFileBestEffort(raw, accountInfo, fileId, cleanupWriteStreamOptions(options))\n }\n\n function scheduleCancelLargeFileAfterStart(started: Promise<LargeFileId>): void {\n void started\n .then((fileId) => cancelStartedLargeFile(fileId))\n .catch(() => {\n // If start failed, no file ID is available to cancel.\n })\n }\n\n async function settleInflightForClose(): Promise<PromiseSettledResult<void>[]> {\n const settled = Promise.allSettled(inflight)\n if (startPromise === null || largeFileId !== null) return await settled\n\n const abortWaiter = waitForAbort(abortScope.signal)\n try {\n const first = await Promise.race([\n settled.then(() => 'settled' as const),\n startPromise.then(\n () => 'start-settled' as const,\n () => 'start-settled' as const,\n ),\n abortWaiter.promise.then(() => 'aborted' as const),\n ])\n if (first === 'aborted' && largeFileId === null) {\n throw abortReason(abortScope.signal)\n }\n return await settled\n } finally {\n abortWaiter.dispose()\n }\n }\n\n function startPartWithAcquiredSlot(data: Uint8Array, partNumber: number): void {\n const task = (async () => {\n try {\n await shipPart(data, partNumber)\n } catch (err) {\n markErrored(err)\n throw err\n } finally {\n sem.release()\n }\n })()\n inflight.push(task)\n // Swallow rejection here; we check `errored` later.\n task.catch(() => {})\n }\n\n async function acquirePartSlot(): Promise<void> {\n await sem.acquire()\n if (errored !== null) {\n sem.release()\n throw errored\n }\n try {\n abortScope.signal.throwIfAborted()\n } catch (err) {\n sem.release()\n throw err\n }\n }\n\n async function waitForInflightPartsToSettle(\n timeoutMs = DEFAULT_CLEANUP_TIMEOUT_MS,\n ): Promise<void> {\n if (inflight.length === 0) return\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n Promise.allSettled(inflight).then(() => undefined),\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, timeoutMs)\n }),\n ])\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n }\n }\n\n async function dispatchPart(): Promise<void> {\n if (pending.length === 0) return\n await acquirePartSlot()\n let data: Uint8Array\n if (pending.length === 1) {\n const head = pending[0]\n if (!head) {\n sem.release()\n return\n }\n data = head\n } else {\n const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0)\n data = new Uint8Array(total)\n let offset = 0\n for (const chunk of pending) {\n data.set(chunk, offset)\n offset += chunk.byteLength\n }\n }\n pending.length = 0\n pendingBytes = 0\n const partNumber = nextPartNumber++\n startPartWithAcquiredSlot(data, partNumber)\n }\n\n const writable = new WritableStream<Uint8Array>({\n async write(chunk: Uint8Array): Promise<void> {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n if (chunk.byteLength === 0) return\n\n pending.push(chunk)\n pendingBytes += chunk.byteLength\n while (pendingBytes >= partSize) {\n await acquirePartSlot()\n if (errored) {\n sem.release()\n throw errored\n }\n // Pull exactly partSize bytes off the front\n const carved = carveExact(pending, partSize)\n const partNumber = nextPartNumber++\n pendingBytes -= partSize\n startPartWithAcquiredSlot(carved, partNumber)\n }\n },\n\n async close(): Promise<void> {\n try {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n\n // Ship any remaining bytes as the last part. If the total fit in one\n // single buffered batch (no parts shipped yet), we have to use the\n // multipart path anyway since we already called startLargeFile lazily.\n if (pendingBytes > 0) {\n await dispatchPart()\n }\n\n const settled = await settleInflightForClose()\n const rejected = settled.find(\n (result): result is PromiseRejectedResult => result.status === 'rejected',\n )\n if (rejected !== undefined && errored === null) {\n markErrored(rejected.reason)\n }\n if (errored) throw errored\n\n if (largeFileId === null) {\n // Stream closed before any data was written. Start an empty large\n // file? B2 requires at least 2 parts. Reject — callers shouldn't\n // close an empty stream.\n throw new Error('createWriteStream closed without any data written.')\n }\n\n const result = await finishLargeFileWithAbortReconciliation(raw, accountInfo, {\n fileId: largeFileId,\n bucketId: options.bucketId,\n fileName: options.fileName,\n partSha1s,\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n })\n abortScope.dispose()\n resolveDone(result)\n } catch (err) {\n const closeError = toError(err)\n if (errored === null) errored = closeError\n abortScope.abort(errored)\n const observedError = errored\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Mirror writer.abort(): close() must not wait for non-abortable\n // b2_start_large_file. If a file ID arrives later, cancel it in the\n // background.\n scheduleCancelLargeFileAfterStart(startPromise)\n abortScope.dispose()\n rejectDone(observedError)\n throw observedError\n }\n await Promise.allSettled(inflight)\n // Capture into a const so the cancel closure sees a non-null\n // `fileId`; closures don't observe the outer `!== null` narrowing\n // because the variable is mutable across the lambda boundary.\n let finalError: unknown = observedError\n if (fileIdToCancel !== null) {\n finalError = await resolveLargeFileErrorAfterCleanup(observedError, raw, accountInfo, {\n fileId: fileIdToCancel,\n bucketId: options.bucketId,\n fileName: options.fileName,\n signal: options.signal,\n onCleanupFailure: options.onCleanupFailure,\n })\n }\n abortScope.dispose()\n rejectDone(finalError)\n throw finalError\n }\n },\n\n async abort(reason: unknown): Promise<void> {\n const abortError = markErrored(reason)\n pending.length = 0\n pendingBytes = 0\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Do not await an in-flight start request here. A stalled\n // b2_start_large_file must not make writer.abort() hang; if it later\n // returns a file ID, cancel it best-effort in the background.\n scheduleCancelLargeFileAfterStart(startPromise)\n }\n if (fileIdToCancel !== null) {\n await waitForInflightPartsToSettle()\n await cancelLargeFileBestEffort(\n raw,\n accountInfo,\n fileIdToCancel,\n cleanupWriteStreamOptions(options),\n )\n }\n abortScope.dispose()\n rejectDone(abortError)\n },\n })\n\n return { writable, done }\n}\n\nfunction cleanupWriteStreamOptions(options: CreateWriteStreamOptions): {\n readonly signal?: AbortSignal\n} & CleanupFailureOptions {\n return {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.onCleanupFailure !== undefined\n ? { onCleanupFailure: options.onCleanupFailure }\n : {}),\n }\n}\n\n/**\n * Removes exactly `size` bytes from the front of `chunks` (mutates) and returns\n * them as a contiguous Uint8Array. Any trailing remainder of the last chunk\n * stays at the front of `chunks` for the next part.\n *\n * @param chunks - Queue of pending chunks. Modified in place.\n * @param size - Number of bytes to carve off the front.\n *\n * @returns A new Uint8Array containing exactly `size` bytes.\n */\nfunction carveExact(chunks: Uint8Array[], size: number): Uint8Array {\n const out = new Uint8Array(size)\n let written = 0\n while (written < size && chunks.length > 0) {\n const head = chunks[0]\n if (!head) break\n const need = size - written\n if (head.byteLength <= need) {\n out.set(head, written)\n written += head.byteLength\n chunks.shift()\n } else {\n out.set(head.subarray(0, need), written)\n chunks[0] = head.subarray(need)\n written += need\n }\n }\n return out\n}\n\nfunction waitForAbort(signal: AbortSignal): {\n readonly promise: Promise<unknown>\n dispose(): void\n} {\n if (signal.aborted) {\n return {\n promise: Promise.resolve(abortReason(signal)),\n dispose() {},\n }\n }\n\n let onAbort: (() => void) | undefined\n const promise = new Promise<unknown>((resolve) => {\n onAbort = () => resolve(abortReason(signal))\n signal.addEventListener('abort', onAbort, { once: true })\n })\n\n return {\n promise,\n dispose() {\n if (onAbort !== undefined) signal.removeEventListener('abort', onAbort)\n },\n }\n}\n"],"mappings":"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"}
@@ -4,8 +4,10 @@ import { ProgressListener } from '../streams/progress.js';
4
4
  import { EncryptionSetting } from '../types/encryption.js';
5
5
  import { FileVersion } from '../types/file.js';
6
6
  import { BucketId } from '../types/ids.js';
7
+ import { CleanupFailureOptions } from './cancel.js';
8
+ import { UploadRetryOptions } from './retry.js';
7
9
  /** Options for creating a streaming multipart upload sink. */
8
- export interface CreateWriteStreamOptions {
10
+ export interface CreateWriteStreamOptions extends UploadRetryOptions, CleanupFailureOptions {
9
11
  /** Target bucket for the upload. */
10
12
  readonly bucketId: BucketId;
11
13
  /** Destination file name in the bucket. */
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/upload/stream.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,iBAAiB,CAAA;AAM5D,8DAA8D;AAC9D,MAAM,WAAW,wBAAwB;IACvC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,mDAAmD;IACnD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IAC7C,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CAmNnB"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/upload/stream.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,iBAAiB,CAAA;AAI5D,OAAO,EACL,KAAK,qBAAqB,EAI3B,MAAM,aAAa,CAAA;AAGpB,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAA;AAEnB,8DAA8D;AAC9D,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB,EAAE,qBAAqB;IACzF,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,mDAAmD;IACnD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IAC7C,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CA0VnB"}