@protontech/drive-sdk 0.1.0 → 0.1.1

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 (447) hide show
  1. package/dist/cache/memoryCache.js +0 -1
  2. package/dist/cache/memoryCache.js.map +1 -1
  3. package/dist/cache/memoryCache.test.js +2 -4
  4. package/dist/cache/memoryCache.test.js.map +1 -1
  5. package/dist/cache/nullCache.js +0 -1
  6. package/dist/cache/nullCache.js.map +1 -1
  7. package/dist/crypto/driveCrypto.d.ts +2 -5
  8. package/dist/crypto/driveCrypto.js +7 -12
  9. package/dist/crypto/driveCrypto.js.map +1 -1
  10. package/dist/crypto/driveCrypto.test.js +14 -14
  11. package/dist/crypto/openPGPCrypto.js +3 -3
  12. package/dist/crypto/openPGPCrypto.js.map +1 -1
  13. package/dist/diagnostic/eventsGenerator.js +1 -1
  14. package/dist/diagnostic/eventsGenerator.js.map +1 -1
  15. package/dist/diagnostic/httpClient.d.ts +1 -1
  16. package/dist/diagnostic/httpClient.js.map +1 -1
  17. package/dist/diagnostic/index.d.ts +3 -3
  18. package/dist/diagnostic/index.js.map +1 -1
  19. package/dist/diagnostic/integrityVerificationStream.js +1 -1
  20. package/dist/diagnostic/integrityVerificationStream.js.map +1 -1
  21. package/dist/diagnostic/interface.d.ts +2 -2
  22. package/dist/diagnostic/sdkDiagnostic.d.ts +3 -3
  23. package/dist/diagnostic/sdkDiagnostic.js +8 -2
  24. package/dist/diagnostic/sdkDiagnostic.js.map +1 -1
  25. package/dist/diagnostic/sdkDiagnosticFull.d.ts +4 -4
  26. package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -1
  27. package/dist/diagnostic/telemetry.js.map +1 -1
  28. package/dist/diagnostic/zipGenerators.js +2 -2
  29. package/dist/diagnostic/zipGenerators.js.map +1 -1
  30. package/dist/diagnostic/zipGenerators.test.js +1 -1
  31. package/dist/diagnostic/zipGenerators.test.js.map +1 -1
  32. package/dist/interface/events.d.ts +2 -4
  33. package/dist/interface/events.js.map +1 -1
  34. package/dist/interface/index.d.ts +5 -5
  35. package/dist/interface/index.js +0 -1
  36. package/dist/interface/index.js.map +1 -1
  37. package/dist/interface/result.js.map +1 -1
  38. package/dist/interface/sharing.d.ts +1 -0
  39. package/dist/interface/sharing.js.map +1 -1
  40. package/dist/interface/telemetry.js +0 -8
  41. package/dist/interface/telemetry.js.map +1 -1
  42. package/dist/interface/thumbnail.js.map +1 -1
  43. package/dist/interface/upload.d.ts +1 -1
  44. package/dist/internal/apiService/apiService.d.ts +1 -1
  45. package/dist/internal/apiService/apiService.js +7 -11
  46. package/dist/internal/apiService/apiService.js.map +1 -1
  47. package/dist/internal/apiService/apiService.test.js +55 -48
  48. package/dist/internal/apiService/apiService.test.js.map +1 -1
  49. package/dist/internal/apiService/coreTypes.d.ts +2356 -2356
  50. package/dist/internal/apiService/driveTypes.d.ts +1680 -1680
  51. package/dist/internal/apiService/errors.js +14 -8
  52. package/dist/internal/apiService/errors.js.map +1 -1
  53. package/dist/internal/apiService/errors.test.js +17 -12
  54. package/dist/internal/apiService/errors.test.js.map +1 -1
  55. package/dist/internal/apiService/transformers.d.ts +1 -1
  56. package/dist/internal/apiService/transformers.js +1 -1
  57. package/dist/internal/asyncIteratorMap.test.js +2 -2
  58. package/dist/internal/asyncIteratorMap.test.js.map +1 -1
  59. package/dist/internal/asyncIteratorRace.d.ts +13 -0
  60. package/dist/internal/asyncIteratorRace.js +59 -0
  61. package/dist/internal/asyncIteratorRace.js.map +1 -0
  62. package/dist/internal/asyncIteratorRace.test.d.ts +1 -0
  63. package/dist/internal/asyncIteratorRace.test.js +119 -0
  64. package/dist/internal/asyncIteratorRace.test.js.map +1 -0
  65. package/dist/internal/batch.d.ts +1 -0
  66. package/dist/internal/batch.js +12 -0
  67. package/dist/internal/batch.js.map +1 -0
  68. package/dist/internal/batch.test.d.ts +1 -0
  69. package/dist/internal/batch.test.js +41 -0
  70. package/dist/internal/batch.test.js.map +1 -0
  71. package/dist/internal/batchLoading.js.map +1 -1
  72. package/dist/internal/batchLoading.test.js +13 -13
  73. package/dist/internal/batchLoading.test.js.map +1 -1
  74. package/dist/internal/devices/apiService.d.ts +3 -3
  75. package/dist/internal/devices/apiService.js +2 -2
  76. package/dist/internal/devices/apiService.js.map +1 -1
  77. package/dist/internal/devices/cryptoService.js +1 -2
  78. package/dist/internal/devices/cryptoService.js.map +1 -1
  79. package/dist/internal/devices/index.d.ts +5 -5
  80. package/dist/internal/devices/index.js.map +1 -1
  81. package/dist/internal/devices/interface.d.ts +3 -3
  82. package/dist/internal/devices/manager.js +2 -2
  83. package/dist/internal/devices/manager.js.map +1 -1
  84. package/dist/internal/devices/manager.test.js +38 -7
  85. package/dist/internal/devices/manager.test.js.map +1 -1
  86. package/dist/internal/download/apiService.d.ts +4 -4
  87. package/dist/internal/download/apiService.js +0 -1
  88. package/dist/internal/download/apiService.js.map +1 -1
  89. package/dist/internal/download/cryptoService.d.ts +4 -4
  90. package/dist/internal/download/cryptoService.js +6 -5
  91. package/dist/internal/download/cryptoService.js.map +1 -1
  92. package/dist/internal/download/fileDownloader.d.ts +4 -4
  93. package/dist/internal/download/fileDownloader.js +3 -2
  94. package/dist/internal/download/fileDownloader.js.map +1 -1
  95. package/dist/internal/download/fileDownloader.test.js +1 -1
  96. package/dist/internal/download/fileDownloader.test.js.map +1 -1
  97. package/dist/internal/download/index.d.ts +5 -5
  98. package/dist/internal/download/index.js +5 -5
  99. package/dist/internal/download/index.js.map +1 -1
  100. package/dist/internal/download/interface.d.ts +3 -4
  101. package/dist/internal/download/telemetry.d.ts +3 -3
  102. package/dist/internal/download/telemetry.js +4 -2
  103. package/dist/internal/download/telemetry.js.map +1 -1
  104. package/dist/internal/download/telemetry.test.js +8 -8
  105. package/dist/internal/download/telemetry.test.js.map +1 -1
  106. package/dist/internal/download/thumbnailDownloader.d.ts +4 -4
  107. package/dist/internal/download/thumbnailDownloader.js +6 -6
  108. package/dist/internal/download/thumbnailDownloader.js.map +1 -1
  109. package/dist/internal/download/thumbnailDownloader.test.js.map +1 -1
  110. package/dist/internal/errors.d.ts +1 -1
  111. package/dist/internal/errors.js +1 -3
  112. package/dist/internal/errors.js.map +1 -1
  113. package/dist/internal/events/apiService.d.ts +2 -2
  114. package/dist/internal/events/apiService.js +9 -5
  115. package/dist/internal/events/apiService.js.map +1 -1
  116. package/dist/internal/events/coreEventManager.d.ts +3 -3
  117. package/dist/internal/events/coreEventManager.js.map +1 -1
  118. package/dist/internal/events/coreEventManager.test.js +14 -14
  119. package/dist/internal/events/eventManager.d.ts +1 -1
  120. package/dist/internal/events/eventManager.js +0 -1
  121. package/dist/internal/events/eventManager.js.map +1 -1
  122. package/dist/internal/events/eventManager.test.js +34 -25
  123. package/dist/internal/events/eventManager.test.js.map +1 -1
  124. package/dist/internal/events/index.d.ts +6 -6
  125. package/dist/internal/events/index.js.map +1 -1
  126. package/dist/internal/events/interface.d.ts +1 -1
  127. package/dist/internal/events/interface.js +0 -1
  128. package/dist/internal/events/interface.js.map +1 -1
  129. package/dist/internal/events/volumeEventManager.d.ts +3 -3
  130. package/dist/internal/events/volumeEventManager.js.map +1 -1
  131. package/dist/internal/events/volumeEventManager.test.js +55 -55
  132. package/dist/internal/events/volumeEventManager.test.js.map +1 -1
  133. package/dist/internal/nodes/apiService.d.ts +4 -3
  134. package/dist/internal/nodes/apiService.js +36 -15
  135. package/dist/internal/nodes/apiService.js.map +1 -1
  136. package/dist/internal/nodes/apiService.test.js +60 -41
  137. package/dist/internal/nodes/apiService.test.js.map +1 -1
  138. package/dist/internal/nodes/cache.d.ts +5 -5
  139. package/dist/internal/nodes/cache.js +14 -7
  140. package/dist/internal/nodes/cache.js.map +1 -1
  141. package/dist/internal/nodes/cache.test.js +31 -9
  142. package/dist/internal/nodes/cache.test.js.map +1 -1
  143. package/dist/internal/nodes/cryptoCache.d.ts +2 -2
  144. package/dist/internal/nodes/cryptoCache.js.map +1 -1
  145. package/dist/internal/nodes/cryptoCache.test.js +24 -4
  146. package/dist/internal/nodes/cryptoCache.test.js.map +1 -1
  147. package/dist/internal/nodes/cryptoService.d.ts +3 -3
  148. package/dist/internal/nodes/cryptoService.js +11 -17
  149. package/dist/internal/nodes/cryptoService.js.map +1 -1
  150. package/dist/internal/nodes/cryptoService.test.js +320 -241
  151. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  152. package/dist/internal/nodes/events.d.ts +3 -3
  153. package/dist/internal/nodes/events.js.map +1 -1
  154. package/dist/internal/nodes/events.test.js +27 -21
  155. package/dist/internal/nodes/events.test.js.map +1 -1
  156. package/dist/internal/nodes/extendedAttributes.d.ts +1 -1
  157. package/dist/internal/nodes/extendedAttributes.js +3 -1
  158. package/dist/internal/nodes/extendedAttributes.js.map +1 -1
  159. package/dist/internal/nodes/extendedAttributes.test.js +7 -10
  160. package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
  161. package/dist/internal/nodes/index.d.ts +10 -10
  162. package/dist/internal/nodes/index.js.map +1 -1
  163. package/dist/internal/nodes/index.test.d.ts +1 -0
  164. package/dist/internal/nodes/index.test.js +106 -0
  165. package/dist/internal/nodes/index.test.js.map +1 -0
  166. package/dist/internal/nodes/interface.d.ts +2 -2
  167. package/dist/internal/nodes/nodesAccess.d.ts +7 -7
  168. package/dist/internal/nodes/nodesAccess.js +28 -16
  169. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  170. package/dist/internal/nodes/nodesAccess.test.js +39 -13
  171. package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
  172. package/dist/internal/nodes/nodesManagement.d.ts +6 -6
  173. package/dist/internal/nodes/nodesManagement.js +9 -7
  174. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  175. package/dist/internal/nodes/nodesManagement.test.js +9 -9
  176. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  177. package/dist/internal/nodes/nodesRevisions.d.ts +4 -4
  178. package/dist/internal/nodes/nodesRevisions.js.map +1 -1
  179. package/dist/internal/photos/albums.d.ts +3 -3
  180. package/dist/internal/photos/albums.js.map +1 -1
  181. package/dist/internal/photos/apiService.d.ts +1 -1
  182. package/dist/internal/photos/apiService.js +3 -6
  183. package/dist/internal/photos/apiService.js.map +1 -1
  184. package/dist/internal/photos/cache.d.ts +1 -1
  185. package/dist/internal/photos/index.d.ts +5 -5
  186. package/dist/internal/photos/index.js.map +1 -1
  187. package/dist/internal/photos/interface.d.ts +2 -2
  188. package/dist/internal/photos/photosTimeline.d.ts +3 -3
  189. package/dist/internal/photos/photosTimeline.js +1 -2
  190. package/dist/internal/photos/photosTimeline.js.map +1 -1
  191. package/dist/internal/sdkEvents.d.ts +1 -1
  192. package/dist/internal/sdkEvents.js +2 -7
  193. package/dist/internal/sdkEvents.js.map +1 -1
  194. package/dist/internal/sdkEvents.test.js +8 -8
  195. package/dist/internal/shares/apiService.d.ts +2 -2
  196. package/dist/internal/shares/apiService.js +5 -3
  197. package/dist/internal/shares/apiService.js.map +1 -1
  198. package/dist/internal/shares/cache.d.ts +2 -2
  199. package/dist/internal/shares/cache.js +12 -6
  200. package/dist/internal/shares/cache.js.map +1 -1
  201. package/dist/internal/shares/cache.test.js.map +1 -1
  202. package/dist/internal/shares/cryptoCache.d.ts +2 -2
  203. package/dist/internal/shares/cryptoCache.test.js +8 -2
  204. package/dist/internal/shares/cryptoCache.test.js.map +1 -1
  205. package/dist/internal/shares/cryptoService.d.ts +3 -3
  206. package/dist/internal/shares/cryptoService.js.map +1 -1
  207. package/dist/internal/shares/cryptoService.test.js +42 -42
  208. package/dist/internal/shares/cryptoService.test.js.map +1 -1
  209. package/dist/internal/shares/index.d.ts +4 -4
  210. package/dist/internal/shares/index.js.map +1 -1
  211. package/dist/internal/shares/interface.d.ts +2 -2
  212. package/dist/internal/shares/manager.d.ts +7 -7
  213. package/dist/internal/shares/manager.js.map +1 -1
  214. package/dist/internal/shares/manager.test.js +71 -63
  215. package/dist/internal/shares/manager.test.js.map +1 -1
  216. package/dist/internal/sharing/apiService.d.ts +4 -4
  217. package/dist/internal/sharing/apiService.js +4 -3
  218. package/dist/internal/sharing/apiService.js.map +1 -1
  219. package/dist/internal/sharing/cache.d.ts +1 -1
  220. package/dist/internal/sharing/cache.test.js +33 -33
  221. package/dist/internal/sharing/cryptoService.d.ts +3 -3
  222. package/dist/internal/sharing/cryptoService.js +3 -5
  223. package/dist/internal/sharing/cryptoService.js.map +1 -1
  224. package/dist/internal/sharing/cryptoService.test.js +39 -39
  225. package/dist/internal/sharing/cryptoService.test.js.map +1 -1
  226. package/dist/internal/sharing/events.d.ts +4 -4
  227. package/dist/internal/sharing/events.js +0 -1
  228. package/dist/internal/sharing/events.js.map +1 -1
  229. package/dist/internal/sharing/events.test.js +39 -40
  230. package/dist/internal/sharing/events.test.js.map +1 -1
  231. package/dist/internal/sharing/index.d.ts +6 -6
  232. package/dist/internal/sharing/index.js.map +1 -1
  233. package/dist/internal/sharing/interface.d.ts +5 -4
  234. package/dist/internal/sharing/sharingAccess.d.ts +6 -6
  235. package/dist/internal/sharing/sharingAccess.js +8 -4
  236. package/dist/internal/sharing/sharingAccess.js.map +1 -1
  237. package/dist/internal/sharing/sharingAccess.test.js +45 -39
  238. package/dist/internal/sharing/sharingAccess.test.js.map +1 -1
  239. package/dist/internal/sharing/sharingManagement.d.ts +4 -4
  240. package/dist/internal/sharing/sharingManagement.js +5 -7
  241. package/dist/internal/sharing/sharingManagement.js.map +1 -1
  242. package/dist/internal/sharing/sharingManagement.test.js +297 -248
  243. package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
  244. package/dist/internal/uids.js.map +1 -1
  245. package/dist/internal/upload/apiService.d.ts +3 -3
  246. package/dist/internal/upload/apiService.js +1 -1
  247. package/dist/internal/upload/apiService.js.map +1 -1
  248. package/dist/internal/upload/blockVerifier.d.ts +3 -3
  249. package/dist/internal/upload/blockVerifier.js +1 -1
  250. package/dist/internal/upload/blockVerifier.js.map +1 -1
  251. package/dist/internal/upload/chunkStreamReader.test.js +6 -6
  252. package/dist/internal/upload/cryptoService.d.ts +4 -4
  253. package/dist/internal/upload/cryptoService.js +4 -4
  254. package/dist/internal/upload/cryptoService.js.map +1 -1
  255. package/dist/internal/upload/digests.js.map +1 -1
  256. package/dist/internal/upload/fileUploader.d.ts +6 -6
  257. package/dist/internal/upload/fileUploader.js.map +1 -1
  258. package/dist/internal/upload/fileUploader.test.js.map +1 -1
  259. package/dist/internal/upload/index.d.ts +5 -5
  260. package/dist/internal/upload/index.js.map +1 -1
  261. package/dist/internal/upload/interface.d.ts +3 -3
  262. package/dist/internal/upload/manager.d.ts +4 -4
  263. package/dist/internal/upload/manager.js +7 -5
  264. package/dist/internal/upload/manager.js.map +1 -1
  265. package/dist/internal/upload/manager.test.js +137 -123
  266. package/dist/internal/upload/manager.test.js.map +1 -1
  267. package/dist/internal/upload/streamUploader.d.ts +6 -6
  268. package/dist/internal/upload/streamUploader.js +8 -6
  269. package/dist/internal/upload/streamUploader.js.map +1 -1
  270. package/dist/internal/upload/streamUploader.test.js +16 -11
  271. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  272. package/dist/internal/upload/telemetry.d.ts +3 -3
  273. package/dist/internal/upload/telemetry.js +5 -3
  274. package/dist/internal/upload/telemetry.js.map +1 -1
  275. package/dist/internal/upload/telemetry.test.js +8 -8
  276. package/dist/internal/upload/telemetry.test.js.map +1 -1
  277. package/dist/protonDriveClient.d.ts +8 -8
  278. package/dist/protonDriveClient.js +12 -9
  279. package/dist/protonDriveClient.js.map +1 -1
  280. package/dist/protonDrivePhotosClient.js.map +1 -1
  281. package/dist/telemetry.js +18 -15
  282. package/dist/telemetry.js.map +1 -1
  283. package/dist/tests/logger.js.map +1 -1
  284. package/dist/tests/telemetry.d.ts +1 -1
  285. package/dist/transformers.js +4 -2
  286. package/dist/transformers.js.map +1 -1
  287. package/package.json +1 -1
  288. package/src/cache/interface.ts +22 -22
  289. package/src/cache/memoryCache.test.ts +7 -7
  290. package/src/cache/memoryCache.ts +4 -4
  291. package/src/cache/nullCache.ts +1 -1
  292. package/src/config.ts +5 -5
  293. package/src/crypto/driveCrypto.test.ts +15 -15
  294. package/src/crypto/driveCrypto.ts +120 -156
  295. package/src/crypto/hmac.ts +1 -1
  296. package/src/crypto/interface.ts +63 -72
  297. package/src/crypto/openPGPCrypto.ts +74 -94
  298. package/src/crypto/utils.ts +1 -1
  299. package/src/diagnostic/eventsGenerator.ts +2 -2
  300. package/src/diagnostic/httpClient.ts +6 -2
  301. package/src/diagnostic/index.ts +12 -10
  302. package/src/diagnostic/integrityVerificationStream.ts +3 -4
  303. package/src/diagnostic/interface.ts +81 -81
  304. package/src/diagnostic/sdkDiagnostic.ts +35 -24
  305. package/src/diagnostic/sdkDiagnosticFull.ts +16 -19
  306. package/src/diagnostic/telemetry.ts +4 -1
  307. package/src/diagnostic/zipGenerators.test.ts +1 -1
  308. package/src/diagnostic/zipGenerators.ts +3 -3
  309. package/src/errors.ts +21 -21
  310. package/src/index.ts +3 -3
  311. package/src/interface/account.ts +10 -10
  312. package/src/interface/author.ts +6 -6
  313. package/src/interface/config.ts +4 -4
  314. package/src/interface/devices.ts +6 -6
  315. package/src/interface/download.ts +12 -9
  316. package/src/interface/events.ts +45 -39
  317. package/src/interface/httpClient.ts +11 -11
  318. package/src/interface/index.ts +76 -19
  319. package/src/interface/nodes.ts +47 -49
  320. package/src/interface/result.ts +1 -3
  321. package/src/interface/sharing.ts +60 -57
  322. package/src/interface/telemetry.ts +74 -74
  323. package/src/interface/thumbnail.ts +5 -6
  324. package/src/interface/upload.ts +20 -12
  325. package/src/internal/apiService/apiService.test.ts +109 -76
  326. package/src/internal/apiService/apiService.ts +40 -26
  327. package/src/internal/apiService/coreTypes.ts +2474 -2463
  328. package/src/internal/apiService/driveTypes.ts +1868 -1822
  329. package/src/internal/apiService/errorCodes.ts +4 -4
  330. package/src/internal/apiService/errors.test.ts +25 -23
  331. package/src/internal/apiService/errors.ts +15 -9
  332. package/src/internal/apiService/index.ts +1 -1
  333. package/src/internal/apiService/transformers.ts +2 -2
  334. package/src/internal/asyncIteratorMap.test.ts +4 -4
  335. package/src/internal/asyncIteratorMap.ts +1 -1
  336. package/src/internal/asyncIteratorRace.test.ts +149 -0
  337. package/src/internal/asyncIteratorRace.ts +79 -0
  338. package/src/internal/batch.test.ts +50 -0
  339. package/src/internal/batch.ts +9 -0
  340. package/src/internal/batchLoading.test.ts +13 -14
  341. package/src/internal/batchLoading.ts +8 -8
  342. package/src/internal/devices/apiService.ts +58 -51
  343. package/src/internal/devices/cryptoService.ts +22 -17
  344. package/src/internal/devices/index.ts +17 -10
  345. package/src/internal/devices/interface.ts +21 -12
  346. package/src/internal/devices/manager.test.ts +40 -9
  347. package/src/internal/devices/manager.ts +3 -3
  348. package/src/internal/download/apiService.ts +66 -49
  349. package/src/internal/download/cryptoService.ts +34 -18
  350. package/src/internal/download/fileDownloader.test.ts +25 -9
  351. package/src/internal/download/fileDownloader.ts +36 -18
  352. package/src/internal/download/index.ts +19 -19
  353. package/src/internal/download/interface.ts +19 -20
  354. package/src/internal/download/queue.ts +3 -3
  355. package/src/internal/download/telemetry.test.ts +11 -11
  356. package/src/internal/download/telemetry.ts +24 -14
  357. package/src/internal/download/thumbnailDownloader.test.ts +11 -6
  358. package/src/internal/download/thumbnailDownloader.ts +43 -32
  359. package/src/internal/errors.ts +7 -5
  360. package/src/internal/events/apiService.ts +30 -17
  361. package/src/internal/events/coreEventManager.test.ts +18 -18
  362. package/src/internal/events/coreEventManager.ts +9 -6
  363. package/src/internal/events/eventManager.test.ts +51 -46
  364. package/src/internal/events/eventManager.ts +6 -5
  365. package/src/internal/events/index.ts +24 -14
  366. package/src/internal/events/interface.ts +47 -39
  367. package/src/internal/events/volumeEventManager.test.ts +61 -65
  368. package/src/internal/events/volumeEventManager.ts +18 -9
  369. package/src/internal/nodes/apiService.test.ts +197 -147
  370. package/src/internal/nodes/apiService.ts +288 -174
  371. package/src/internal/nodes/cache.test.ts +48 -20
  372. package/src/internal/nodes/cache.ts +60 -44
  373. package/src/internal/nodes/cryptoCache.test.ts +34 -14
  374. package/src/internal/nodes/cryptoCache.ts +10 -5
  375. package/src/internal/nodes/cryptoService.test.ts +492 -351
  376. package/src/internal/nodes/cryptoService.ts +170 -88
  377. package/src/internal/nodes/events.test.ts +38 -28
  378. package/src/internal/nodes/events.ts +7 -5
  379. package/src/internal/nodes/extendedAttributes.test.ts +28 -24
  380. package/src/internal/nodes/extendedAttributes.ts +20 -15
  381. package/src/internal/nodes/index.test.ts +133 -0
  382. package/src/internal/nodes/index.ts +27 -15
  383. package/src/internal/nodes/interface.ts +42 -29
  384. package/src/internal/nodes/nodesAccess.test.ts +124 -58
  385. package/src/internal/nodes/nodesAccess.ts +73 -49
  386. package/src/internal/nodes/nodesManagement.test.ts +32 -31
  387. package/src/internal/nodes/nodesManagement.ts +39 -32
  388. package/src/internal/nodes/nodesRevisions.ts +7 -7
  389. package/src/internal/nodes/validations.ts +2 -2
  390. package/src/internal/photos/albums.ts +5 -5
  391. package/src/internal/photos/apiService.ts +4 -7
  392. package/src/internal/photos/cache.ts +1 -1
  393. package/src/internal/photos/index.ts +8 -8
  394. package/src/internal/photos/interface.ts +2 -2
  395. package/src/internal/photos/photosTimeline.ts +4 -5
  396. package/src/internal/sdkEvents.test.ts +10 -10
  397. package/src/internal/sdkEvents.ts +5 -13
  398. package/src/internal/shares/apiService.ts +44 -33
  399. package/src/internal/shares/cache.test.ts +6 -4
  400. package/src/internal/shares/cache.ts +21 -12
  401. package/src/internal/shares/cryptoCache.test.ts +17 -11
  402. package/src/internal/shares/cryptoCache.ts +4 -4
  403. package/src/internal/shares/cryptoService.test.ts +72 -74
  404. package/src/internal/shares/cryptoService.ts +48 -23
  405. package/src/internal/shares/index.ts +23 -11
  406. package/src/internal/shares/interface.ts +8 -8
  407. package/src/internal/shares/manager.test.ts +88 -80
  408. package/src/internal/shares/manager.ts +19 -19
  409. package/src/internal/sharing/apiService.ts +282 -175
  410. package/src/internal/sharing/cache.test.ts +35 -35
  411. package/src/internal/sharing/cache.ts +2 -2
  412. package/src/internal/sharing/cryptoService.test.ts +58 -46
  413. package/src/internal/sharing/cryptoService.ts +121 -84
  414. package/src/internal/sharing/events.test.ts +45 -49
  415. package/src/internal/sharing/events.ts +9 -6
  416. package/src/internal/sharing/index.ts +22 -11
  417. package/src/internal/sharing/interface.ts +40 -40
  418. package/src/internal/sharing/sharingAccess.test.ts +71 -65
  419. package/src/internal/sharing/sharingAccess.ts +39 -21
  420. package/src/internal/sharing/sharingManagement.test.ts +398 -298
  421. package/src/internal/sharing/sharingManagement.ts +138 -65
  422. package/src/internal/uids.ts +1 -1
  423. package/src/internal/upload/apiService.ts +167 -117
  424. package/src/internal/upload/blockVerifier.ts +8 -6
  425. package/src/internal/upload/chunkStreamReader.test.ts +7 -7
  426. package/src/internal/upload/cryptoService.ts +42 -36
  427. package/src/internal/upload/digests.ts +2 -2
  428. package/src/internal/upload/fileUploader.test.ts +15 -3
  429. package/src/internal/upload/fileUploader.ts +39 -17
  430. package/src/internal/upload/index.ts +13 -14
  431. package/src/internal/upload/interface.ts +78 -78
  432. package/src/internal/upload/manager.test.ts +170 -153
  433. package/src/internal/upload/manager.ts +59 -35
  434. package/src/internal/upload/queue.ts +3 -3
  435. package/src/internal/upload/streamUploader.test.ts +40 -26
  436. package/src/internal/upload/streamUploader.ts +87 -69
  437. package/src/internal/upload/telemetry.test.ts +11 -11
  438. package/src/internal/upload/telemetry.ts +25 -15
  439. package/src/internal/wait.test.ts +1 -1
  440. package/src/internal/wait.ts +3 -3
  441. package/src/protonDriveClient.ts +121 -39
  442. package/src/protonDrivePhotosClient.ts +16 -10
  443. package/src/telemetry.ts +60 -52
  444. package/src/tests/logger.ts +1 -1
  445. package/src/tests/telemetry.ts +2 -2
  446. package/src/transformers.ts +27 -21
  447. package/src/version.ts +0 -1
