@milaboratories/pl-drivers 1.11.58 → 1.11.60

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 (330) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/clients/constructors.cjs +28 -28
  3. package/dist/clients/constructors.cjs.map +1 -1
  4. package/dist/clients/constructors.d.ts +17 -13
  5. package/dist/clients/constructors.js +28 -26
  6. package/dist/clients/constructors.js.map +1 -1
  7. package/dist/clients/crc32c.cjs +8 -13
  8. package/dist/clients/crc32c.cjs.map +1 -1
  9. package/dist/clients/crc32c.js +8 -12
  10. package/dist/clients/crc32c.js.map +1 -1
  11. package/dist/clients/download.cjs +119 -160
  12. package/dist/clients/download.cjs.map +1 -1
  13. package/dist/clients/download.d.ts +45 -41
  14. package/dist/clients/download.js +115 -137
  15. package/dist/clients/download.js.map +1 -1
  16. package/dist/clients/logs.cjs +78 -82
  17. package/dist/clients/logs.cjs.map +1 -1
  18. package/dist/clients/logs.d.ts +34 -24
  19. package/dist/clients/logs.js +77 -80
  20. package/dist/clients/logs.js.map +1 -1
  21. package/dist/clients/ls_api.cjs +62 -68
  22. package/dist/clients/ls_api.cjs.map +1 -1
  23. package/dist/clients/ls_api.d.ts +15 -11
  24. package/dist/clients/ls_api.js +61 -66
  25. package/dist/clients/ls_api.js.map +1 -1
  26. package/dist/clients/progress.cjs +49 -59
  27. package/dist/clients/progress.cjs.map +1 -1
  28. package/dist/clients/progress.d.ts +27 -20
  29. package/dist/clients/progress.js +48 -57
  30. package/dist/clients/progress.js.map +1 -1
  31. package/dist/clients/upload.cjs +189 -250
  32. package/dist/clients/upload.cjs.map +1 -1
  33. package/dist/clients/upload.d.ts +44 -34
  34. package/dist/clients/upload.js +187 -229
  35. package/dist/clients/upload.js.map +1 -1
  36. package/dist/drivers/download_blob/blob_key.cjs +9 -26
  37. package/dist/drivers/download_blob/blob_key.cjs.map +1 -1
  38. package/dist/drivers/download_blob/blob_key.js +7 -5
  39. package/dist/drivers/download_blob/blob_key.js.map +1 -1
  40. package/dist/drivers/download_blob/download_blob.cjs +395 -478
  41. package/dist/drivers/download_blob/download_blob.cjs.map +1 -1
  42. package/dist/drivers/download_blob/download_blob.d.ts +102 -100
  43. package/dist/drivers/download_blob/download_blob.js +388 -453
  44. package/dist/drivers/download_blob/download_blob.js.map +1 -1
  45. package/dist/drivers/download_blob/download_blob_task.cjs +128 -163
  46. package/dist/drivers/download_blob/download_blob_task.cjs.map +1 -1
  47. package/dist/drivers/download_blob/download_blob_task.js +125 -141
  48. package/dist/drivers/download_blob/download_blob_task.js.map +1 -1
  49. package/dist/drivers/download_blob/sparse_cache/cache.cjs +166 -195
  50. package/dist/drivers/download_blob/sparse_cache/cache.cjs.map +1 -1
  51. package/dist/drivers/download_blob/sparse_cache/cache.js +164 -193
  52. package/dist/drivers/download_blob/sparse_cache/cache.js.map +1 -1
  53. package/dist/drivers/download_blob/sparse_cache/file.cjs +29 -50
  54. package/dist/drivers/download_blob/sparse_cache/file.cjs.map +1 -1
  55. package/dist/drivers/download_blob/sparse_cache/file.js +28 -29
  56. package/dist/drivers/download_blob/sparse_cache/file.js.map +1 -1
  57. package/dist/drivers/download_blob/sparse_cache/ranges.cjs +48 -76
  58. package/dist/drivers/download_blob/sparse_cache/ranges.cjs.map +1 -1
  59. package/dist/drivers/download_blob/sparse_cache/ranges.js +47 -54
  60. package/dist/drivers/download_blob/sparse_cache/ranges.js.map +1 -1
  61. package/dist/drivers/download_blob_url/driver.cjs +125 -165
  62. package/dist/drivers/download_blob_url/driver.cjs.map +1 -1
  63. package/dist/drivers/download_blob_url/driver.d.ts +45 -42
  64. package/dist/drivers/download_blob_url/driver.js +123 -144
  65. package/dist/drivers/download_blob_url/driver.js.map +1 -1
  66. package/dist/drivers/download_blob_url/driver_id.cjs +4 -4
  67. package/dist/drivers/download_blob_url/driver_id.cjs.map +1 -1
  68. package/dist/drivers/download_blob_url/driver_id.js +4 -3
  69. package/dist/drivers/download_blob_url/driver_id.js.map +1 -1
  70. package/dist/drivers/download_blob_url/snapshot.cjs +7 -11
  71. package/dist/drivers/download_blob_url/snapshot.cjs.map +1 -1
  72. package/dist/drivers/download_blob_url/snapshot.d.ts +10 -5
  73. package/dist/drivers/download_blob_url/snapshot.js +5 -8
  74. package/dist/drivers/download_blob_url/snapshot.js.map +1 -1
  75. package/dist/drivers/download_blob_url/task.cjs +147 -194
  76. package/dist/drivers/download_blob_url/task.cjs.map +1 -1
  77. package/dist/drivers/download_blob_url/task.d.ts +55 -57
  78. package/dist/drivers/download_blob_url/task.js +140 -170
  79. package/dist/drivers/download_blob_url/task.js.map +1 -1
  80. package/dist/drivers/download_url/driver.cjs +109 -146
  81. package/dist/drivers/download_url/driver.cjs.map +1 -1
  82. package/dist/drivers/download_url/driver.d.ts +59 -57
  83. package/dist/drivers/download_url/driver.js +107 -125
  84. package/dist/drivers/download_url/driver.js.map +1 -1
  85. package/dist/drivers/download_url/task.cjs +104 -137
  86. package/dist/drivers/download_url/task.cjs.map +1 -1
  87. package/dist/drivers/download_url/task.d.ts +33 -37
  88. package/dist/drivers/download_url/task.js +99 -113
  89. package/dist/drivers/download_url/task.js.map +1 -1
  90. package/dist/drivers/helpers/download_local_handle.cjs +13 -14
  91. package/dist/drivers/helpers/download_local_handle.cjs.map +1 -1
  92. package/dist/drivers/helpers/download_local_handle.js +13 -13
  93. package/dist/drivers/helpers/download_local_handle.js.map +1 -1
  94. package/dist/drivers/helpers/download_remote_handle.cjs +23 -24
  95. package/dist/drivers/helpers/download_remote_handle.cjs.map +1 -1
  96. package/dist/drivers/helpers/download_remote_handle.js +22 -22
  97. package/dist/drivers/helpers/download_remote_handle.js.map +1 -1
  98. package/dist/drivers/helpers/files_cache.cjs +53 -64
  99. package/dist/drivers/helpers/files_cache.cjs.map +1 -1
  100. package/dist/drivers/helpers/files_cache.js +52 -62
  101. package/dist/drivers/helpers/files_cache.js.map +1 -1
  102. package/dist/drivers/helpers/helpers.cjs +24 -28
  103. package/dist/drivers/helpers/helpers.cjs.map +1 -1
  104. package/dist/drivers/helpers/helpers.d.ts +10 -7
  105. package/dist/drivers/helpers/helpers.js +24 -27
  106. package/dist/drivers/helpers/helpers.js.map +1 -1
  107. package/dist/drivers/helpers/logs_handle.cjs +24 -33
  108. package/dist/drivers/helpers/logs_handle.cjs.map +1 -1
  109. package/dist/drivers/helpers/logs_handle.js +24 -29
  110. package/dist/drivers/helpers/logs_handle.js.map +1 -1
  111. package/dist/drivers/helpers/ls_remote_import_handle.cjs +20 -20
  112. package/dist/drivers/helpers/ls_remote_import_handle.cjs.map +1 -1
  113. package/dist/drivers/helpers/ls_remote_import_handle.js +20 -18
  114. package/dist/drivers/helpers/ls_remote_import_handle.js.map +1 -1
  115. package/dist/drivers/helpers/ls_storage_entry.cjs +36 -40
  116. package/dist/drivers/helpers/ls_storage_entry.cjs.map +1 -1
  117. package/dist/drivers/helpers/ls_storage_entry.js +36 -37
  118. package/dist/drivers/helpers/ls_storage_entry.js.map +1 -1
  119. package/dist/drivers/helpers/polling_ops.d.ts +6 -5
  120. package/dist/drivers/helpers/read_file.cjs +34 -57
  121. package/dist/drivers/helpers/read_file.cjs.map +1 -1
  122. package/dist/drivers/helpers/read_file.js +30 -34
  123. package/dist/drivers/helpers/read_file.js.map +1 -1
  124. package/dist/drivers/logs.cjs +94 -112
  125. package/dist/drivers/logs.cjs.map +1 -1
  126. package/dist/drivers/logs.d.ts +35 -32
  127. package/dist/drivers/logs.js +93 -110
  128. package/dist/drivers/logs.js.map +1 -1
  129. package/dist/drivers/logs_stream.cjs +210 -242
  130. package/dist/drivers/logs_stream.cjs.map +1 -1
  131. package/dist/drivers/logs_stream.d.ts +55 -53
  132. package/dist/drivers/logs_stream.js +209 -240
  133. package/dist/drivers/logs_stream.js.map +1 -1
  134. package/dist/drivers/ls.cjs +151 -238
  135. package/dist/drivers/ls.cjs.map +1 -1
  136. package/dist/drivers/ls.d.ts +53 -49
  137. package/dist/drivers/ls.js +148 -216
  138. package/dist/drivers/ls.js.map +1 -1
  139. package/dist/drivers/types.cjs +25 -53
  140. package/dist/drivers/types.cjs.map +1 -1
  141. package/dist/drivers/types.d.ts +91 -106
  142. package/dist/drivers/types.js +23 -50
  143. package/dist/drivers/types.js.map +1 -1
  144. package/dist/drivers/upload.cjs +127 -153
  145. package/dist/drivers/upload.cjs.map +1 -1
  146. package/dist/drivers/upload.d.ts +52 -50
  147. package/dist/drivers/upload.js +126 -151
  148. package/dist/drivers/upload.js.map +1 -1
  149. package/dist/drivers/upload_task.cjs +223 -260
  150. package/dist/drivers/upload_task.cjs.map +1 -1
  151. package/dist/drivers/upload_task.d.ts +54 -52
  152. package/dist/drivers/upload_task.js +221 -258
  153. package/dist/drivers/upload_task.js.map +1 -1
  154. package/dist/drivers/urls/url.cjs +30 -35
  155. package/dist/drivers/urls/url.cjs.map +1 -1
  156. package/dist/drivers/urls/url.js +28 -33
  157. package/dist/drivers/urls/url.js.map +1 -1
  158. package/dist/drivers/virtual_storages.cjs +36 -48
  159. package/dist/drivers/virtual_storages.cjs.map +1 -1
  160. package/dist/drivers/virtual_storages.d.ts +6 -2
  161. package/dist/drivers/virtual_storages.js +32 -46
  162. package/dist/drivers/virtual_storages.js.map +1 -1
  163. package/dist/helpers/download.cjs +72 -95
  164. package/dist/helpers/download.cjs.map +1 -1
  165. package/dist/helpers/download.d.ts +13 -9
  166. package/dist/helpers/download.js +71 -93
  167. package/dist/helpers/download.js.map +1 -1
  168. package/dist/helpers/download_errors.cjs +28 -27
  169. package/dist/helpers/download_errors.cjs.map +1 -1
  170. package/dist/helpers/download_errors.d.ts +16 -13
  171. package/dist/helpers/download_errors.js +28 -26
  172. package/dist/helpers/download_errors.js.map +1 -1
  173. package/dist/helpers/validate.cjs +8 -7
  174. package/dist/helpers/validate.cjs.map +1 -1
  175. package/dist/helpers/validate.d.ts +4 -1
  176. package/dist/helpers/validate.js +6 -5
  177. package/dist/helpers/validate.js.map +1 -1
  178. package/dist/index.cjs +75 -79
  179. package/dist/index.d.ts +22 -22
  180. package/dist/index.js +22 -21
  181. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs +238 -249
  182. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs.map +1 -1
  183. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs +27 -27
  184. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs.map +1 -1
  185. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +25 -23
  186. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js +26 -25
  187. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js.map +1 -1
  188. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +51 -87
  189. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js +238 -245
  190. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js.map +1 -1
  191. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs +295 -289
  192. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs.map +1 -1
  193. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs +30 -30
  194. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs.map +1 -1
  195. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js +29 -28
  196. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js.map +1 -1
  197. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +86 -150
  198. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js +295 -285
  199. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js.map +1 -1
  200. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs +385 -393
  201. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs.map +1 -1
  202. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs +34 -34
  203. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs.map +1 -1
  204. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +33 -34
  205. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js +33 -32
  206. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js.map +1 -1
  207. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +78 -129
  208. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js +385 -387
  209. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js.map +1 -1
  210. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs +570 -468
  211. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs.map +1 -1
  212. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs +82 -82
  213. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs.map +1 -1
  214. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +109 -112
  215. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js +81 -80
  216. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js.map +1 -1
  217. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +243 -264
  218. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js +569 -460
  219. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js.map +1 -1
  220. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +751 -729
  221. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -1
  222. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs +67 -67
  223. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs.map +1 -1
  224. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js +66 -65
  225. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js.map +1 -1
  226. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts +15 -381
  227. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +749 -718
  228. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -1
  229. package/dist/proto-grpc/google/protobuf/duration.cjs +92 -100
  230. package/dist/proto-grpc/google/protobuf/duration.cjs.map +1 -1
  231. package/dist/proto-grpc/google/protobuf/duration.d.ts +38 -43
  232. package/dist/proto-grpc/google/protobuf/duration.js +91 -98
  233. package/dist/proto-grpc/google/protobuf/duration.js.map +1 -1
  234. package/dist/proto-grpc/google/protobuf/timestamp.cjs +117 -128
  235. package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -1
  236. package/dist/proto-grpc/google/protobuf/timestamp.d.ts +50 -55
  237. package/dist/proto-grpc/google/protobuf/timestamp.js +116 -126
  238. package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -1
  239. package/dist/proto-rest/downloadapi.d.ts +85 -91
  240. package/dist/proto-rest/index.d.ts +11 -16
  241. package/dist/proto-rest/progressapi.d.ts +130 -140
  242. package/dist/proto-rest/streamingapi.d.ts +413 -434
  243. package/package.json +12 -12
  244. package/dist/clients/constructors.d.ts.map +0 -1
  245. package/dist/clients/crc32c.d.ts +0 -2
  246. package/dist/clients/crc32c.d.ts.map +0 -1
  247. package/dist/clients/download.d.ts.map +0 -1
  248. package/dist/clients/logs.d.ts.map +0 -1
  249. package/dist/clients/ls_api.d.ts.map +0 -1
  250. package/dist/clients/progress.d.ts.map +0 -1
  251. package/dist/clients/upload.d.ts.map +0 -1
  252. package/dist/drivers/download_blob/blob_key.d.ts +0 -5
  253. package/dist/drivers/download_blob/blob_key.d.ts.map +0 -1
  254. package/dist/drivers/download_blob/download_blob.d.ts.map +0 -1
  255. package/dist/drivers/download_blob/download_blob_task.d.ts +0 -56
  256. package/dist/drivers/download_blob/download_blob_task.d.ts.map +0 -1
  257. package/dist/drivers/download_blob/sparse_cache/cache.d.ts +0 -82
  258. package/dist/drivers/download_blob/sparse_cache/cache.d.ts.map +0 -1
  259. package/dist/drivers/download_blob/sparse_cache/file.d.ts +0 -8
  260. package/dist/drivers/download_blob/sparse_cache/file.d.ts.map +0 -1
  261. package/dist/drivers/download_blob/sparse_cache/ranges.d.ts +0 -46
  262. package/dist/drivers/download_blob/sparse_cache/ranges.d.ts.map +0 -1
  263. package/dist/drivers/download_blob_url/driver.d.ts.map +0 -1
  264. package/dist/drivers/download_blob_url/driver_id.d.ts +0 -6
  265. package/dist/drivers/download_blob_url/driver_id.d.ts.map +0 -1
  266. package/dist/drivers/download_blob_url/snapshot.d.ts.map +0 -1
  267. package/dist/drivers/download_blob_url/task.d.ts.map +0 -1
  268. package/dist/drivers/download_url/driver.d.ts.map +0 -1
  269. package/dist/drivers/download_url/task.d.ts.map +0 -1
  270. package/dist/drivers/helpers/download_local_handle.d.ts +0 -11
  271. package/dist/drivers/helpers/download_local_handle.d.ts.map +0 -1
  272. package/dist/drivers/helpers/download_remote_handle.d.ts +0 -13
  273. package/dist/drivers/helpers/download_remote_handle.d.ts.map +0 -1
  274. package/dist/drivers/helpers/files_cache.d.ts +0 -29
  275. package/dist/drivers/helpers/files_cache.d.ts.map +0 -1
  276. package/dist/drivers/helpers/helpers.d.ts.map +0 -1
  277. package/dist/drivers/helpers/logs_handle.d.ts +0 -15
  278. package/dist/drivers/helpers/logs_handle.d.ts.map +0 -1
  279. package/dist/drivers/helpers/ls_remote_import_handle.d.ts +0 -8
  280. package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +0 -1
  281. package/dist/drivers/helpers/ls_storage_entry.d.ts +0 -23
  282. package/dist/drivers/helpers/ls_storage_entry.d.ts.map +0 -1
  283. package/dist/drivers/helpers/polling_ops.d.ts.map +0 -1
  284. package/dist/drivers/helpers/read_file.d.ts +0 -12
  285. package/dist/drivers/helpers/read_file.d.ts.map +0 -1
  286. package/dist/drivers/helpers/test_helpers.d.ts +0 -2
  287. package/dist/drivers/helpers/test_helpers.d.ts.map +0 -1
  288. package/dist/drivers/logs.d.ts.map +0 -1
  289. package/dist/drivers/logs_stream.d.ts.map +0 -1
  290. package/dist/drivers/ls.d.ts.map +0 -1
  291. package/dist/drivers/types.d.ts.map +0 -1
  292. package/dist/drivers/upload.d.ts.map +0 -1
  293. package/dist/drivers/upload_task.d.ts.map +0 -1
  294. package/dist/drivers/urls/url.d.ts +0 -13
  295. package/dist/drivers/urls/url.d.ts.map +0 -1
  296. package/dist/drivers/virtual_storages.d.ts.map +0 -1
  297. package/dist/helpers/download.d.ts.map +0 -1
  298. package/dist/helpers/download_errors.d.ts.map +0 -1
  299. package/dist/helpers/validate.d.ts.map +0 -1
  300. package/dist/index.cjs.map +0 -1
  301. package/dist/index.d.ts.map +0 -1
  302. package/dist/index.js.map +0 -1
  303. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +0 -1
  304. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +0 -1
  305. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +0 -46
  306. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +0 -1
  307. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +0 -1
  308. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +0 -1
  309. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +0 -1
  310. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +0 -1
  311. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +0 -1
  312. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts +0 -108
  313. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +0 -1
  314. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +0 -1
  315. package/dist/proto-grpc/google/api/http.d.ts +0 -460
  316. package/dist/proto-grpc/google/api/http.d.ts.map +0 -1
  317. package/dist/proto-grpc/google/protobuf/descriptor.d.ts +0 -2340
  318. package/dist/proto-grpc/google/protobuf/descriptor.d.ts.map +0 -1
  319. package/dist/proto-grpc/google/protobuf/duration.d.ts.map +0 -1
  320. package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +0 -1
  321. package/dist/proto-rest/downloadapi.d.ts.map +0 -1
  322. package/dist/proto-rest/index.d.ts.map +0 -1
  323. package/dist/proto-rest/lsapi.d.ts +0 -148
  324. package/dist/proto-rest/lsapi.d.ts.map +0 -1
  325. package/dist/proto-rest/progressapi.d.ts.map +0 -1
  326. package/dist/proto-rest/streamingapi.d.ts.map +0 -1
  327. package/dist/proto-rest/uploadapi.d.ts +0 -355
  328. package/dist/proto-rest/uploadapi.d.ts.map +0 -1
  329. package/dist/test_env.d.ts +0 -6
  330. package/dist/test_env.d.ts.map +0 -1