@@ -22,16 +22,16 @@ export const enum ErrorCode {
22
22
  // Following codes takes name from the API documentation.
23
23
  ALREADY_EXISTS = 2500,
24
24
  NOT_EXISTS = 2501,
25
- INSUFFICIENT_QUOTA = 200001,
25
+ INSUFFICIENT_QUOTA = 200001,
26
26
  INSUFFICIENT_SPACE = 200002,
27
27
  MAX_FILE_SIZE_FOR_FREE_USER = 200003,
28
28
  MAX_PUBLIC_EDIT_MODE_FOR_FREE_USER = 200004,
29
- INSUFFICIENT_VOLUME_QUOTA= 200100,
30
- INSUFFICIENT_DEVICE_QUOTA= 200101,
29
+ INSUFFICIENT_VOLUME_QUOTA = 200100,
30
+ INSUFFICIENT_DEVICE_QUOTA = 200101,
31
31
  ALREADY_MEMBER_OF_SHARE_IN_VOLUME_WITH_ANOTHER_ADDRESS = 200201,
32
32
  TOO_MANY_CHILDREN = 200300,
33
33
  NESTING_TOO_DEEP = 200301,
34
- INSUFFICIENT_INVITATION_QUOTA = 200600,
34
+ INSUFFICIENT_INVITATION_QUOTA = 200600,
35
35
  INSUFFICIENT_SHARE_QUOTA = 200601,
36
36
  INSUFFICIENT_SHARE_JOINED_QUOTA = 200602,
37
37
  INSUFFICIENT_BOOKMARKS_QUOTA = 200800,
@@ -1,19 +1,14 @@
1
- import { apiErrorFactory } from "./errors";
2
- import * as errors from "./errors";
1
+ import { apiErrorFactory } from './errors';
2
+ import * as errors from './errors';
3
3
  import { ErrorCode } from './errorCodes';
4
4
 
5
5
  function mockAPIResponseAndResult(options: {
6
- httpStatusCode?: number,
7
- httpStatusText?: string,
8
- code: number,
9
- message?: string,
6
+ httpStatusCode?: number;
7
+ httpStatusText?: string;
8
+ code: number;
9
+ message?: string;
10
10
  }) {
11
- const {
12
- httpStatusCode = 422,
13
- httpStatusText = 'Unprocessable Entity',
14
- code,
15
- message = 'API error',
16
- } = options;
11
+ const { httpStatusCode = 422, httpStatusText = 'Unprocessable Entity', code, message = 'API error' } = options;
17
12
 
18
13
  const result = { Code: code, Error: message };
19
14
  const response = new Response(JSON.stringify(result), { status: httpStatusCode, statusText: httpStatusText });
@@ -21,43 +16,50 @@ function mockAPIResponseAndResult(options: {
21
16
  return { response, result };
22
17
  }
23
18
 
24
- describe("apiErrorFactory should return", () => {
25
- it("generic APIHTTPError when there is no specifc body", () => {
19
+ describe('apiErrorFactory should return', () => {
20
+ it('generic APIHTTPError when there is no specifc body', () => {
26
21
  const response = new Response('', { status: 404, statusText: 'Not found' });
27
22
  const error = apiErrorFactory({ response });
28
23
  expect(error).toBeInstanceOf(errors.APIHTTPError);
29
- expect(error.message).toBe("Not found");
24
+ expect(error.message).toBe('Not found');
30
25
  expect((error as errors.APIHTTPError).statusCode).toBe(404);
31
26
  });
32
27
 
33
- it("generic APIHTTPError with generic message when there is no specifc statusText", () => {
28
+ it('generic APIHTTPError with generic message when there is no specifc statusText', () => {
34
29
  const response = new Response('', { status: 404, statusText: '' });
35
30
  const error = apiErrorFactory({ response });
36
31
  expect(error).toBeInstanceOf(errors.APIHTTPError);
37
- expect(error.message).toBe("Unknown error");
32
+ expect(error.message).toBe('Unknown error');
38
33
  expect((error as errors.APIHTTPError).statusCode).toBe(404);
39
34
  });
40
35
 
41
- it("generic APIHTTPError when there 404 both in status code and body code", () => {
42
- const error = apiErrorFactory(mockAPIResponseAndResult({ httpStatusCode: 404, httpStatusText: 'Path not found', code: 404, message: 'Not found' }));
36
+ it('generic APIHTTPError when there 404 both in status code and body code', () => {
37
+ const error = apiErrorFactory(
38
+ mockAPIResponseAndResult({
39
+ httpStatusCode: 404,
40
+ httpStatusText: 'Path not found',
41
+ code: 404,
42
+ message: 'Not found',
43
+ }),
44
+ );
43
45
  expect(error).toBeInstanceOf(errors.APIHTTPError);
44
- expect(error.message).toBe("Path not found");
46
+ expect(error.message).toBe('Path not found');
45
47
  expect((error as errors.APIHTTPError).statusCode).toBe(404);
46
48
  });
47
49
 
48
- it("generic APICodeError when there is body even if wrong", () => {
50
+ it('generic APICodeError when there is body even if wrong', () => {
49
51
  const result = {};
50
52
  const response = new Response('', { status: 422 });
51
53
  const error = apiErrorFactory({ response, result });
52
54
  expectAPICodeError(error, 0, 'Unknown error');
53
55
  });
54
56
 
55
- it("generic APICodeError when there is body but not specific handle", () => {
57
+ it('generic APICodeError when there is body but not specific handle', () => {
56
58
  const error = apiErrorFactory(mockAPIResponseAndResult({ code: 42, message: 'General error' }));
57
59
  expectAPICodeError(error, 42, 'General error');
58
60
  });
59
61
 
60
- it("NotFoundAPIError when code is ErrorCode.NOT_EXISTS", () => {
62
+ it('NotFoundAPIError when code is ErrorCode.NOT_EXISTS', () => {
61
63
  const error = apiErrorFactory(mockAPIResponseAndResult({ code: ErrorCode.NOT_EXISTS, message: 'Not found' }));
62
64
  expect(error).toBeInstanceOf(errors.NotFoundAPIError);
63
65
  expectAPICodeError(error, ErrorCode.NOT_EXISTS, 'Not found');
@@ -3,7 +3,7 @@ import { c } from 'ttag';
3
3
  import { ServerError, ValidationError } from '../../errors';
4
4
  import { ErrorCode, HTTPErrorCode } from './errorCodes';
5
5
 
6
- export function apiErrorFactory({ response, result }: { response: Response, result?: unknown }): ServerError {
6
+ export function apiErrorFactory({ response, result }: { response: Response; result?: unknown }): ServerError {
7
7
  // Backend responses with 404 both in the response and body code.
8
8
  // In such a case we want to stick to APIHTTPError to be very clear
9
9
  // it is not NotFoundAPIError.
@@ -22,15 +22,21 @@ export function apiErrorFactory({ response, result }: { response: Response, resu
22
22
  trace?: object;
23
23
  };
24
24
 
25
- const [code, message, details] = [typedResult.Code || 0, typedResult.Error || c('Error').t`Unknown error`, typedResult.Details];
25
+ const [code, message, details] = [
26
+ typedResult.Code || 0,
27
+ typedResult.Error || c('Error').t`Unknown error`,
28
+ typedResult.Details,
29
+ ];
26
30
 
27
- const debug = typedResult.exception ? {
28
- exception: typedResult.exception,
29
- message: typedResult.message,
30
- file: typedResult.file,
31
- line: typedResult.line,
32
- trace: typedResult.trace,
33
- } : undefined;
31
+ const debug = typedResult.exception
32
+ ? {
33
+ exception: typedResult.exception,
34
+ message: typedResult.message,
35
+ file: typedResult.file,
36
+ line: typedResult.line,
37
+ trace: typedResult.trace,
38
+ }
39
+ : undefined;
34
40
 
35
41
  switch (code) {
36
42
  case ErrorCode.NOT_EXISTS:
@@ -3,5 +3,5 @@ export type { paths as drivePaths } from './driveTypes';
3
3
  export type { paths as corePaths } from './coreTypes';
4
4
  export { HTTPErrorCode, ErrorCode, isCodeOk, isCodeOkAsync } from './errorCodes';
5
5
  export { nodeTypeNumberToNodeType, permissionsToDirectMemberRole, memberRoleToPermission } from './transformers';
6
- export { ObserverStream } from './observerStream';
6
+ export { ObserverStream } from './observerStream';
7
7
  export * from './errors';
@@ -1,4 +1,4 @@
1
- import { Logger, NodeType, MemberRole } from "../../interface";
1
+ import { Logger, NodeType, MemberRole } from '../../interface';
2
2
 
3
3
  export function nodeTypeNumberToNodeType(logger: Logger, nodeTypeNumber: number): NodeType {
4
4
  switch (nodeTypeNumber) {
@@ -34,7 +34,7 @@ export function permissionsToDirectMemberRole(logger: Logger, permissionsNumber?
34
34
  export function memberRoleToPermission(memberRole: MemberRole): 4 | 6 | 22 {
35
35
  if (memberRole === MemberRole.Inherited) {
36
36
  // This is developer error.
37
- throw new Error("Cannot convert inherited role to permission");
37
+ throw new Error('Cannot convert inherited role to permission');
38
38
  }
39
39
  switch (memberRole) {
40
40
  case MemberRole.Viewer:
@@ -52,7 +52,7 @@ describe('asyncIteratorMap', () => {
52
52
  const inputGen = createAsyncGenerator(Object.keys(delays).map(Number));
53
53
 
54
54
  const slowMapper = async (x: number) => {
55
- await new Promise(resolve => setTimeout(resolve, delays[x]));
55
+ await new Promise((resolve) => setTimeout(resolve, delays[x]));
56
56
  return x * 2;
57
57
  };
58
58
 
@@ -71,11 +71,11 @@ describe('asyncIteratorMap', () => {
71
71
  });
72
72
 
73
73
  test('handles errors from input iterator properly', async () => {
74
- const throwingInputGen = async function*() {
74
+ const throwingInputGen = async function* () {
75
75
  yield 1;
76
76
  yield 2;
77
77
  throw new Error('Error providing value: 3');
78
- }
78
+ };
79
79
 
80
80
  const mapper = async (x: number) => x * 2;
81
81
 
@@ -134,7 +134,7 @@ describe('asyncIteratorMap', () => {
134
134
  maxConcurrentExecutions = Math.max(maxConcurrentExecutions, concurrentExecutions);
135
135
 
136
136
  // Wait for 100ms to simulate work
137
- await new Promise(resolve => setTimeout(resolve, 100));
137
+ await new Promise((resolve) => setTimeout(resolve, 100));
138
138
 
139
139
  concurrentExecutions--;
140
140
  return x * 2;
@@ -8,7 +8,7 @@ const DEFAULT_CONCURRENCY = 10;
8
8
  *
9
9
  * Any error from the input iterator or the mapper function is propagated
10
10
  * to the output iterator.
11
- *
11
+ *
12
12
  * @param inputIterator - The input async iterator.
13
13
  * @param mapper - The mapper function that maps the input values to output values.
14
14
  * @param concurrency - The concurrency limit. How many parallel async mapper calls are allowed.
@@ -0,0 +1,149 @@
1
+ import { asyncIteratorRace } from './asyncIteratorRace';
2
+
3
+ async function* createInputIterator<T>(generators: AsyncGenerator<T>[]): AsyncGenerator<AsyncGenerator<T>> {
4
+ for (const generator of generators) {
5
+ yield generator;
6
+ }
7
+ }
8
+
9
+ async function* createAsyncGenerator<T>(values: T[], delay: number = 0): AsyncGenerator<T> {
10
+ for (const value of values) {
11
+ if (delay > 0) {
12
+ await new Promise((resolve) => setTimeout(resolve, delay));
13
+ }
14
+ yield value;
15
+ }
16
+ }
17
+
18
+ function createTrackingGenerator<T>(
19
+ values: T[],
20
+ trackingSet: Set<number>,
21
+ id: number,
22
+ delay: number = 10,
23
+ ): AsyncGenerator<T> {
24
+ return (async function* () {
25
+ trackingSet.add(id);
26
+ try {
27
+ for (const value of values) {
28
+ await new Promise((resolve) => setTimeout(resolve, delay));
29
+ yield value;
30
+ }
31
+ } finally {
32
+ trackingSet.delete(id);
33
+ }
34
+ })();
35
+ }
36
+
37
+ describe('asyncIteratorRace', () => {
38
+ it('should handle empty input iterator', async () => {
39
+ async function* emptyInput(): AsyncGenerator<AsyncGenerator<number>> {
40
+ return;
41
+ }
42
+
43
+ const result = asyncIteratorRace(emptyInput());
44
+ const values = await Array.fromAsync(result);
45
+
46
+ expect(values).toEqual([]);
47
+ });
48
+
49
+ it('should handle single generator with no values', async () => {
50
+ const input = createInputIterator([createAsyncGenerator([])]);
51
+
52
+ const result = asyncIteratorRace(input);
53
+ const values = await Array.fromAsync(result);
54
+
55
+ expect(values).toEqual([]);
56
+ });
57
+
58
+ it('should handle single generator with multiple values', async () => {
59
+ const input = createInputIterator([createAsyncGenerator([1, 2, 3])]);
60
+
61
+ const result = asyncIteratorRace(input);
62
+ const values = await Array.fromAsync(result);
63
+
64
+ expect(values).toEqual([1, 2, 3]);
65
+ });
66
+
67
+ it('should handle generators with mixed empty and non-empty results', async () => {
68
+ const input = createInputIterator([
69
+ createAsyncGenerator([]),
70
+ createAsyncGenerator([1, 3]),
71
+ createAsyncGenerator([]),
72
+ createAsyncGenerator([2]),
73
+ ]);
74
+
75
+ const result = asyncIteratorRace(input);
76
+ const values = await Array.fromAsync(result);
77
+
78
+ expect(values.sort()).toEqual([1, 2, 3]);
79
+ });
80
+
81
+ it('should limit concurrent reading of input iterators', async () => {
82
+ const concurrency = 2;
83
+ const activeIterators = new Set<number>();
84
+ let maxConcurrentActive = 0;
85
+
86
+ const generators = Array.from({ length: 5 }, (_, i) =>
87
+ createTrackingGenerator([i * 10, i * 10 + 1], activeIterators, i, 50),
88
+ );
89
+ const input = createInputIterator(generators);
90
+
91
+ const result = asyncIteratorRace(input, concurrency);
92
+
93
+ const values: number[] = [];
94
+ for await (const value of result) {
95
+ maxConcurrentActive = Math.max(maxConcurrentActive, activeIterators.size);
96
+ values.push(value);
97
+ }
98
+
99
+ expect(maxConcurrentActive).toBe(concurrency);
100
+ expect(values).toHaveLength(10);
101
+ expect(values.sort()).toEqual([0, 1, 10, 11, 20, 21, 30, 31, 40, 41]);
102
+ });
103
+
104
+ it('should yield values as soon as any generator yields', async () => {
105
+ const slowGenerator = (async function* () {
106
+ await new Promise((resolve) => setTimeout(resolve, 100));
107
+ yield 'slow';
108
+ })();
109
+ const fastGenerator = (async function* () {
110
+ await new Promise((resolve) => setTimeout(resolve, 50));
111
+ yield 'fast';
112
+ })();
113
+ const input = createInputIterator([slowGenerator, fastGenerator]);
114
+ const result = asyncIteratorRace(input, 2);
115
+
116
+ const yieldTimes: number[] = [];
117
+ const startTime = Date.now();
118
+ const values: string[] = [];
119
+ for await (const value of result) {
120
+ yieldTimes.push(Date.now() - startTime);
121
+ values.push(value);
122
+ }
123
+
124
+ expect(values).toEqual(['fast', 'slow']);
125
+ expect(yieldTimes[0]).toBeGreaterThan(40);
126
+ expect(yieldTimes[0]).toBeLessThan(60);
127
+ expect(yieldTimes[1]).toBeGreaterThan(90);
128
+ expect(yieldTimes[1]).toBeLessThan(110);
129
+ });
130
+
131
+ it('should propagate errors from input iterators', async () => {
132
+ const errorGenerator = (async function* () {
133
+ yield 'before-error';
134
+ throw new Error('Test error');
135
+ })();
136
+ const input = createInputIterator([errorGenerator]);
137
+
138
+ const result = asyncIteratorRace(input);
139
+
140
+ const values: string[] = [];
141
+ await expect(async () => {
142
+ for await (const value of result) {
143
+ values.push(value);
144
+ }
145
+ }).rejects.toThrow('Test error');
146
+
147
+ expect(values).toEqual(['before-error']);
148
+ });
149
+ });
@@ -0,0 +1,79 @@
1
+ const DEFAULT_CONCURRENCY = 10;
2
+
3
+ /**
4
+ * Races multiple async iterators into a single async iterator.
5
+ *
6
+ * The input iterators are provided as an async iterator that yields async
7
+ * iterators. This allows to create the iterators lazily, e.g., when the
8
+ * input iterators are created from a database query.
9
+ *
10
+ * The number of input iterators being read at the same time is limited by
11
+ * the `concurrency` parameter.
12
+ *
13
+ * Any error from the input iterators is propagated to the output iterator.
14
+ */
15
+ export async function* asyncIteratorRace<T>(
16
+ inputIterators: AsyncGenerator<AsyncGenerator<T>>,
17
+ concurrency: number = DEFAULT_CONCURRENCY,
18
+ ): AsyncGenerator<T> {
19
+ const promises = new Map<
20
+ number,
21
+ Promise<{
22
+ iteratorIndex: number;
23
+ result: IteratorResult<T>;
24
+ }>
25
+ >();
26
+
27
+ let nextIteratorIndex = 0;
28
+ let inputIteratorsExhausted = false;
29
+ const activeIterators = new Map<number, AsyncGenerator<T>>();
30
+
31
+ const startNewIterator = async (): Promise<void> => {
32
+ if (inputIteratorsExhausted || activeIterators.size >= concurrency) {
33
+ return;
34
+ }
35
+
36
+ const nextIteratorResult = await inputIterators.next();
37
+ if (nextIteratorResult.done) {
38
+ inputIteratorsExhausted = true;
39
+ return;
40
+ }
41
+
42
+ const iterator = nextIteratorResult.value;
43
+ const iteratorIndex = nextIteratorIndex++;
44
+ activeIterators.set(iteratorIndex, iterator);
45
+
46
+ promises.set(
47
+ iteratorIndex,
48
+ (async () => {
49
+ const result = await iterator.next();
50
+ return { iteratorIndex, result };
51
+ })(),
52
+ );
53
+ };
54
+
55
+ while (activeIterators.size < concurrency && !inputIteratorsExhausted) {
56
+ await startNewIterator();
57
+ }
58
+
59
+ while (promises.size > 0) {
60
+ const { iteratorIndex, result } = await Promise.race(promises.values());
61
+ promises.delete(iteratorIndex);
62
+
63
+ if (result.done) {
64
+ activeIterators.delete(iteratorIndex);
65
+ await startNewIterator();
66
+ } else {
67
+ yield result.value;
68
+
69
+ const iterator = activeIterators.get(iteratorIndex)!;
70
+ promises.set(
71
+ iteratorIndex,
72
+ (async () => {
73
+ const result = await iterator.next();
74
+ return { iteratorIndex, result };
75
+ })(),
76
+ );
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,50 @@
1
+ import { batch } from './batch';
2
+
3
+ describe('batch', () => {
4
+ it('should batch an array of numbers into chunks of specified size', () => {
5
+ const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
6
+ const batchSize = 3;
7
+ const result = Array.from(batch(items, batchSize));
8
+
9
+ expect(result).toEqual([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]);
10
+ });
11
+
12
+ it('should handle batch size equal to array length', () => {
13
+ const items = [1, 2, 3, 4, 5];
14
+ const batchSize = 5;
15
+ const result = Array.from(batch(items, batchSize));
16
+
17
+ expect(result).toEqual([[1, 2, 3, 4, 5]]);
18
+ });
19
+
20
+ it('should handle batch size larger than array length', () => {
21
+ const items = [1, 2, 3];
22
+ const batchSize = 10;
23
+ const result = Array.from(batch(items, batchSize));
24
+
25
+ expect(result).toEqual([[1, 2, 3]]);
26
+ });
27
+
28
+ it('should handle batch size of 1', () => {
29
+ const items = [1, 2, 3];
30
+ const batchSize = 1;
31
+ const result = Array.from(batch(items, batchSize));
32
+
33
+ expect(result).toEqual([[1], [2], [3]]);
34
+ });
35
+
36
+ it('should handle empty array', () => {
37
+ const items: number[] = [];
38
+ const batchSize = 3;
39
+ const result = Array.from(batch(items, batchSize));
40
+
41
+ expect(result).toEqual([]);
42
+ });
43
+
44
+ it('should handle zero batch size gracefully', () => {
45
+ const items = [1, 2, 3];
46
+ const batchSize = 0;
47
+
48
+ expect(() => Array.from(batch(items, batchSize))).toThrow();
49
+ });
50
+ });
@@ -0,0 +1,9 @@
1
+ export function* batch<T>(items: T[], batchSize: number): Generator<T[]> {
2
+ if (batchSize <= 0) {
3
+ throw new Error('Batch size must be greater than 0');
4
+ }
5
+
6
+ for (let i = 0; i < items.length; i += batchSize) {
7
+ yield items.slice(i, i + batchSize);
8
+ }
9
+ }
@@ -1,19 +1,19 @@
1
1
  import { BatchLoading } from './batchLoading';
2
2
 
3
- describe("BatchLoading", () => {
3
+ describe('BatchLoading', () => {
4
4
  let batchLoading: BatchLoading<string, string>;
5
5
 
6
6
  beforeEach(() => {
7
7
  jest.clearAllMocks();
8
8
  });
9
9
 
10
- it("should load in batches with loadItems", async () => {
10
+ it('should load in batches with loadItems', async () => {
11
11
  const loadItems = jest.fn((items: string[]) => Promise.resolve(items.map((item) => `loaded:${item}`)));
12
12
 
13
13
  batchLoading = new BatchLoading<string, string>({ loadItems, batchSize: 2 });
14
14
 
15
15
  const result = [];
16
- for (const item of ["a", "b", "c", "d", "e"]) {
16
+ for (const item of ['a', 'b', 'c', 'd', 'e']) {
17
17
  for await (const loadedItem of batchLoading.load(item)) {
18
18
  result.push(loadedItem);
19
19
  }
@@ -22,15 +22,14 @@ describe("BatchLoading", () => {
22
22
  result.push(loadedItem);
23
23
  }
24
24
 
25
-
26
- expect(result).toEqual(["loaded:a", "loaded:b", "loaded:c", "loaded:d", "loaded:e"]);
25
+ expect(result).toEqual(['loaded:a', 'loaded:b', 'loaded:c', 'loaded:d', 'loaded:e']);
27
26
  expect(loadItems).toHaveBeenCalledTimes(3);
28
- expect(loadItems).toHaveBeenNthCalledWith(1, ["a", "b"]);
29
- expect(loadItems).toHaveBeenNthCalledWith(2, ["c", "d"]);
30
- expect(loadItems).toHaveBeenNthCalledWith(3, ["e"]);
27
+ expect(loadItems).toHaveBeenNthCalledWith(1, ['a', 'b']);
28
+ expect(loadItems).toHaveBeenNthCalledWith(2, ['c', 'd']);
29
+ expect(loadItems).toHaveBeenNthCalledWith(3, ['e']);
31
30
  });
32
31
 
33
- it("should load in batches with iterateItems", async () => {
32
+ it('should load in batches with iterateItems', async () => {
34
33
  const iterateItems = jest.fn(async function* (items: string[]) {
35
34
  for (const item of items) {
36
35
  yield `loaded:${item}`;
@@ -40,7 +39,7 @@ describe("BatchLoading", () => {
40
39
  batchLoading = new BatchLoading<string, string>({ iterateItems, batchSize: 2 });
41
40
 
42
41
  const result = [];
43
- for (const item of ["a", "b", "c", "d", "e"]) {
42
+ for (const item of ['a', 'b', 'c', 'd', 'e']) {
44
43
  for await (const loadedItem of batchLoading.load(item)) {
45
44
  result.push(loadedItem);
46
45
  }
@@ -49,10 +48,10 @@ describe("BatchLoading", () => {
49
48
  result.push(loadedItem);
50
49
  }
51
50
 
52
- expect(result).toEqual(["loaded:a", "loaded:b", "loaded:c", "loaded:d", "loaded:e"]);
51
+ expect(result).toEqual(['loaded:a', 'loaded:b', 'loaded:c', 'loaded:d', 'loaded:e']);
53
52
  expect(iterateItems).toHaveBeenCalledTimes(3);
54
- expect(iterateItems).toHaveBeenNthCalledWith(1, ["a", "b"]);
55
- expect(iterateItems).toHaveBeenNthCalledWith(2, ["c", "d"]);
56
- expect(iterateItems).toHaveBeenNthCalledWith(3, ["e"]);
53
+ expect(iterateItems).toHaveBeenNthCalledWith(1, ['a', 'b']);
54
+ expect(iterateItems).toHaveBeenNthCalledWith(2, ['c', 'd']);
55
+ expect(iterateItems).toHaveBeenNthCalledWith(3, ['e']);
57
56
  });
58
57
  });
@@ -2,14 +2,14 @@ const DEFAULT_BATCH_LOADING = 10;
2
2
 
3
3
  /**
4
4
  * Helper class for batch loading items.
5
- *
5
+ *
6
6
  * The class is responsible for fetching items in batches. Any call to
7
7
  * `load` will add the item to the batch (without fetching anything),
8
8
  * and if the batch reaches the limit, it will fetch the items and yield
9
9
  * them transparently to the caller.
10
- *
10
+ *
11
11
  * Example:
12
- *
12
+ *
13
13
  * ```typescript
14
14
  * const batchLoading = new BatchLoading<string, DecryptedNode>({ loadItems: loadNodesCallback });
15
15
  * for (const nodeUid of nodeUids) {
@@ -29,19 +29,19 @@ export class BatchLoading<ID, ITEM> {
29
29
  private itemsToFetch: ID[];
30
30
 
31
31
  constructor(options: {
32
- loadItems?: (ids: ID[]) => Promise<ITEM[]>,
33
- iterateItems?: (ids: ID[]) => AsyncGenerator<ITEM>,
34
- batchSize?: number,
32
+ loadItems?: (ids: ID[]) => Promise<ITEM[]>;
33
+ iterateItems?: (ids: ID[]) => AsyncGenerator<ITEM>;
34
+ batchSize?: number;
35
35
  }) {
36
36
  this.itemsToFetch = [];
37
-
37
+
38
38
  if (options.loadItems) {
39
39
  const loadItems = options.loadItems;
40
40
  this.iterateItems = async function* (ids: ID[]) {
41
41
  for (const item of await loadItems(ids)) {
42
42
  yield item;
43
43
  }
44
- }
44
+ };
45
45
  } else if (options.iterateItems) {
46
46
  this.iterateItems = options.iterateItems;
47
47
  } else {