@@ -1,100 +1,77 @@
1
- 'use strict';
1
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
2
+ const require_download_errors = require('./download_errors.cjs');
3
+ let undici = require("undici");
4
+ let node_stream = require("node:stream");
5
+ let node_stream_web = require("node:stream/web");
6
+ let node_stream_consumers = require("node:stream/consumers");
2
7
 
3
- var undici = require('undici');
4
- var node_stream = require('node:stream');
5
- var web = require('node:stream/web');
6
- var consumers = require('node:stream/consumers');
7
- var download_errors = require('./download_errors.cjs');
8
-
9
- class RemoteFileDownloader {
10
- httpClient;
11
- offByOneServers = [];
12
- constructor(httpClient) {
13
- this.httpClient = httpClient;
14
- }
15
- async withContent(url, reqHeaders, ops, handler) {
16
- const headers = { ...reqHeaders };
17
- const urlOrigin = new URL(url).origin;
18
- // Add range header if specified
19
- if (ops.range) {
20
- const offByOne = this.offByOneServers.includes(urlOrigin);
21
- headers["Range"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;
22
- }
23
- const { statusCode, body, headers: responseHeaders, } = await undici.request(url, {
24
- dispatcher: this.httpClient,
25
- // Undici automatically sets certain headers, so we need to lowercase user-provided headers
26
- // to prevent automatic headers from being set and avoid "duplicated headers" error.
27
- headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
28
- signal: ops.signal,
29
- highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset
30
- });
31
- ops.signal?.throwIfAborted();
32
- const webBody = node_stream.Readable.toWeb(body);
33
- let handlerSuccess = false;
34
- try {
35
- await checkStatusCodeOk(statusCode, webBody, url);
36
- ops.signal?.throwIfAborted();
37
- let result = undefined;
38
- const contentLength = Number(responseHeaders["content-length"]);
39
- if (Number.isNaN(contentLength) || contentLength === 0) {
40
- // Some backend versions have a bug that they are not returning content-length header.
41
- // In this case `content-length` header is returned as 0.
42
- // We should not clip the result stream to 0 bytes in such case.
43
- result = await handler(webBody, 0);
44
- }
45
- else {
46
- // Some backend versions have a bug where they return more data than requested in range.
47
- // So we have to manually normalize the stream to the expected size.
48
- const size = ops.range ? ops.range.to - ops.range.from : contentLength;
49
- const normalizedStream = webBody.pipeThrough(new (class extends web.TransformStream {
50
- constructor(sizeBytes, recordOffByOne) {
51
- super({
52
- transform(chunk, controller) {
53
- const truncatedChunk = chunk.slice(0, sizeBytes);
54
- controller.enqueue(truncatedChunk);
55
- sizeBytes -= truncatedChunk.length;
56
- if (!sizeBytes)
57
- controller.terminate();
58
- },
59
- flush(controller) {
60
- // Some backend versions have a bug where they return 1 less byte than requested in range.
61
- // We cannot always request one more byte because if this end byte is the last byte of the file,
62
- // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.
63
- if (sizeBytes === 1) {
64
- recordOffByOne();
65
- controller.error(new download_errors.OffByOneError());
66
- }
67
- },
68
- });
69
- }
70
- })(size, () => this.offByOneServers.push(urlOrigin)));
71
- result = await handler(normalizedStream, size);
72
- }
73
- handlerSuccess = true;
74
- return result;
75
- }
76
- catch (error) {
77
- // Cleanup on error (including handler errors)
78
- if (!handlerSuccess && !webBody.locked) {
79
- try {
80
- await webBody.cancel();
81
- }
82
- catch {
83
- // Ignore cleanup errors
84
- }
85
- }
86
- throw error;
87
- }
88
- }
89
- }
8
+ //#region src/helpers/download.ts
9
+ var RemoteFileDownloader = class {
10
+ offByOneServers = [];
11
+ constructor(httpClient) {
12
+ this.httpClient = httpClient;
13
+ }
14
+ async withContent(url, reqHeaders, ops, handler) {
15
+ const headers = { ...reqHeaders };
16
+ const urlOrigin = new URL(url).origin;
17
+ if (ops.range) {
18
+ const offByOne = this.offByOneServers.includes(urlOrigin);
19
+ headers["Range"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;
20
+ }
21
+ const { statusCode, body, headers: responseHeaders } = await (0, undici.request)(url, {
22
+ dispatcher: this.httpClient,
23
+ headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
24
+ signal: ops.signal,
25
+ highWaterMark: 1 * 1024 * 1024
26
+ });
27
+ ops.signal?.throwIfAborted();
28
+ const webBody = node_stream.Readable.toWeb(body);
29
+ let handlerSuccess = false;
30
+ try {
31
+ await checkStatusCodeOk(statusCode, webBody, url);
32
+ ops.signal?.throwIfAborted();
33
+ let result = void 0;
34
+ const contentLength = Number(responseHeaders["content-length"]);
35
+ if (Number.isNaN(contentLength) || contentLength === 0) result = await handler(webBody, 0);
36
+ else {
37
+ const size = ops.range ? ops.range.to - ops.range.from : contentLength;
38
+ result = await handler(webBody.pipeThrough(new class extends node_stream_web.TransformStream {
39
+ constructor(sizeBytes, recordOffByOne) {
40
+ super({
41
+ transform(chunk, controller) {
42
+ const truncatedChunk = chunk.slice(0, sizeBytes);
43
+ controller.enqueue(truncatedChunk);
44
+ sizeBytes -= truncatedChunk.length;
45
+ if (!sizeBytes) controller.terminate();
46
+ },
47
+ flush(controller) {
48
+ if (sizeBytes === 1) {
49
+ recordOffByOne();
50
+ controller.error(new require_download_errors.OffByOneError());
51
+ }
52
+ }
53
+ });
54
+ }
55
+ }(size, () => this.offByOneServers.push(urlOrigin))), size);
56
+ }
57
+ handlerSuccess = true;
58
+ return result;
59
+ } catch (error) {
60
+ if (!handlerSuccess && !webBody.locked) try {
61
+ await webBody.cancel();
62
+ } catch {}
63
+ throw error;
64
+ }
65
+ }
66
+ };
90
67
  async function checkStatusCodeOk(statusCode, webBody, url) {
91
- if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {
92
- const beginning = (await consumers.text(webBody)).substring(0, 1000);
93
- if (400 <= statusCode && statusCode < 500)
94
- throw new download_errors.DownloadNetworkError400(statusCode, url, beginning);
95
- throw new download_errors.DownloadNetworkError(statusCode, url, beginning);
96
- }
68
+ if (statusCode != 200 && statusCode != 206) {
69
+ const beginning = (await (0, node_stream_consumers.text)(webBody)).substring(0, 1e3);
70
+ if (400 <= statusCode && statusCode < 500) throw new require_download_errors.DownloadNetworkError400(statusCode, url, beginning);
71
+ throw new require_download_errors.DownloadNetworkError(statusCode, url, beginning);
72
+ }
97
73
  }
98
74
 
75
+ //#endregion
99
76
  exports.RemoteFileDownloader = RemoteFileDownloader;
100
- //# sourceMappingURL=download.cjs.map
77
+ //# sourceMappingURL=download.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"download.cjs","sources":["../../src/helpers/download.ts"],"sourcesContent":["// @TODO Gleb Zakharov\n/* eslint-disable n/no-unsupported-features/node-builtins */\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\nimport { TransformStream } from \"node:stream/web\";\nimport { text } from \"node:stream/consumers\";\nimport type { GetContentOptions } from \"@milaboratories/pl-model-common\";\nimport { OffByOneError, DownloadNetworkError400, DownloadNetworkError } from \"./download_errors\";\n\nexport type ContentHandler<T> = (content: ReadableStream, size: number) => Promise<T>;\n\nexport class RemoteFileDownloader {\n private readonly offByOneServers: string[] = [];\n\n constructor(public readonly httpClient: Dispatcher) {}\n\n async withContent<T>(\n url: string,\n reqHeaders: Record<string, string>,\n ops: GetContentOptions,\n handler: ContentHandler<T>,\n ): Promise<T> {\n const headers = { ...reqHeaders };\n const urlOrigin = new URL(url).origin;\n\n // Add range header if specified\n if (ops.range) {\n const offByOne = this.offByOneServers.includes(urlOrigin);\n headers[\"Range\"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;\n }\n\n const {\n statusCode,\n body,\n headers: responseHeaders,\n } = await request(url, {\n dispatcher: this.httpClient,\n // Undici automatically sets certain headers, so we need to lowercase user-provided headers\n // to prevent automatic headers from being set and avoid \"duplicated headers\" error.\n headers: Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]),\n ),\n signal: ops.signal,\n highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset\n });\n ops.signal?.throwIfAborted();\n\n const webBody = Readable.toWeb(body);\n let handlerSuccess = false;\n\n try {\n await checkStatusCodeOk(statusCode, webBody, url);\n ops.signal?.throwIfAborted();\n\n let result: T | undefined = undefined;\n\n const contentLength = Number(responseHeaders[\"content-length\"]);\n if (Number.isNaN(contentLength) || contentLength === 0) {\n // Some backend versions have a bug that they are not returning content-length header.\n // In this case `content-length` header is returned as 0.\n // We should not clip the result stream to 0 bytes in such case.\n result = await handler(webBody, 0);\n } else {\n // Some backend versions have a bug where they return more data than requested in range.\n // So we have to manually normalize the stream to the expected size.\n const size = ops.range ? ops.range.to - ops.range.from : contentLength;\n const normalizedStream = webBody.pipeThrough(\n new (class extends TransformStream {\n constructor(sizeBytes: number, recordOffByOne: () => void) {\n super({\n transform(chunk: Uint8Array, controller) {\n const truncatedChunk = chunk.slice(0, sizeBytes);\n controller.enqueue(truncatedChunk);\n sizeBytes -= truncatedChunk.length;\n if (!sizeBytes) controller.terminate();\n },\n flush(controller) {\n // Some backend versions have a bug where they return 1 less byte than requested in range.\n // We cannot always request one more byte because if this end byte is the last byte of the file,\n // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.\n if (sizeBytes === 1) {\n recordOffByOne();\n controller.error(new OffByOneError());\n }\n },\n });\n }\n })(size, () => this.offByOneServers.push(urlOrigin)),\n );\n result = await handler(normalizedStream, size);\n }\n\n handlerSuccess = true;\n return result;\n } catch (error) {\n // Cleanup on error (including handler errors)\n if (!handlerSuccess && !webBody.locked) {\n try {\n await webBody.cancel();\n } catch {\n // Ignore cleanup errors\n }\n }\n throw error;\n }\n }\n}\n\nasync function checkStatusCodeOk(statusCode: number, webBody: ReadableStream, url: string) {\n if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {\n const beginning = (await text(webBody)).substring(0, 1000);\n if (400 <= statusCode && statusCode < 500)\n throw new DownloadNetworkError400(statusCode, url, beginning);\n throw new DownloadNetworkError(statusCode, url, beginning);\n }\n}\n"],"names":["request","Readable","TransformStream","OffByOneError","text","DownloadNetworkError400","DownloadNetworkError"],"mappings":"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"}
1
+ {"version":3,"file":"download.cjs","names":["Readable","TransformStream","OffByOneError","DownloadNetworkError400","DownloadNetworkError"],"sources":["../../src/helpers/download.ts"],"sourcesContent":["// @TODO Gleb Zakharov\n/* eslint-disable n/no-unsupported-features/node-builtins */\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\nimport { TransformStream } from \"node:stream/web\";\nimport { text } from \"node:stream/consumers\";\nimport type { GetContentOptions } from \"@milaboratories/pl-model-common\";\nimport { OffByOneError, DownloadNetworkError400, DownloadNetworkError } from \"./download_errors\";\n\nexport type ContentHandler<T> = (content: ReadableStream, size: number) => Promise<T>;\n\nexport class RemoteFileDownloader {\n private readonly offByOneServers: string[] = [];\n\n constructor(public readonly httpClient: Dispatcher) {}\n\n async withContent<T>(\n url: string,\n reqHeaders: Record<string, string>,\n ops: GetContentOptions,\n handler: ContentHandler<T>,\n ): Promise<T> {\n const headers = { ...reqHeaders };\n const urlOrigin = new URL(url).origin;\n\n // Add range header if specified\n if (ops.range) {\n const offByOne = this.offByOneServers.includes(urlOrigin);\n headers[\"Range\"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;\n }\n\n const {\n statusCode,\n body,\n headers: responseHeaders,\n } = await request(url, {\n dispatcher: this.httpClient,\n // Undici automatically sets certain headers, so we need to lowercase user-provided headers\n // to prevent automatic headers from being set and avoid \"duplicated headers\" error.\n headers: Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]),\n ),\n signal: ops.signal,\n highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset\n });\n ops.signal?.throwIfAborted();\n\n const webBody = Readable.toWeb(body);\n let handlerSuccess = false;\n\n try {\n await checkStatusCodeOk(statusCode, webBody, url);\n ops.signal?.throwIfAborted();\n\n let result: T | undefined = undefined;\n\n const contentLength = Number(responseHeaders[\"content-length\"]);\n if (Number.isNaN(contentLength) || contentLength === 0) {\n // Some backend versions have a bug that they are not returning content-length header.\n // In this case `content-length` header is returned as 0.\n // We should not clip the result stream to 0 bytes in such case.\n result = await handler(webBody, 0);\n } else {\n // Some backend versions have a bug where they return more data than requested in range.\n // So we have to manually normalize the stream to the expected size.\n const size = ops.range ? ops.range.to - ops.range.from : contentLength;\n const normalizedStream = webBody.pipeThrough(\n new (class extends TransformStream {\n constructor(sizeBytes: number, recordOffByOne: () => void) {\n super({\n transform(chunk: Uint8Array, controller) {\n const truncatedChunk = chunk.slice(0, sizeBytes);\n controller.enqueue(truncatedChunk);\n sizeBytes -= truncatedChunk.length;\n if (!sizeBytes) controller.terminate();\n },\n flush(controller) {\n // Some backend versions have a bug where they return 1 less byte than requested in range.\n // We cannot always request one more byte because if this end byte is the last byte of the file,\n // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.\n if (sizeBytes === 1) {\n recordOffByOne();\n controller.error(new OffByOneError());\n }\n },\n });\n }\n })(size, () => this.offByOneServers.push(urlOrigin)),\n );\n result = await handler(normalizedStream, size);\n }\n\n handlerSuccess = true;\n return result;\n } catch (error) {\n // Cleanup on error (including handler errors)\n if (!handlerSuccess && !webBody.locked) {\n try {\n await webBody.cancel();\n } catch {\n // Ignore cleanup errors\n }\n }\n throw error;\n }\n }\n}\n\nasync function checkStatusCodeOk(statusCode: number, webBody: ReadableStream, url: string) {\n if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {\n const beginning = (await text(webBody)).substring(0, 1000);\n if (400 <= statusCode && statusCode < 500)\n throw new DownloadNetworkError400(statusCode, url, beginning);\n throw new DownloadNetworkError(statusCode, url, beginning);\n }\n}\n"],"mappings":";;;;;;;;AAaA,IAAa,uBAAb,MAAkC;CAChC,AAAiB,kBAA4B,EAAE;CAE/C,YAAY,AAAgB,YAAwB;EAAxB;;CAE5B,MAAM,YACJ,KACA,YACA,KACA,SACY;EACZ,MAAM,UAAU,EAAE,GAAG,YAAY;EACjC,MAAM,YAAY,IAAI,IAAI,IAAI,CAAC;AAG/B,MAAI,IAAI,OAAO;GACb,MAAM,WAAW,KAAK,gBAAgB,SAAS,UAAU;AACzD,WAAQ,WAAW,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,MAAM,WAAW,IAAI;;EAG/E,MAAM,EACJ,YACA,MACA,SAAS,oBACP,0BAAc,KAAK;GACrB,YAAY,KAAK;GAGjB,SAAS,OAAO,YACd,OAAO,QAAQ,QAAQ,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,IAAI,aAAa,EAAE,MAAM,CAAC,CAC1E;GACD,QAAQ,IAAI;GACZ,eAAe,IAAI,OAAO;GAC3B,CAAC;AACF,MAAI,QAAQ,gBAAgB;EAE5B,MAAM,UAAUA,qBAAS,MAAM,KAAK;EACpC,IAAI,iBAAiB;AAErB,MAAI;AACF,SAAM,kBAAkB,YAAY,SAAS,IAAI;AACjD,OAAI,QAAQ,gBAAgB;GAE5B,IAAI,SAAwB;GAE5B,MAAM,gBAAgB,OAAO,gBAAgB,kBAAkB;AAC/D,OAAI,OAAO,MAAM,cAAc,IAAI,kBAAkB,EAInD,UAAS,MAAM,QAAQ,SAAS,EAAE;QAC7B;IAGL,MAAM,OAAO,IAAI,QAAQ,IAAI,MAAM,KAAK,IAAI,MAAM,OAAO;AAwBzD,aAAS,MAAM,QAvBU,QAAQ,YAC/B,IAAK,cAAcC,gCAAgB;KACjC,YAAY,WAAmB,gBAA4B;AACzD,YAAM;OACJ,UAAU,OAAmB,YAAY;QACvC,MAAM,iBAAiB,MAAM,MAAM,GAAG,UAAU;AAChD,mBAAW,QAAQ,eAAe;AAClC,qBAAa,eAAe;AAC5B,YAAI,CAAC,UAAW,YAAW,WAAW;;OAExC,MAAM,YAAY;AAIhB,YAAI,cAAc,GAAG;AACnB,yBAAgB;AAChB,oBAAW,MAAM,IAAIC,uCAAe,CAAC;;;OAG1C,CAAC;;MAEH,YAAY,KAAK,gBAAgB,KAAK,UAAU,CAAC,CACrD,EACwC,KAAK;;AAGhD,oBAAiB;AACjB,UAAO;WACA,OAAO;AAEd,OAAI,CAAC,kBAAkB,CAAC,QAAQ,OAC9B,KAAI;AACF,UAAM,QAAQ,QAAQ;WAChB;AAIV,SAAM;;;;AAKZ,eAAe,kBAAkB,YAAoB,SAAyB,KAAa;AACzF,KAAI,cAAc,OAAO,cAAc,KAA8C;EACnF,MAAM,aAAa,sCAAW,QAAQ,EAAE,UAAU,GAAG,IAAK;AAC1D,MAAI,OAAO,cAAc,aAAa,IACpC,OAAM,IAAIC,gDAAwB,YAAY,KAAK,UAAU;AAC/D,QAAM,IAAIC,6CAAqB,YAAY,KAAK,UAAU"}
@@ -1,11 +1,15 @@
1
- import type { Dispatcher } from "undici";
2
- import type { ReadableStream } from "node:stream/web";
3
- import type { GetContentOptions } from "@milaboratories/pl-model-common";
4
- export type ContentHandler<T> = (content: ReadableStream, size: number) => Promise<T>;
5
- export declare class RemoteFileDownloader {
6
- readonly httpClient: Dispatcher;
7
- private readonly offByOneServers;
8
- constructor(httpClient: Dispatcher);
9
- withContent<T>(url: string, reqHeaders: Record<string, string>, ops: GetContentOptions, handler: ContentHandler<T>): Promise<T>;
1
+ import { Dispatcher } from "undici";
2
+ import { ReadableStream } from "node:stream/web";
3
+ import { GetContentOptions } from "@milaboratories/pl-model-common";
4
+
5
+ //#region src/helpers/download.d.ts
6
+ type ContentHandler$1<T> = (content: ReadableStream, size: number) => Promise<T>;
7
+ declare class RemoteFileDownloader {
8
+ readonly httpClient: Dispatcher;
9
+ private readonly offByOneServers;
10
+ constructor(httpClient: Dispatcher);
11
+ withContent<T>(url: string, reqHeaders: Record<string, string>, ops: GetContentOptions, handler: ContentHandler$1<T>): Promise<T>;
10
12
  }
13
+ //#endregion
14
+ export { ContentHandler$1 as ContentHandler, RemoteFileDownloader };
11
15
  //# sourceMappingURL=download.d.ts.map
@@ -1,98 +1,76 @@
1
- import { request } from 'undici';
2
- import { Readable } from 'node:stream';
3
- import { TransformStream } from 'node:stream/web';
4
- import { text } from 'node:stream/consumers';
5
- import { OffByOneError, DownloadNetworkError400, DownloadNetworkError } from './download_errors.js';
1
+ import { DownloadNetworkError, DownloadNetworkError400, OffByOneError } from "./download_errors.js";
2
+ import { request } from "undici";
3
+ import { Readable } from "node:stream";
4
+ import { TransformStream } from "node:stream/web";
5
+ import { text } from "node:stream/consumers";
6
6
 
7
- class RemoteFileDownloader {
8
- httpClient;
9
- offByOneServers = [];
10
- constructor(httpClient) {
11
- this.httpClient = httpClient;
12
- }
13
- async withContent(url, reqHeaders, ops, handler) {
14
- const headers = { ...reqHeaders };
15
- const urlOrigin = new URL(url).origin;
16
- // Add range header if specified
17
- if (ops.range) {
18
- const offByOne = this.offByOneServers.includes(urlOrigin);
19
- headers["Range"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;
20
- }
21
- const { statusCode, body, headers: responseHeaders, } = await request(url, {
22
- dispatcher: this.httpClient,
23
- // Undici automatically sets certain headers, so we need to lowercase user-provided headers
24
- // to prevent automatic headers from being set and avoid "duplicated headers" error.
25
- headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
26
- signal: ops.signal,
27
- highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset
28
- });
29
- ops.signal?.throwIfAborted();
30
- const webBody = Readable.toWeb(body);
31
- let handlerSuccess = false;
32
- try {
33
- await checkStatusCodeOk(statusCode, webBody, url);
34
- ops.signal?.throwIfAborted();
35
- let result = undefined;
36
- const contentLength = Number(responseHeaders["content-length"]);
37
- if (Number.isNaN(contentLength) || contentLength === 0) {
38
- // Some backend versions have a bug that they are not returning content-length header.
39
- // In this case `content-length` header is returned as 0.
40
- // We should not clip the result stream to 0 bytes in such case.
41
- result = await handler(webBody, 0);
42
- }
43
- else {
44
- // Some backend versions have a bug where they return more data than requested in range.
45
- // So we have to manually normalize the stream to the expected size.
46
- const size = ops.range ? ops.range.to - ops.range.from : contentLength;
47
- const normalizedStream = webBody.pipeThrough(new (class extends TransformStream {
48
- constructor(sizeBytes, recordOffByOne) {
49
- super({
50
- transform(chunk, controller) {
51
- const truncatedChunk = chunk.slice(0, sizeBytes);
52
- controller.enqueue(truncatedChunk);
53
- sizeBytes -= truncatedChunk.length;
54
- if (!sizeBytes)
55
- controller.terminate();
56
- },
57
- flush(controller) {
58
- // Some backend versions have a bug where they return 1 less byte than requested in range.
59
- // We cannot always request one more byte because if this end byte is the last byte of the file,
60
- // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.
61
- if (sizeBytes === 1) {
62
- recordOffByOne();
63
- controller.error(new OffByOneError());
64
- }
65
- },
66
- });
67
- }
68
- })(size, () => this.offByOneServers.push(urlOrigin)));
69
- result = await handler(normalizedStream, size);
70
- }
71
- handlerSuccess = true;
72
- return result;
73
- }
74
- catch (error) {
75
- // Cleanup on error (including handler errors)
76
- if (!handlerSuccess && !webBody.locked) {
77
- try {
78
- await webBody.cancel();
79
- }
80
- catch {
81
- // Ignore cleanup errors
82
- }
83
- }
84
- throw error;
85
- }
86
- }
87
- }
7
+ //#region src/helpers/download.ts
8
+ var RemoteFileDownloader = class {
9
+ offByOneServers = [];
10
+ constructor(httpClient) {
11
+ this.httpClient = httpClient;
12
+ }
13
+ async withContent(url, reqHeaders, ops, handler) {
14
+ const headers = { ...reqHeaders };
15
+ const urlOrigin = new URL(url).origin;
16
+ if (ops.range) {
17
+ const offByOne = this.offByOneServers.includes(urlOrigin);
18
+ headers["Range"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;
19
+ }
20
+ const { statusCode, body, headers: responseHeaders } = await request(url, {
21
+ dispatcher: this.httpClient,
22
+ headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
23
+ signal: ops.signal,
24
+ highWaterMark: 1 * 1024 * 1024
25
+ });
26
+ ops.signal?.throwIfAborted();
27
+ const webBody = Readable.toWeb(body);
28
+ let handlerSuccess = false;
29
+ try {
30
+ await checkStatusCodeOk(statusCode, webBody, url);
31
+ ops.signal?.throwIfAborted();
32
+ let result = void 0;
33
+ const contentLength = Number(responseHeaders["content-length"]);
34
+ if (Number.isNaN(contentLength) || contentLength === 0) result = await handler(webBody, 0);
35
+ else {
36
+ const size = ops.range ? ops.range.to - ops.range.from : contentLength;
37
+ result = await handler(webBody.pipeThrough(new class extends TransformStream {
38
+ constructor(sizeBytes, recordOffByOne) {
39
+ super({
40
+ transform(chunk, controller) {
41
+ const truncatedChunk = chunk.slice(0, sizeBytes);
42
+ controller.enqueue(truncatedChunk);
43
+ sizeBytes -= truncatedChunk.length;
44
+ if (!sizeBytes) controller.terminate();
45
+ },
46
+ flush(controller) {
47
+ if (sizeBytes === 1) {
48
+ recordOffByOne();
49
+ controller.error(new OffByOneError());
50
+ }
51
+ }
52
+ });
53
+ }
54
+ }(size, () => this.offByOneServers.push(urlOrigin))), size);
55
+ }
56
+ handlerSuccess = true;
57
+ return result;
58
+ } catch (error) {
59
+ if (!handlerSuccess && !webBody.locked) try {
60
+ await webBody.cancel();
61
+ } catch {}
62
+ throw error;
63
+ }
64
+ }
65
+ };
88
66
  async function checkStatusCodeOk(statusCode, webBody, url) {
89
- if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {
90
- const beginning = (await text(webBody)).substring(0, 1000);
91
- if (400 <= statusCode && statusCode < 500)
92
- throw new DownloadNetworkError400(statusCode, url, beginning);
93
- throw new DownloadNetworkError(statusCode, url, beginning);
94
- }
67
+ if (statusCode != 200 && statusCode != 206) {
68
+ const beginning = (await text(webBody)).substring(0, 1e3);
69
+ if (400 <= statusCode && statusCode < 500) throw new DownloadNetworkError400(statusCode, url, beginning);
70
+ throw new DownloadNetworkError(statusCode, url, beginning);
71
+ }
95
72
  }
96
73
 
74
+ //#endregion
97
75
  export { RemoteFileDownloader };
98
- //# sourceMappingURL=download.js.map
76
+ //# sourceMappingURL=download.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","sources":["../../src/helpers/download.ts"],"sourcesContent":["// @TODO Gleb Zakharov\n/* eslint-disable n/no-unsupported-features/node-builtins */\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\nimport { TransformStream } from \"node:stream/web\";\nimport { text } from \"node:stream/consumers\";\nimport type { GetContentOptions } from \"@milaboratories/pl-model-common\";\nimport { OffByOneError, DownloadNetworkError400, DownloadNetworkError } from \"./download_errors\";\n\nexport type ContentHandler<T> = (content: ReadableStream, size: number) => Promise<T>;\n\nexport class RemoteFileDownloader {\n private readonly offByOneServers: string[] = [];\n\n constructor(public readonly httpClient: Dispatcher) {}\n\n async withContent<T>(\n url: string,\n reqHeaders: Record<string, string>,\n ops: GetContentOptions,\n handler: ContentHandler<T>,\n ): Promise<T> {\n const headers = { ...reqHeaders };\n const urlOrigin = new URL(url).origin;\n\n // Add range header if specified\n if (ops.range) {\n const offByOne = this.offByOneServers.includes(urlOrigin);\n headers[\"Range\"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;\n }\n\n const {\n statusCode,\n body,\n headers: responseHeaders,\n } = await request(url, {\n dispatcher: this.httpClient,\n // Undici automatically sets certain headers, so we need to lowercase user-provided headers\n // to prevent automatic headers from being set and avoid \"duplicated headers\" error.\n headers: Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]),\n ),\n signal: ops.signal,\n highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset\n });\n ops.signal?.throwIfAborted();\n\n const webBody = Readable.toWeb(body);\n let handlerSuccess = false;\n\n try {\n await checkStatusCodeOk(statusCode, webBody, url);\n ops.signal?.throwIfAborted();\n\n let result: T | undefined = undefined;\n\n const contentLength = Number(responseHeaders[\"content-length\"]);\n if (Number.isNaN(contentLength) || contentLength === 0) {\n // Some backend versions have a bug that they are not returning content-length header.\n // In this case `content-length` header is returned as 0.\n // We should not clip the result stream to 0 bytes in such case.\n result = await handler(webBody, 0);\n } else {\n // Some backend versions have a bug where they return more data than requested in range.\n // So we have to manually normalize the stream to the expected size.\n const size = ops.range ? ops.range.to - ops.range.from : contentLength;\n const normalizedStream = webBody.pipeThrough(\n new (class extends TransformStream {\n constructor(sizeBytes: number, recordOffByOne: () => void) {\n super({\n transform(chunk: Uint8Array, controller) {\n const truncatedChunk = chunk.slice(0, sizeBytes);\n controller.enqueue(truncatedChunk);\n sizeBytes -= truncatedChunk.length;\n if (!sizeBytes) controller.terminate();\n },\n flush(controller) {\n // Some backend versions have a bug where they return 1 less byte than requested in range.\n // We cannot always request one more byte because if this end byte is the last byte of the file,\n // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.\n if (sizeBytes === 1) {\n recordOffByOne();\n controller.error(new OffByOneError());\n }\n },\n });\n }\n })(size, () => this.offByOneServers.push(urlOrigin)),\n );\n result = await handler(normalizedStream, size);\n }\n\n handlerSuccess = true;\n return result;\n } catch (error) {\n // Cleanup on error (including handler errors)\n if (!handlerSuccess && !webBody.locked) {\n try {\n await webBody.cancel();\n } catch {\n // Ignore cleanup errors\n }\n }\n throw error;\n }\n }\n}\n\nasync function checkStatusCodeOk(statusCode: number, webBody: ReadableStream, url: string) {\n if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {\n const beginning = (await text(webBody)).substring(0, 1000);\n if (400 <= statusCode && statusCode < 500)\n throw new DownloadNetworkError400(statusCode, url, beginning);\n throw new DownloadNetworkError(statusCode, url, beginning);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"download.js","names":[],"sources":["../../src/helpers/download.ts"],"sourcesContent":["// @TODO Gleb Zakharov\n/* eslint-disable n/no-unsupported-features/node-builtins */\nimport type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\nimport { TransformStream } from \"node:stream/web\";\nimport { text } from \"node:stream/consumers\";\nimport type { GetContentOptions } from \"@milaboratories/pl-model-common\";\nimport { OffByOneError, DownloadNetworkError400, DownloadNetworkError } from \"./download_errors\";\n\nexport type ContentHandler<T> = (content: ReadableStream, size: number) => Promise<T>;\n\nexport class RemoteFileDownloader {\n private readonly offByOneServers: string[] = [];\n\n constructor(public readonly httpClient: Dispatcher) {}\n\n async withContent<T>(\n url: string,\n reqHeaders: Record<string, string>,\n ops: GetContentOptions,\n handler: ContentHandler<T>,\n ): Promise<T> {\n const headers = { ...reqHeaders };\n const urlOrigin = new URL(url).origin;\n\n // Add range header if specified\n if (ops.range) {\n const offByOne = this.offByOneServers.includes(urlOrigin);\n headers[\"Range\"] = `bytes=${ops.range.from}-${ops.range.to - (offByOne ? 0 : 1)}`;\n }\n\n const {\n statusCode,\n body,\n headers: responseHeaders,\n } = await request(url, {\n dispatcher: this.httpClient,\n // Undici automatically sets certain headers, so we need to lowercase user-provided headers\n // to prevent automatic headers from being set and avoid \"duplicated headers\" error.\n headers: Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]),\n ),\n signal: ops.signal,\n highWaterMark: 1 * 1024 * 1024, // 1MB chunks instead of 64KB, tested to be optimal for Human Aging dataset\n });\n ops.signal?.throwIfAborted();\n\n const webBody = Readable.toWeb(body);\n let handlerSuccess = false;\n\n try {\n await checkStatusCodeOk(statusCode, webBody, url);\n ops.signal?.throwIfAborted();\n\n let result: T | undefined = undefined;\n\n const contentLength = Number(responseHeaders[\"content-length\"]);\n if (Number.isNaN(contentLength) || contentLength === 0) {\n // Some backend versions have a bug that they are not returning content-length header.\n // In this case `content-length` header is returned as 0.\n // We should not clip the result stream to 0 bytes in such case.\n result = await handler(webBody, 0);\n } else {\n // Some backend versions have a bug where they return more data than requested in range.\n // So we have to manually normalize the stream to the expected size.\n const size = ops.range ? ops.range.to - ops.range.from : contentLength;\n const normalizedStream = webBody.pipeThrough(\n new (class extends TransformStream {\n constructor(sizeBytes: number, recordOffByOne: () => void) {\n super({\n transform(chunk: Uint8Array, controller) {\n const truncatedChunk = chunk.slice(0, sizeBytes);\n controller.enqueue(truncatedChunk);\n sizeBytes -= truncatedChunk.length;\n if (!sizeBytes) controller.terminate();\n },\n flush(controller) {\n // Some backend versions have a bug where they return 1 less byte than requested in range.\n // We cannot always request one more byte because if this end byte is the last byte of the file,\n // the backend will return 416 (Range Not Satisfiable). So error is thrown to force client to retry the request.\n if (sizeBytes === 1) {\n recordOffByOne();\n controller.error(new OffByOneError());\n }\n },\n });\n }\n })(size, () => this.offByOneServers.push(urlOrigin)),\n );\n result = await handler(normalizedStream, size);\n }\n\n handlerSuccess = true;\n return result;\n } catch (error) {\n // Cleanup on error (including handler errors)\n if (!handlerSuccess && !webBody.locked) {\n try {\n await webBody.cancel();\n } catch {\n // Ignore cleanup errors\n }\n }\n throw error;\n }\n }\n}\n\nasync function checkStatusCodeOk(statusCode: number, webBody: ReadableStream, url: string) {\n if (statusCode != 200 && statusCode != 206 /* partial content from range request */) {\n const beginning = (await text(webBody)).substring(0, 1000);\n if (400 <= statusCode && statusCode < 500)\n throw new DownloadNetworkError400(statusCode, url, beginning);\n throw new DownloadNetworkError(statusCode, url, beginning);\n }\n}\n"],"mappings":";;;;;;;AAaA,IAAa,uBAAb,MAAkC;CAChC,AAAiB,kBAA4B,EAAE;CAE/C,YAAY,AAAgB,YAAwB;EAAxB;;CAE5B,MAAM,YACJ,KACA,YACA,KACA,SACY;EACZ,MAAM,UAAU,EAAE,GAAG,YAAY;EACjC,MAAM,YAAY,IAAI,IAAI,IAAI,CAAC;AAG/B,MAAI,IAAI,OAAO;GACb,MAAM,WAAW,KAAK,gBAAgB,SAAS,UAAU;AACzD,WAAQ,WAAW,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,MAAM,WAAW,IAAI;;EAG/E,MAAM,EACJ,YACA,MACA,SAAS,oBACP,MAAM,QAAQ,KAAK;GACrB,YAAY,KAAK;GAGjB,SAAS,OAAO,YACd,OAAO,QAAQ,QAAQ,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,IAAI,aAAa,EAAE,MAAM,CAAC,CAC1E;GACD,QAAQ,IAAI;GACZ,eAAe,IAAI,OAAO;GAC3B,CAAC;AACF,MAAI,QAAQ,gBAAgB;EAE5B,MAAM,UAAU,SAAS,MAAM,KAAK;EACpC,IAAI,iBAAiB;AAErB,MAAI;AACF,SAAM,kBAAkB,YAAY,SAAS,IAAI;AACjD,OAAI,QAAQ,gBAAgB;GAE5B,IAAI,SAAwB;GAE5B,MAAM,gBAAgB,OAAO,gBAAgB,kBAAkB;AAC/D,OAAI,OAAO,MAAM,cAAc,IAAI,kBAAkB,EAInD,UAAS,MAAM,QAAQ,SAAS,EAAE;QAC7B;IAGL,MAAM,OAAO,IAAI,QAAQ,IAAI,MAAM,KAAK,IAAI,MAAM,OAAO;AAwBzD,aAAS,MAAM,QAvBU,QAAQ,YAC/B,IAAK,cAAc,gBAAgB;KACjC,YAAY,WAAmB,gBAA4B;AACzD,YAAM;OACJ,UAAU,OAAmB,YAAY;QACvC,MAAM,iBAAiB,MAAM,MAAM,GAAG,UAAU;AAChD,mBAAW,QAAQ,eAAe;AAClC,qBAAa,eAAe;AAC5B,YAAI,CAAC,UAAW,YAAW,WAAW;;OAExC,MAAM,YAAY;AAIhB,YAAI,cAAc,GAAG;AACnB,yBAAgB;AAChB,oBAAW,MAAM,IAAI,eAAe,CAAC;;;OAG1C,CAAC;;MAEH,YAAY,KAAK,gBAAgB,KAAK,UAAU,CAAC,CACrD,EACwC,KAAK;;AAGhD,oBAAiB;AACjB,UAAO;WACA,OAAO;AAEd,OAAI,CAAC,kBAAkB,CAAC,QAAQ,OAC9B,KAAI;AACF,UAAM,QAAQ,QAAQ;WAChB;AAIV,SAAM;;;;AAKZ,eAAe,kBAAkB,YAAoB,SAAyB,KAAa;AACzF,KAAI,cAAc,OAAO,cAAc,KAA8C;EACnF,MAAM,aAAa,MAAM,KAAK,QAAQ,EAAE,UAAU,GAAG,IAAK;AAC1D,MAAI,OAAO,cAAc,aAAa,IACpC,OAAM,IAAI,wBAAwB,YAAY,KAAK,UAAU;AAC/D,QAAM,IAAI,qBAAqB,YAAY,KAAK,UAAU"}
@@ -1,43 +1,44 @@
1
- 'use strict';
2
1
 
3
- class DownloadNetworkError extends Error {
4
- name = "DownloadNetworkError";
5
- statusCode;
6
- url;
7
- beginning;
8
- constructor(statusCode, url, beginning) {
9
- super(`Http download error: statusCode: ${statusCode} url: ${url.toString()}, beginning of body: ${beginning}`);
10
- this.statusCode = statusCode;
11
- this.url = url;
12
- this.beginning = beginning;
13
- }
14
- }
2
+ //#region src/helpers/download_errors.ts
3
+ var DownloadNetworkError = class extends Error {
4
+ name = "DownloadNetworkError";
5
+ statusCode;
6
+ url;
7
+ beginning;
8
+ constructor(statusCode, url, beginning) {
9
+ super(`Http download error: statusCode: ${statusCode} url: ${url.toString()}, beginning of body: ${beginning}`);
10
+ this.statusCode = statusCode;
11
+ this.url = url;
12
+ this.beginning = beginning;
13
+ }
14
+ };
15
15
  function isDownloadNetworkError(error) {
16
- return error instanceof Error && error.name.startsWith("DownloadNetworkError");
16
+ return error instanceof Error && error.name.startsWith("DownloadNetworkError");
17
17
  }
18
18
  /** Throws when a status code of the downloading URL was in range [400, 500). */
19
- class DownloadNetworkError400 extends DownloadNetworkError {
20
- name = "DownloadNetworkError400";
21
- }
19
+ var DownloadNetworkError400 = class extends DownloadNetworkError {
20
+ name = "DownloadNetworkError400";
21
+ };
22
22
  function isDownloadNetworkError400(error) {
23
- return error instanceof Error && error.name === "DownloadNetworkError400";
23
+ return error instanceof Error && error.name === "DownloadNetworkError400";
24
24
  }
25
25
  /**
26
- * There are backend versions that return 1 less byte than requested in range.
27
- * For such cases, this error will be thrown, so client can retry the request.
28
- * Dowloader will retry the request with one more byte in range.
29
- */
30
- class OffByOneError extends Error {
31
- name = "OffByOneError";
32
- }
26
+ * There are backend versions that return 1 less byte than requested in range.
27
+ * For such cases, this error will be thrown, so client can retry the request.
28
+ * Dowloader will retry the request with one more byte in range.
29
+ */
30
+ var OffByOneError = class extends Error {
31
+ name = "OffByOneError";
32
+ };
33
33
  function isOffByOneError(error) {
34
- return error instanceof Error && error.name === "OffByOneError";
34
+ return error instanceof Error && error.name === "OffByOneError";
35
35
  }
36
36
 
37
+ //#endregion
37
38
  exports.DownloadNetworkError = DownloadNetworkError;
38
39
  exports.DownloadNetworkError400 = DownloadNetworkError400;
39
40
  exports.OffByOneError = OffByOneError;
40
41
  exports.isDownloadNetworkError = isDownloadNetworkError;
41
42
  exports.isDownloadNetworkError400 = isDownloadNetworkError400;
42
43
  exports.isOffByOneError = isOffByOneError;
43
- //# sourceMappingURL=download_errors.cjs.map
44
+ //# sourceMappingURL=download_errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"download_errors.cjs","sources":["../../src/helpers/download_errors.ts"],"sourcesContent":["export class DownloadNetworkError extends Error {\n name = \"DownloadNetworkError\";\n\n statusCode: number;\n url: string;\n beginning: string;\n\n constructor(statusCode: number, url: string, beginning: string) {\n super(\n `Http download error: statusCode: ${statusCode} url: ${url.toString()}, beginning of body: ${beginning}`,\n );\n this.statusCode = statusCode;\n this.url = url;\n this.beginning = beginning;\n }\n}\n\nexport function isDownloadNetworkError(error: unknown): error is DownloadNetworkError {\n return error instanceof Error && error.name.startsWith(\"DownloadNetworkError\");\n}\n\n/** Throws when a status code of the downloading URL was in range [400, 500). */\nexport class DownloadNetworkError400 extends DownloadNetworkError {\n name = \"DownloadNetworkError400\";\n}\n\nexport function isDownloadNetworkError400(error: unknown): error is DownloadNetworkError400 {\n return error instanceof Error && error.name === \"DownloadNetworkError400\";\n}\n\n/**\n * There are backend versions that return 1 less byte than requested in range.\n * For such cases, this error will be thrown, so client can retry the request.\n * Dowloader will retry the request with one more byte in range.\n */\nexport class OffByOneError extends Error {\n name = \"OffByOneError\";\n}\n\nexport function isOffByOneError(error: unknown): error is OffByOneError {\n return error instanceof Error && error.name === \"OffByOneError\";\n}\n"],"names":[],"mappings":";;AAAM,MAAO,oBAAqB,SAAQ,KAAK,CAAA;IAC7C,IAAI,GAAG,sBAAsB;AAE7B,IAAA,UAAU;AACV,IAAA,GAAG;AACH,IAAA,SAAS;AAET,IAAA,WAAA,CAAY,UAAkB,EAAE,GAAW,EAAE,SAAiB,EAAA;AAC5D,QAAA,KAAK,CACH,CAAA,iCAAA,EAAoC,UAAU,CAAA,MAAA,EAAS,GAAG,CAAC,QAAQ,EAAE,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAE,CACzG;AACD,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU;AAC5B,QAAA,IAAI,CAAC,GAAG,GAAG,GAAG;AACd,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;IAC5B;AACD;AAEK,SAAU,sBAAsB,CAAC,KAAc,EAAA;AACnD,IAAA,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC;AAChF;AAEA;AACM,MAAO,uBAAwB,SAAQ,oBAAoB,CAAA;IAC/D,IAAI,GAAG,yBAAyB;AACjC;AAEK,SAAU,yBAAyB,CAAC,KAAc,EAAA;IACtD,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB;AAC3E;AAEA;;;;AAIG;AACG,MAAO,aAAc,SAAQ,KAAK,CAAA;IACtC,IAAI,GAAG,eAAe;AACvB;AAEK,SAAU,eAAe,CAAC,KAAc,EAAA;IAC5C,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;AACjE;;;;;;;;;"}
1
+ {"version":3,"file":"download_errors.cjs","names":[],"sources":["../../src/helpers/download_errors.ts"],"sourcesContent":["export class DownloadNetworkError extends Error {\n name = \"DownloadNetworkError\";\n\n statusCode: number;\n url: string;\n beginning: string;\n\n constructor(statusCode: number, url: string, beginning: string) {\n super(\n `Http download error: statusCode: ${statusCode} url: ${url.toString()}, beginning of body: ${beginning}`,\n );\n this.statusCode = statusCode;\n this.url = url;\n this.beginning = beginning;\n }\n}\n\nexport function isDownloadNetworkError(error: unknown): error is DownloadNetworkError {\n return error instanceof Error && error.name.startsWith(\"DownloadNetworkError\");\n}\n\n/** Throws when a status code of the downloading URL was in range [400, 500). */\nexport class DownloadNetworkError400 extends DownloadNetworkError {\n name = \"DownloadNetworkError400\";\n}\n\nexport function isDownloadNetworkError400(error: unknown): error is DownloadNetworkError400 {\n return error instanceof Error && error.name === \"DownloadNetworkError400\";\n}\n\n/**\n * There are backend versions that return 1 less byte than requested in range.\n * For such cases, this error will be thrown, so client can retry the request.\n * Dowloader will retry the request with one more byte in range.\n */\nexport class OffByOneError extends Error {\n name = \"OffByOneError\";\n}\n\nexport function isOffByOneError(error: unknown): error is OffByOneError {\n return error instanceof Error && error.name === \"OffByOneError\";\n}\n"],"mappings":";;AAAA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,OAAO;CAEP;CACA;CACA;CAEA,YAAY,YAAoB,KAAa,WAAmB;AAC9D,QACE,oCAAoC,WAAW,QAAQ,IAAI,UAAU,CAAC,uBAAuB,YAC9F;AACD,OAAK,aAAa;AAClB,OAAK,MAAM;AACX,OAAK,YAAY;;;AAIrB,SAAgB,uBAAuB,OAA+C;AACpF,QAAO,iBAAiB,SAAS,MAAM,KAAK,WAAW,uBAAuB;;;AAIhF,IAAa,0BAAb,cAA6C,qBAAqB;CAChE,OAAO;;AAGT,SAAgB,0BAA0B,OAAkD;AAC1F,QAAO,iBAAiB,SAAS,MAAM,SAAS;;;;;;;AAQlD,IAAa,gBAAb,cAAmC,MAAM;CACvC,OAAO;;AAGT,SAAgB,gBAAgB,OAAwC;AACtE,QAAO,iBAAiB,SAAS,MAAM,SAAS"}
@@ -1,23 +1,26 @@
1
- export declare class DownloadNetworkError extends Error {
2
- name: string;
3
- statusCode: number;
4
- url: string;
5
- beginning: string;
6
- constructor(statusCode: number, url: string, beginning: string);
1
+ //#region src/helpers/download_errors.d.ts
2
+ declare class DownloadNetworkError extends Error {
3
+ name: string;
4
+ statusCode: number;
5
+ url: string;
6
+ beginning: string;
7
+ constructor(statusCode: number, url: string, beginning: string);
7
8
  }
8
- export declare function isDownloadNetworkError(error: unknown): error is DownloadNetworkError;
9
+ declare function isDownloadNetworkError(error: unknown): error is DownloadNetworkError;
9
10
  /** Throws when a status code of the downloading URL was in range [400, 500). */
10
- export declare class DownloadNetworkError400 extends DownloadNetworkError {
11
- name: string;
11
+ declare class DownloadNetworkError400 extends DownloadNetworkError {
12
+ name: string;
12
13
  }
13
- export declare function isDownloadNetworkError400(error: unknown): error is DownloadNetworkError400;
14
+ declare function isDownloadNetworkError400(error: unknown): error is DownloadNetworkError400;
14
15
  /**
15
16
  * There are backend versions that return 1 less byte than requested in range.
16
17
  * For such cases, this error will be thrown, so client can retry the request.
17
18
  * Dowloader will retry the request with one more byte in range.
18
19
  */
19
- export declare class OffByOneError extends Error {
20
- name: string;
20
+ declare class OffByOneError extends Error {
21
+ name: string;
21
22
  }
22
- export declare function isOffByOneError(error: unknown): error is OffByOneError;
23
+ declare function isOffByOneError(error: unknown): error is OffByOneError;
24
+ //#endregion
25
+ export { DownloadNetworkError, DownloadNetworkError400, OffByOneError, isDownloadNetworkError, isDownloadNetworkError400, isOffByOneError };
23
26
  //# sourceMappingURL=download_errors.d.ts.map