@brightchain/brightchain-api-lib 0.23.21 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. package/package.json +5 -5
  2. package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.d.ts.map +1 -1
  3. package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.js +11 -0
  4. package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.js.map +1 -1
  5. package/src/lib/__tests__/fixtures/mocked-model.js +63 -60
  6. package/src/lib/__tests__/fixtures/mocked-model.js.map +1 -1
  7. package/src/lib/application.d.ts +1 -1
  8. package/src/lib/application.d.ts.map +1 -1
  9. package/src/lib/application.js +113 -33
  10. package/src/lib/application.js.map +1 -1
  11. package/src/lib/auth/aclEnforcedAvailability.js +4 -0
  12. package/src/lib/auth/aclEnforcedAvailability.js.map +1 -1
  13. package/src/lib/auth/aclEnforcedBlockStore.js +7 -0
  14. package/src/lib/auth/aclEnforcedBlockStore.js.map +1 -1
  15. package/src/lib/auth/ecdsaNodeAuthenticator.js +1 -0
  16. package/src/lib/auth/ecdsaNodeAuthenticator.js.map +1 -1
  17. package/src/lib/auth/poolAclBootstrap.js +2 -0
  18. package/src/lib/auth/poolAclBootstrap.js.map +1 -1
  19. package/src/lib/auth/poolAclStore.js +2 -1
  20. package/src/lib/auth/poolAclStore.js.map +1 -1
  21. package/src/lib/auth/poolAclUpdater.js +4 -0
  22. package/src/lib/auth/poolAclUpdater.js.map +1 -1
  23. package/src/lib/availability/availabilityMetrics.js +43 -45
  24. package/src/lib/availability/availabilityMetrics.js.map +1 -1
  25. package/src/lib/availability/availabilityService.js +26 -20
  26. package/src/lib/availability/availabilityService.js.map +1 -1
  27. package/src/lib/availability/blockRegistry.js +46 -25
  28. package/src/lib/availability/blockRegistry.js.map +1 -1
  29. package/src/lib/availability/discoveryProtocol.js +10 -8
  30. package/src/lib/availability/discoveryProtocol.js.map +1 -1
  31. package/src/lib/availability/gossipService.js +56 -45
  32. package/src/lib/availability/gossipService.js.map +1 -1
  33. package/src/lib/availability/heartbeatMonitor.js +22 -20
  34. package/src/lib/availability/heartbeatMonitor.js.map +1 -1
  35. package/src/lib/availability/poolDiscoveryService.js +7 -1
  36. package/src/lib/availability/poolDiscoveryService.js.map +1 -1
  37. package/src/lib/availability/quorumGossipHandler.js +13 -6
  38. package/src/lib/availability/quorumGossipHandler.js.map +1 -1
  39. package/src/lib/availability/reconciliationService.js +18 -12
  40. package/src/lib/availability/reconciliationService.js.map +1 -1
  41. package/src/lib/blockFetch/blockFetcher.js +14 -8
  42. package/src/lib/blockFetch/blockFetcher.js.map +1 -1
  43. package/src/lib/blockFetch/fetchQueue.js +9 -7
  44. package/src/lib/blockFetch/fetchQueue.js.map +1 -1
  45. package/src/lib/blockFetch/httpBlockFetchTransport.js +2 -0
  46. package/src/lib/blockFetch/httpBlockFetchTransport.js.map +1 -1
  47. package/src/lib/browserKeyring.js +5 -2
  48. package/src/lib/browserKeyring.js.map +1 -1
  49. package/src/lib/controllers/api/blocks.d.ts.map +1 -1
  50. package/src/lib/controllers/api/blocks.js +9 -3
  51. package/src/lib/controllers/api/blocks.js.map +1 -1
  52. package/src/lib/controllers/api/brighthub/connectionController.d.ts +80 -0
  53. package/src/lib/controllers/api/brighthub/connectionController.d.ts.map +1 -0
  54. package/src/lib/controllers/api/brighthub/connectionController.js +890 -0
  55. package/src/lib/controllers/api/brighthub/connectionController.js.map +1 -0
  56. package/src/lib/controllers/api/brighthub/index.d.ts +9 -0
  57. package/src/lib/controllers/api/brighthub/index.d.ts.map +1 -0
  58. package/src/lib/controllers/api/brighthub/index.js +12 -0
  59. package/src/lib/controllers/api/brighthub/index.js.map +1 -0
  60. package/src/lib/controllers/api/brighthub/messagingController.d.ts +84 -0
  61. package/src/lib/controllers/api/brighthub/messagingController.d.ts.map +1 -0
  62. package/src/lib/controllers/api/brighthub/messagingController.js +1077 -0
  63. package/src/lib/controllers/api/brighthub/messagingController.js.map +1 -0
  64. package/src/lib/controllers/api/brighthub/notificationController.d.ts +89 -0
  65. package/src/lib/controllers/api/brighthub/notificationController.d.ts.map +1 -0
  66. package/src/lib/controllers/api/brighthub/notificationController.js +444 -0
  67. package/src/lib/controllers/api/brighthub/notificationController.js.map +1 -0
  68. package/src/lib/controllers/api/brighthub/postController.d.ts +75 -0
  69. package/src/lib/controllers/api/brighthub/postController.d.ts.map +1 -0
  70. package/src/lib/controllers/api/brighthub/postController.js +388 -0
  71. package/src/lib/controllers/api/brighthub/postController.js.map +1 -0
  72. package/src/lib/controllers/api/brighthub/timelineController.d.ts +74 -0
  73. package/src/lib/controllers/api/brighthub/timelineController.d.ts.map +1 -0
  74. package/src/lib/controllers/api/brighthub/timelineController.js +418 -0
  75. package/src/lib/controllers/api/brighthub/timelineController.js.map +1 -0
  76. package/src/lib/controllers/api/brightpass.d.ts.map +1 -1
  77. package/src/lib/controllers/api/brightpass.js +46 -4
  78. package/src/lib/controllers/api/brightpass.js.map +1 -1
  79. package/src/lib/controllers/api/cbl.js +1 -0
  80. package/src/lib/controllers/api/cbl.js.map +1 -1
  81. package/src/lib/controllers/api/channels.js +2 -2
  82. package/src/lib/controllers/api/channels.js.map +1 -1
  83. package/src/lib/controllers/api/conversations.js +1 -1
  84. package/src/lib/controllers/api/conversations.js.map +1 -1
  85. package/src/lib/controllers/api/docs.js +2 -1
  86. package/src/lib/controllers/api/docs.js.map +1 -1
  87. package/src/lib/controllers/api/emails.d.ts.map +1 -1
  88. package/src/lib/controllers/api/emails.js +16 -2
  89. package/src/lib/controllers/api/emails.js.map +1 -1
  90. package/src/lib/controllers/api/explodingMessages.js +2 -4
  91. package/src/lib/controllers/api/explodingMessages.js.map +1 -1
  92. package/src/lib/controllers/api/groups.js +2 -2
  93. package/src/lib/controllers/api/groups.js.map +1 -1
  94. package/src/lib/controllers/api/health.d.ts +9 -2
  95. package/src/lib/controllers/api/health.d.ts.map +1 -1
  96. package/src/lib/controllers/api/health.js +48 -6
  97. package/src/lib/controllers/api/health.js.map +1 -1
  98. package/src/lib/controllers/api/index.d.ts +1 -0
  99. package/src/lib/controllers/api/index.d.ts.map +1 -1
  100. package/src/lib/controllers/api/index.js +1 -0
  101. package/src/lib/controllers/api/index.js.map +1 -1
  102. package/src/lib/controllers/api/introspection.js +2 -0
  103. package/src/lib/controllers/api/introspection.js.map +1 -1
  104. package/src/lib/controllers/api/messages.js +1 -1
  105. package/src/lib/controllers/api/messages.js.map +1 -1
  106. package/src/lib/controllers/api/nodes.js +6 -6
  107. package/src/lib/controllers/api/nodes.js.map +1 -1
  108. package/src/lib/controllers/api/quorum.d.ts +1 -1
  109. package/src/lib/controllers/api/quorum.d.ts.map +1 -1
  110. package/src/lib/controllers/api/quorum.js +3 -2
  111. package/src/lib/controllers/api/quorum.js.map +1 -1
  112. package/src/lib/controllers/api/scbl.js +3 -0
  113. package/src/lib/controllers/api/scbl.js.map +1 -1
  114. package/src/lib/controllers/api/sessions.d.ts +18 -2
  115. package/src/lib/controllers/api/sessions.d.ts.map +1 -1
  116. package/src/lib/controllers/api/sessions.js +60 -3
  117. package/src/lib/controllers/api/sessions.js.map +1 -1
  118. package/src/lib/controllers/api/sync.js +4 -4
  119. package/src/lib/controllers/api/sync.js.map +1 -1
  120. package/src/lib/controllers/api/user.d.ts +2 -0
  121. package/src/lib/controllers/api/user.d.ts.map +1 -1
  122. package/src/lib/controllers/api/user.js +95 -3
  123. package/src/lib/controllers/api/user.js.map +1 -1
  124. package/src/lib/controllers/identity/deviceController.js +2 -2
  125. package/src/lib/controllers/identity/deviceController.js.map +1 -1
  126. package/src/lib/controllers/identity/directoryController.js +1 -1
  127. package/src/lib/controllers/identity/directoryController.js.map +1 -1
  128. package/src/lib/controllers/identity/identityProofController.js +4 -6
  129. package/src/lib/controllers/identity/identityProofController.js.map +1 -1
  130. package/src/lib/databaseInit.d.ts +3 -3
  131. package/src/lib/databaseInit.js +5 -5
  132. package/src/lib/databaseInit.js.map +1 -1
  133. package/src/lib/datastore/block-document-store.d.ts.map +1 -1
  134. package/src/lib/datastore/block-document-store.js +18 -6
  135. package/src/lib/datastore/block-document-store.js.map +1 -1
  136. package/src/lib/datastore/document-store.d.ts.map +1 -1
  137. package/src/lib/datastore/memory-document-store.js +5 -2
  138. package/src/lib/datastore/memory-document-store.js.map +1 -1
  139. package/src/lib/encryption/encryptedMetadataService.js +2 -0
  140. package/src/lib/encryption/encryptedMetadataService.js.map +1 -1
  141. package/src/lib/encryption/encryptionAwareReplication.js +3 -0
  142. package/src/lib/encryption/encryptionAwareReplication.js.map +1 -1
  143. package/src/lib/encryption/errors.d.ts.map +1 -1
  144. package/src/lib/encryption/errors.js +8 -0
  145. package/src/lib/encryption/errors.js.map +1 -1
  146. package/src/lib/encryption/poolKeyManager.js +2 -0
  147. package/src/lib/encryption/poolKeyManager.js.map +1 -1
  148. package/src/lib/environment.js +10 -0
  149. package/src/lib/environment.js.map +1 -1
  150. package/src/lib/errors/express-validation.js +1 -0
  151. package/src/lib/errors/express-validation.js.map +1 -1
  152. package/src/lib/errors/invalid-backup-code-version.js +1 -0
  153. package/src/lib/errors/invalid-backup-code-version.js.map +1 -1
  154. package/src/lib/errors/memberIndexSchemaValidationError.js +1 -0
  155. package/src/lib/errors/memberIndexSchemaValidationError.js.map +1 -1
  156. package/src/lib/errors/missing-validated-data.js +2 -0
  157. package/src/lib/errors/missing-validated-data.js.map +1 -1
  158. package/src/lib/errors/token-not-found.js +1 -0
  159. package/src/lib/errors/token-not-found.js.map +1 -1
  160. package/src/lib/errors/typed-error-local.js +3 -0
  161. package/src/lib/errors/typed-error-local.js.map +1 -1
  162. package/src/lib/interfaces/brightpass/index.d.ts +103 -0
  163. package/src/lib/interfaces/brightpass/index.d.ts.map +1 -0
  164. package/src/lib/interfaces/brightpass/index.js +11 -0
  165. package/src/lib/interfaces/brightpass/index.js.map +1 -0
  166. package/src/lib/interfaces/environment.d.ts +1 -1
  167. package/src/lib/interfaces/environment.d.ts.map +1 -1
  168. package/src/lib/interfaces/index.d.ts +1 -0
  169. package/src/lib/interfaces/index.d.ts.map +1 -1
  170. package/src/lib/interfaces/member/memberProfileResponse.d.ts.map +1 -1
  171. package/src/lib/interfaces/member/operational.d.ts.map +1 -1
  172. package/src/lib/interfaces/member-init-config.d.ts +1 -1
  173. package/src/lib/interfaces/member-init-config.d.ts.map +1 -1
  174. package/src/lib/interfaces/responses/api-backup-codes-response.d.ts.map +1 -1
  175. package/src/lib/interfaces/responses/api-challenge-response.d.ts.map +1 -1
  176. package/src/lib/interfaces/responses/api-code-count-response.d.ts.map +1 -1
  177. package/src/lib/interfaces/responses/api-detailed-health-response.d.ts.map +1 -1
  178. package/src/lib/interfaces/responses/api-discover-block-response.d.ts.map +1 -1
  179. package/src/lib/interfaces/responses/api-express-validation-error.d.ts.map +1 -1
  180. package/src/lib/interfaces/responses/api-get-block-response.d.ts.map +1 -1
  181. package/src/lib/interfaces/responses/api-get-node-response.d.ts.map +1 -1
  182. package/src/lib/interfaces/responses/api-health-response.d.ts.map +1 -1
  183. package/src/lib/interfaces/responses/api-list-nodes-response.d.ts.map +1 -1
  184. package/src/lib/interfaces/responses/api-login-response.d.ts.map +1 -1
  185. package/src/lib/interfaces/responses/api-members-response.d.ts.map +1 -1
  186. package/src/lib/interfaces/responses/api-mnemonic-response.d.ts.map +1 -1
  187. package/src/lib/interfaces/responses/api-reconcile-response.d.ts.map +1 -1
  188. package/src/lib/interfaces/responses/api-register-node-response.d.ts.map +1 -1
  189. package/src/lib/interfaces/responses/api-registration-response.d.ts.map +1 -1
  190. package/src/lib/interfaces/responses/api-replicate-block-response.d.ts.map +1 -1
  191. package/src/lib/interfaces/responses/api-request-user-response.d.ts.map +1 -1
  192. package/src/lib/interfaces/responses/api-store-block-response.d.ts.map +1 -1
  193. package/src/lib/interfaces/responses/api-store-cbl-response.d.ts.map +1 -1
  194. package/src/lib/interfaces/responses/api-sync-request-response.d.ts.map +1 -1
  195. package/src/lib/interfaces/responses/brighthub/api-connection-response.d.ts +21 -0
  196. package/src/lib/interfaces/responses/brighthub/api-connection-response.d.ts.map +1 -0
  197. package/src/lib/interfaces/responses/brighthub/api-connection-response.js +3 -0
  198. package/src/lib/interfaces/responses/brighthub/api-connection-response.js.map +1 -0
  199. package/src/lib/interfaces/responses/brighthub/api-messaging-response.d.ts +39 -0
  200. package/src/lib/interfaces/responses/brighthub/api-messaging-response.d.ts.map +1 -0
  201. package/src/lib/interfaces/responses/brighthub/api-messaging-response.js +3 -0
  202. package/src/lib/interfaces/responses/brighthub/api-messaging-response.js.map +1 -0
  203. package/src/lib/interfaces/responses/brighthub/api-notification-response.d.ts +30 -0
  204. package/src/lib/interfaces/responses/brighthub/api-notification-response.d.ts.map +1 -0
  205. package/src/lib/interfaces/responses/brighthub/api-notification-response.js +3 -0
  206. package/src/lib/interfaces/responses/brighthub/api-notification-response.js.map +1 -0
  207. package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts +21 -0
  208. package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts.map +1 -0
  209. package/src/lib/interfaces/responses/brighthub/api-post-response.js +3 -0
  210. package/src/lib/interfaces/responses/brighthub/api-post-response.js.map +1 -0
  211. package/src/lib/interfaces/responses/brighthub/api-timeline-response.d.ts +14 -0
  212. package/src/lib/interfaces/responses/brighthub/api-timeline-response.d.ts.map +1 -0
  213. package/src/lib/interfaces/responses/brighthub/api-timeline-response.js +3 -0
  214. package/src/lib/interfaces/responses/brighthub/api-timeline-response.js.map +1 -0
  215. package/src/lib/interfaces/responses/brighthub/api-user-profile-response.d.ts +10 -0
  216. package/src/lib/interfaces/responses/brighthub/api-user-profile-response.d.ts.map +1 -0
  217. package/src/lib/interfaces/responses/brighthub/api-user-profile-response.js +3 -0
  218. package/src/lib/interfaces/responses/brighthub/api-user-profile-response.js.map +1 -0
  219. package/src/lib/interfaces/responses/brighthub/index.d.ts +13 -0
  220. package/src/lib/interfaces/responses/brighthub/index.d.ts.map +1 -0
  221. package/src/lib/interfaces/responses/brighthub/index.js +9 -0
  222. package/src/lib/interfaces/responses/brighthub/index.js.map +1 -0
  223. package/src/lib/interfaces/responses/index.d.ts +1 -0
  224. package/src/lib/interfaces/responses/index.d.ts.map +1 -1
  225. package/src/lib/interfaces/storage/storedDocumentTypes.d.ts +1 -1
  226. package/src/lib/interfaces/storage/storedDocumentTypes.js +1 -1
  227. package/src/lib/interfaces/storage/userRoleSchema.d.ts.map +1 -1
  228. package/src/lib/interfaces/storage/userRoleSchema.js +1 -3
  229. package/src/lib/interfaces/storage/userRoleSchema.js.map +1 -1
  230. package/src/lib/middlewares.js +31 -31
  231. package/src/lib/middlewares.js.map +1 -1
  232. package/src/lib/nodeKeyring.js +2 -0
  233. package/src/lib/nodeKeyring.js.map +1 -1
  234. package/src/lib/plugins/brightchain-database-plugin.d.ts +14 -14
  235. package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
  236. package/src/lib/plugins/brightchain-database-plugin.js +36 -34
  237. package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
  238. package/src/lib/routers/api.d.ts +63 -1
  239. package/src/lib/routers/api.d.ts.map +1 -1
  240. package/src/lib/routers/api.js +126 -2
  241. package/src/lib/routers/api.js.map +1 -1
  242. package/src/lib/routers/app.d.ts.map +1 -1
  243. package/src/lib/routers/app.js +10 -1
  244. package/src/lib/routers/app.js.map +1 -1
  245. package/src/lib/routers/base.js +2 -0
  246. package/src/lib/routers/base.js.map +1 -1
  247. package/src/lib/routers/index.d.ts +1 -0
  248. package/src/lib/routers/index.d.ts.map +1 -1
  249. package/src/lib/routers/index.js +1 -0
  250. package/src/lib/routers/index.js.map +1 -1
  251. package/src/lib/routers/testEmailRouter.d.ts +15 -0
  252. package/src/lib/routers/testEmailRouter.d.ts.map +1 -0
  253. package/src/lib/routers/testEmailRouter.js +34 -0
  254. package/src/lib/routers/testEmailRouter.js.map +1 -0
  255. package/src/lib/secureEnclaveKeyring.js +4 -2
  256. package/src/lib/secureEnclaveKeyring.js.map +1 -1
  257. package/src/lib/services/auth.d.ts.map +1 -1
  258. package/src/lib/services/auth.js +11 -2
  259. package/src/lib/services/auth.js.map +1 -1
  260. package/src/lib/services/base.js +1 -0
  261. package/src/lib/services/base.js.map +1 -1
  262. package/src/lib/services/blockServiceFactory.js +2 -0
  263. package/src/lib/services/blockServiceFactory.js.map +1 -1
  264. package/src/lib/services/blockStore.js +3 -2
  265. package/src/lib/services/blockStore.js.map +1 -1
  266. package/src/lib/services/blocks.js +1 -0
  267. package/src/lib/services/blocks.js.map +1 -1
  268. package/src/lib/services/brightChainBackupCodeService.d.ts +114 -0
  269. package/src/lib/services/brightChainBackupCodeService.d.ts.map +1 -0
  270. package/src/lib/services/brightChainBackupCodeService.js +303 -0
  271. package/src/lib/services/brightChainBackupCodeService.js.map +1 -0
  272. package/src/lib/services/brightchain-authentication-provider.d.ts.map +1 -1
  273. package/src/lib/services/brightchain-authentication-provider.js +40 -9
  274. package/src/lib/services/brightchain-authentication-provider.js.map +1 -1
  275. package/src/lib/services/brightchain-member-init.service.d.ts +17 -17
  276. package/src/lib/services/brightchain-member-init.service.d.ts.map +1 -1
  277. package/src/lib/services/brightchain-member-init.service.js +12 -9
  278. package/src/lib/services/brightchain-member-init.service.js.map +1 -1
  279. package/src/lib/services/brighthub/connectionService.d.ts +286 -0
  280. package/src/lib/services/brighthub/connectionService.d.ts.map +1 -0
  281. package/src/lib/services/brighthub/connectionService.js +1887 -0
  282. package/src/lib/services/brighthub/connectionService.js.map +1 -0
  283. package/src/lib/services/brighthub/discoveryService.d.ts +110 -0
  284. package/src/lib/services/brighthub/discoveryService.d.ts.map +1 -0
  285. package/src/lib/services/brighthub/discoveryService.js +528 -0
  286. package/src/lib/services/brighthub/discoveryService.js.map +1 -0
  287. package/src/lib/services/brighthub/feedService.d.ts +141 -0
  288. package/src/lib/services/brighthub/feedService.d.ts.map +1 -0
  289. package/src/lib/services/brighthub/feedService.js +418 -0
  290. package/src/lib/services/brighthub/feedService.js.map +1 -0
  291. package/src/lib/services/brighthub/index.d.ts +11 -0
  292. package/src/lib/services/brighthub/index.d.ts.map +1 -0
  293. package/src/lib/services/brighthub/index.js +14 -0
  294. package/src/lib/services/brighthub/index.js.map +1 -0
  295. package/src/lib/services/brighthub/messagingService.d.ts +109 -0
  296. package/src/lib/services/brighthub/messagingService.d.ts.map +1 -0
  297. package/src/lib/services/brighthub/messagingService.js +947 -0
  298. package/src/lib/services/brighthub/messagingService.js.map +1 -0
  299. package/src/lib/services/brighthub/messagingService.test-helpers.d.ts +75 -0
  300. package/src/lib/services/brighthub/messagingService.test-helpers.d.ts.map +1 -0
  301. package/src/lib/services/brighthub/messagingService.test-helpers.js +237 -0
  302. package/src/lib/services/brighthub/messagingService.test-helpers.js.map +1 -0
  303. package/src/lib/services/brighthub/notificationService.d.ts +172 -0
  304. package/src/lib/services/brighthub/notificationService.d.ts.map +1 -0
  305. package/src/lib/services/brighthub/notificationService.js +768 -0
  306. package/src/lib/services/brighthub/notificationService.js.map +1 -0
  307. package/src/lib/services/brighthub/notificationService.test-helpers.d.ts +75 -0
  308. package/src/lib/services/brighthub/notificationService.test-helpers.d.ts.map +1 -0
  309. package/src/lib/services/brighthub/notificationService.test-helpers.js +230 -0
  310. package/src/lib/services/brighthub/notificationService.test-helpers.js.map +1 -0
  311. package/src/lib/services/brighthub/postService.d.ts +129 -0
  312. package/src/lib/services/brighthub/postService.d.ts.map +1 -0
  313. package/src/lib/services/brighthub/postService.js +470 -0
  314. package/src/lib/services/brighthub/postService.js.map +1 -0
  315. package/src/lib/services/brighthub/postService.test-helpers.d.ts +40 -0
  316. package/src/lib/services/brighthub/postService.test-helpers.d.ts.map +1 -0
  317. package/src/lib/services/brighthub/postService.test-helpers.js +84 -0
  318. package/src/lib/services/brighthub/postService.test-helpers.js.map +1 -0
  319. package/src/lib/services/brighthub/textFormatter.d.ts +64 -0
  320. package/src/lib/services/brighthub/textFormatter.d.ts.map +1 -0
  321. package/src/lib/services/brighthub/textFormatter.js +256 -0
  322. package/src/lib/services/brighthub/textFormatter.js.map +1 -0
  323. package/src/lib/services/brighthub/threadService.d.ts +79 -0
  324. package/src/lib/services/brighthub/threadService.d.ts.map +1 -0
  325. package/src/lib/services/brighthub/threadService.js +246 -0
  326. package/src/lib/services/brighthub/threadService.js.map +1 -0
  327. package/src/lib/services/brighthub/userProfileService.d.ts +203 -0
  328. package/src/lib/services/brighthub/userProfileService.d.ts.map +1 -0
  329. package/src/lib/services/brighthub/userProfileService.js +868 -0
  330. package/src/lib/services/brighthub/userProfileService.js.map +1 -0
  331. package/src/lib/services/brighthub/userProfileService.test-helpers.d.ts +86 -0
  332. package/src/lib/services/brighthub/userProfileService.test-helpers.d.ts.map +1 -0
  333. package/src/lib/services/brighthub/userProfileService.test-helpers.js +169 -0
  334. package/src/lib/services/brighthub/userProfileService.test-helpers.js.map +1 -0
  335. package/src/lib/services/brighthub/webSocketServer.d.ts +68 -0
  336. package/src/lib/services/brighthub/webSocketServer.d.ts.map +1 -0
  337. package/src/lib/services/brighthub/webSocketServer.js +194 -0
  338. package/src/lib/services/brighthub/webSocketServer.js.map +1 -0
  339. package/src/lib/services/brightpass/auditLogger.js +10 -5
  340. package/src/lib/services/brightpass/auditLogger.js.map +1 -1
  341. package/src/lib/services/brightpass/vaultEncryption.js +8 -8
  342. package/src/lib/services/brightpass/vaultEncryption.js.map +1 -1
  343. package/src/lib/services/brightpass.js +16 -8
  344. package/src/lib/services/brightpass.js.map +1 -1
  345. package/src/lib/services/cliOperatorPrompt.js +5 -2
  346. package/src/lib/services/cliOperatorPrompt.js.map +1 -1
  347. package/src/lib/services/clientWebSocketServer.d.ts +69 -4
  348. package/src/lib/services/clientWebSocketServer.d.ts.map +1 -1
  349. package/src/lib/services/clientWebSocketServer.js +188 -10
  350. package/src/lib/services/clientWebSocketServer.js.map +1 -1
  351. package/src/lib/services/contentAwareBlocksService.js +2 -0
  352. package/src/lib/services/contentAwareBlocksService.js.map +1 -1
  353. package/src/lib/services/contentIngestionService.d.ts.map +1 -1
  354. package/src/lib/services/contentIngestionService.js +2 -0
  355. package/src/lib/services/contentIngestionService.js.map +1 -1
  356. package/src/lib/services/diskQuorumService.js +3 -0
  357. package/src/lib/services/diskQuorumService.js.map +1 -1
  358. package/src/lib/services/email.js +5 -0
  359. package/src/lib/services/email.js.map +1 -1
  360. package/src/lib/services/eventNotificationSystem.d.ts +51 -10
  361. package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
  362. package/src/lib/services/eventNotificationSystem.js +76 -23
  363. package/src/lib/services/eventNotificationSystem.js.map +1 -1
  364. package/src/lib/services/expirationScheduler.js +6 -3
  365. package/src/lib/services/expirationScheduler.js.map +1 -1
  366. package/src/lib/services/fakeEmailService.d.ts +68 -0
  367. package/src/lib/services/fakeEmailService.d.ts.map +1 -0
  368. package/src/lib/services/fakeEmailService.js +110 -0
  369. package/src/lib/services/fakeEmailService.js.map +1 -0
  370. package/src/lib/services/fec.js +1 -3
  371. package/src/lib/services/fec.js.map +1 -1
  372. package/src/lib/services/fecServiceFactory.js +2 -2
  373. package/src/lib/services/fecServiceFactory.js.map +1 -1
  374. package/src/lib/services/fecUsageExample.js +1 -3
  375. package/src/lib/services/fecUsageExample.js.map +1 -1
  376. package/src/lib/services/identityExpirationScheduler.d.ts.map +1 -1
  377. package/src/lib/services/identityExpirationScheduler.js +7 -2
  378. package/src/lib/services/identityExpirationScheduler.js.map +1 -1
  379. package/src/lib/services/index.d.ts +3 -1
  380. package/src/lib/services/index.d.ts.map +1 -1
  381. package/src/lib/services/index.js +3 -1
  382. package/src/lib/services/index.js.map +1 -1
  383. package/src/lib/services/messageEventsWebSocketHandler.js +1 -0
  384. package/src/lib/services/messageEventsWebSocketHandler.js.map +1 -1
  385. package/src/lib/services/messagePassingService.js +5 -0
  386. package/src/lib/services/messagePassingService.js.map +1 -1
  387. package/src/lib/services/nativeRsFecService.js +3 -5
  388. package/src/lib/services/nativeRsFecService.js.map +1 -1
  389. package/src/lib/services/presenceService.js +5 -4
  390. package/src/lib/services/presenceService.js.map +1 -1
  391. package/src/lib/services/quorum.js +3 -2
  392. package/src/lib/services/quorum.js.map +1 -1
  393. package/src/lib/services/quorumDatabaseAdapter.d.ts +5 -5
  394. package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -1
  395. package/src/lib/services/quorumDatabaseAdapter.js +5 -3
  396. package/src/lib/services/quorumDatabaseAdapter.js.map +1 -1
  397. package/src/lib/services/rbac-input-builder.js +5 -0
  398. package/src/lib/services/rbac-input-builder.js.map +1 -1
  399. package/src/lib/services/secureKeyStorage.js +3 -0
  400. package/src/lib/services/secureKeyStorage.js.map +1 -1
  401. package/src/lib/services/sessionAdapter.d.ts +4 -4
  402. package/src/lib/services/sessionAdapter.d.ts.map +1 -1
  403. package/src/lib/services/sessionAdapter.js +3 -2
  404. package/src/lib/services/sessionAdapter.js.map +1 -1
  405. package/src/lib/services/webSocketMessageServer.js +7 -4
  406. package/src/lib/services/webSocketMessageServer.js.map +1 -1
  407. package/src/lib/services/webSocketPeerProvider.js +2 -1
  408. package/src/lib/services/webSocketPeerProvider.js.map +1 -1
  409. package/src/lib/services/websocketHandler.js +9 -1
  410. package/src/lib/services/websocketHandler.js.map +1 -1
  411. package/src/lib/shared-types.d.ts +1 -2
  412. package/src/lib/shared-types.d.ts.map +1 -1
  413. package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.d.ts +63 -0
  414. package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.d.ts.map +1 -0
  415. package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.js +160 -0
  416. package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.js.map +1 -0
  417. package/src/lib/stores/availabilityAwareBlockStore.js +34 -5
  418. package/src/lib/stores/availabilityAwareBlockStore.js.map +1 -1
  419. package/src/lib/stores/cloudBlockStoreBase.d.ts +121 -0
  420. package/src/lib/stores/cloudBlockStoreBase.d.ts.map +1 -0
  421. package/src/lib/stores/cloudBlockStoreBase.js +1165 -0
  422. package/src/lib/stores/cloudBlockStoreBase.js.map +1 -0
  423. package/src/lib/stores/diskBlockAsyncStore.js +9 -5
  424. package/src/lib/stores/diskBlockAsyncStore.js.map +1 -1
  425. package/src/lib/stores/diskBlockMetadataStore.js +2 -0
  426. package/src/lib/stores/diskBlockMetadataStore.js.map +1 -1
  427. package/src/lib/stores/diskBlockStore.js +10 -8
  428. package/src/lib/stores/diskBlockStore.js.map +1 -1
  429. package/src/lib/stores/diskCBLStore.d.ts.map +1 -1
  430. package/src/lib/stores/diskCBLStore.js +8 -0
  431. package/src/lib/stores/diskCBLStore.js.map +1 -1
  432. package/src/lib/stores/index.d.ts +1 -0
  433. package/src/lib/stores/index.d.ts.map +1 -1
  434. package/src/lib/stores/index.js +1 -0
  435. package/src/lib/stores/index.js.map +1 -1
  436. package/src/lib/systemKeyring.d.ts.map +1 -1
  437. package/src/lib/systemKeyring.js +5 -4
  438. package/src/lib/systemKeyring.js.map +1 -1
  439. package/src/lib/transforms/checksumTransform.js +1 -0
  440. package/src/lib/transforms/checksumTransform.js.map +1 -1
  441. package/src/lib/transforms/memoryWritableStream.js +1 -0
  442. package/src/lib/transforms/memoryWritableStream.js.map +1 -1
  443. package/src/lib/transforms/xorMultipleTransform.js +3 -0
  444. package/src/lib/transforms/xorMultipleTransform.js.map +1 -1
  445. package/src/lib/utils/rehydration.d.ts +1 -1
  446. package/src/lib/utils/rehydration.js +1 -1
  447. package/src/lib/utils/serialization.d.ts +1 -1
  448. package/src/lib/utils/serialization.js +1 -1
  449. package/src/lib/services/backupCodeService.d.ts +0 -35
  450. package/src/lib/services/backupCodeService.d.ts.map +0 -1
  451. package/src/lib/services/backupCodeService.js +0 -109
  452. package/src/lib/services/backupCodeService.js.map +0 -1
@@ -0,0 +1,1165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudBlockStoreBase = void 0;
4
+ /**
5
+ * CloudBlockStoreBase - Abstract base class for cloud-backed block stores.
6
+ *
7
+ * Implements IBlockStore and IPooledBlockStore, encapsulating all shared cloud
8
+ * store logic (metadata serialization, FEC orchestration, CBL whitening, pool
9
+ * key management, retry logic). Subclasses implement only the cloud-specific
10
+ * I/O primitives (uploadObject, downloadObject, deleteObject, objectExists,
11
+ * listObjects, isTransientError).
12
+ *
13
+ * @see DiskBlockAsyncStore for the disk-based reference implementation
14
+ * @see AzureBlobBlockStore for the Azure Blob Storage subclass
15
+ * @see S3BlockStore for the Amazon S3 subclass
16
+ */
17
+ const brightchain_lib_1 = require("@brightchain/brightchain-lib");
18
+ /**
19
+ * Cast a raw hex string to BlockId without validation.
20
+ * Used for opaque storage keys that must satisfy the branded type.
21
+ */
22
+ function toStorageKey(hex) {
23
+ return hex;
24
+ }
25
+ /** Default TTL for the local checksum index (5 minutes) */
26
+ const DEFAULT_INDEX_TTL_MS = 5 * 60 * 1000;
27
+ /** Default page size for listing objects during index refresh */
28
+ const DEFAULT_LIST_PAGE_SIZE = 1000;
29
+ class CloudBlockStoreBase {
30
+ config;
31
+ _blockSize;
32
+ fecService = null;
33
+ // === Local checksum index for getRandomBlocks ===
34
+ localIndex = new Set();
35
+ indexStale = true;
36
+ indexLastRefreshed = 0;
37
+ indexTtlMs;
38
+ listPageSize;
39
+ constructor(config, indexTtlMs = DEFAULT_INDEX_TTL_MS, listPageSize = DEFAULT_LIST_PAGE_SIZE) {
40
+ this.config = config;
41
+ this._blockSize = config.blockSize;
42
+ this.indexTtlMs = indexTtlMs;
43
+ this.listPageSize = listPageSize;
44
+ }
45
+ // =========================================================================
46
+ // Public accessors
47
+ // =========================================================================
48
+ get blockSize() {
49
+ return this._blockSize;
50
+ }
51
+ setFecService(fecService) {
52
+ this.fecService = fecService;
53
+ }
54
+ getFecService() {
55
+ return this.fecService;
56
+ }
57
+ // =========================================================================
58
+ // Key management
59
+ // =========================================================================
60
+ /**
61
+ * Build the object key for block data.
62
+ * Pattern: {keyPrefix}{poolId}/{checksumHex}
63
+ */
64
+ buildObjectKey(checksumHex, poolId = brightchain_lib_1.DEFAULT_POOL) {
65
+ const prefix = this.config.keyPrefix ?? '';
66
+ return `${prefix}${poolId}/${checksumHex}`;
67
+ }
68
+ /**
69
+ * Build the object key for a metadata sidecar.
70
+ * Pattern: {keyPrefix}{poolId}/{checksumHex}.meta
71
+ */
72
+ buildMetaKey(checksumHex, poolId = brightchain_lib_1.DEFAULT_POOL) {
73
+ return `${this.buildObjectKey(checksumHex, poolId)}.meta`;
74
+ }
75
+ /**
76
+ * Build the object key for a parity block.
77
+ * Pattern: {keyPrefix}{poolId}/parity/{checksumHex}/{parityIndex}
78
+ */
79
+ buildParityKey(checksumHex, parityIndex, poolId = brightchain_lib_1.DEFAULT_POOL) {
80
+ const prefix = this.config.keyPrefix ?? '';
81
+ return `${prefix}${poolId}/parity/${checksumHex}/${parityIndex}`;
82
+ }
83
+ /**
84
+ * Build the prefix for listing parity blocks of a given data block.
85
+ */
86
+ buildParityPrefix(checksumHex, poolId = brightchain_lib_1.DEFAULT_POOL) {
87
+ const prefix = this.config.keyPrefix ?? '';
88
+ return `${prefix}${poolId}/parity/${checksumHex}/`;
89
+ }
90
+ /**
91
+ * Build the prefix for listing all blocks in a pool.
92
+ */
93
+ buildPoolPrefix(poolId = brightchain_lib_1.DEFAULT_POOL) {
94
+ const prefix = this.config.keyPrefix ?? '';
95
+ return `${prefix}${poolId}/`;
96
+ }
97
+ // =========================================================================
98
+ // Utility helpers
99
+ // =========================================================================
100
+ keyToHex(key) {
101
+ return typeof key === 'string' ? key : key.toHex();
102
+ }
103
+ hexToChecksum(hex) {
104
+ return brightchain_lib_1.Checksum.fromHex(hex);
105
+ }
106
+ // =========================================================================
107
+ // Retry logic
108
+ // =========================================================================
109
+ /**
110
+ * Retry an operation with exponential backoff for transient errors.
111
+ * Base delay 1s, factor 2x, max 3 retries by default.
112
+ */
113
+ async withRetry(operation, blockChecksum, fn, maxRetries = 3) {
114
+ let lastError;
115
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
116
+ try {
117
+ return await fn();
118
+ }
119
+ catch (error) {
120
+ lastError = error;
121
+ if (!this.isTransientError(error) || attempt === maxRetries) {
122
+ break;
123
+ }
124
+ const delay = Math.pow(2, attempt) * 1000;
125
+ await new Promise((resolve) => setTimeout(resolve, delay));
126
+ }
127
+ }
128
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.CloudOperationFailed, undefined, {
129
+ operation,
130
+ blockChecksum,
131
+ originalError: String(lastError),
132
+ });
133
+ }
134
+ // =========================================================================
135
+ // Metadata serialization helpers
136
+ // =========================================================================
137
+ serializeMetadata(metadata) {
138
+ const file = {
139
+ blockId: metadata.blockId,
140
+ createdAt: metadata.createdAt.toISOString(),
141
+ expiresAt: metadata.expiresAt?.toISOString() ?? null,
142
+ durabilityLevel: metadata.durabilityLevel,
143
+ parityBlockIds: [...metadata.parityBlockIds],
144
+ accessCount: metadata.accessCount,
145
+ lastAccessedAt: metadata.lastAccessedAt.toISOString(),
146
+ replicationStatus: metadata.replicationStatus,
147
+ targetReplicationFactor: metadata.targetReplicationFactor,
148
+ replicaNodeIds: [...metadata.replicaNodeIds],
149
+ size: metadata.size,
150
+ checksum: metadata.checksum,
151
+ ...(metadata.poolId !== undefined ? { poolId: metadata.poolId } : {}),
152
+ };
153
+ return new TextEncoder().encode(JSON.stringify(file));
154
+ }
155
+ deserializeMetadata(data) {
156
+ const json = new TextDecoder().decode(data);
157
+ const file = JSON.parse(json);
158
+ return {
159
+ blockId: file.blockId,
160
+ createdAt: new Date(file.createdAt),
161
+ expiresAt: file.expiresAt ? new Date(file.expiresAt) : null,
162
+ durabilityLevel: file.durabilityLevel,
163
+ parityBlockIds: file.parityBlockIds,
164
+ accessCount: file.accessCount,
165
+ lastAccessedAt: new Date(file.lastAccessedAt),
166
+ replicationStatus: file.replicationStatus,
167
+ targetReplicationFactor: file.targetReplicationFactor,
168
+ replicaNodeIds: file.replicaNodeIds,
169
+ size: file.size,
170
+ checksum: file.checksum,
171
+ ...(file.poolId !== undefined ? { poolId: file.poolId } : {}),
172
+ };
173
+ }
174
+ // =========================================================================
175
+ // Local checksum index management
176
+ // =========================================================================
177
+ /**
178
+ * Check if the local index needs refreshing based on TTL.
179
+ */
180
+ isIndexStale() {
181
+ if (this.indexStale)
182
+ return true;
183
+ return Date.now() - this.indexLastRefreshed > this.indexTtlMs;
184
+ }
185
+ /**
186
+ * Refresh the local checksum index by listing objects from the cloud store.
187
+ */
188
+ async refreshIndex(poolId = brightchain_lib_1.DEFAULT_POOL) {
189
+ const prefix = this.buildPoolPrefix(poolId);
190
+ const keys = await this.listObjects(prefix, this.listPageSize);
191
+ this.localIndex.clear();
192
+ const poolPrefix = this.buildPoolPrefix(poolId);
193
+ for (const key of keys) {
194
+ // Extract checksum hex from key, skip .meta and parity/ keys
195
+ if (key.endsWith('.meta'))
196
+ continue;
197
+ if (key.includes('/parity/'))
198
+ continue;
199
+ const checksumHex = key.substring(poolPrefix.length);
200
+ if (checksumHex && !checksumHex.includes('/')) {
201
+ this.localIndex.add(checksumHex);
202
+ }
203
+ }
204
+ this.indexStale = false;
205
+ this.indexLastRefreshed = Date.now();
206
+ }
207
+ // =========================================================================
208
+ // IBlockStore — Core Block Operations
209
+ // =========================================================================
210
+ async has(key) {
211
+ const hex = this.keyToHex(key);
212
+ const objectKey = this.buildObjectKey(hex);
213
+ return this.withRetry('has', hex, () => this.objectExists(objectKey));
214
+ }
215
+ async getData(key) {
216
+ const hex = this.keyToHex(key);
217
+ const objectKey = this.buildObjectKey(hex);
218
+ const data = await this.withRetry('getData', hex, () => this.downloadObject(objectKey));
219
+ // Record access in metadata
220
+ try {
221
+ const metaKey = this.buildMetaKey(hex);
222
+ if (await this.objectExists(metaKey)) {
223
+ const metaData = await this.downloadObject(metaKey);
224
+ const metadata = this.deserializeMetadata(metaData);
225
+ metadata.accessCount++;
226
+ metadata.lastAccessedAt = new Date();
227
+ await this.uploadObject(metaKey, this.serializeMetadata(metadata));
228
+ }
229
+ }
230
+ catch {
231
+ // Ignore metadata access errors — data retrieval is the priority
232
+ }
233
+ return new brightchain_lib_1.RawDataBlock(this._blockSize, data, new Date(), key, brightchain_lib_1.BlockType.RawData, brightchain_lib_1.BlockDataType.RawData, true, true);
234
+ }
235
+ async setData(block, options) {
236
+ const hex = this.keyToHex(block.idChecksum);
237
+ const objectKey = this.buildObjectKey(hex);
238
+ // Idempotent — skip if block already exists
239
+ const exists = await this.withRetry('setData.exists', hex, () => this.objectExists(objectKey));
240
+ if (exists)
241
+ return;
242
+ // Validate block
243
+ try {
244
+ block.validate();
245
+ }
246
+ catch {
247
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.BlockValidationFailed);
248
+ }
249
+ // Upload block data
250
+ await this.withRetry('setData.upload', hex, () => this.uploadObject(objectKey, block.data));
251
+ // Create and upload metadata sidecar
252
+ const metadata = (0, brightchain_lib_1.createDefaultBlockMetadata)(toStorageKey(hex), block.data.length, hex, options);
253
+ const metaKey = this.buildMetaKey(hex);
254
+ await this.withRetry('setData.meta', hex, () => this.uploadObject(metaKey, this.serializeMetadata(metadata)));
255
+ // Update local index
256
+ this.localIndex.add(hex);
257
+ // Generate parity blocks based on durability level
258
+ const durabilityLevel = options?.durabilityLevel ?? brightchain_lib_1.DurabilityLevel.Standard;
259
+ const parityCount = (0, brightchain_lib_1.getParityCountForDurability)(durabilityLevel);
260
+ if (parityCount > 0 && this.fecService) {
261
+ try {
262
+ await this.generateParityBlocks(block.idChecksum, parityCount);
263
+ }
264
+ catch {
265
+ // If parity generation fails, keep the block but without parity protection
266
+ }
267
+ }
268
+ }
269
+ async deleteData(key) {
270
+ const hex = this.keyToHex(key);
271
+ const objectKey = this.buildObjectKey(hex);
272
+ // Check existence
273
+ const exists = await this.withRetry('deleteData.exists', hex, () => this.objectExists(objectKey));
274
+ if (!exists) {
275
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
276
+ KEY: hex,
277
+ });
278
+ }
279
+ // Delete parity blocks first
280
+ try {
281
+ const parityPrefix = this.buildParityPrefix(hex);
282
+ const parityKeys = await this.listObjects(parityPrefix);
283
+ for (const pk of parityKeys) {
284
+ try {
285
+ await this.deleteObject(pk);
286
+ }
287
+ catch {
288
+ // Ignore errors deleting parity files
289
+ }
290
+ }
291
+ }
292
+ catch {
293
+ // Ignore errors listing parity blocks
294
+ }
295
+ // Delete block data
296
+ await this.withRetry('deleteData.delete', hex, () => this.deleteObject(objectKey));
297
+ // Delete metadata sidecar
298
+ try {
299
+ const metaKey = this.buildMetaKey(hex);
300
+ await this.deleteObject(metaKey);
301
+ }
302
+ catch {
303
+ // Ignore errors deleting metadata
304
+ }
305
+ // Update local index
306
+ this.localIndex.delete(hex);
307
+ }
308
+ async getRandomBlocks(count) {
309
+ if (count <= 0)
310
+ return [];
311
+ // Refresh index if stale
312
+ if (this.isIndexStale()) {
313
+ await this.refreshIndex();
314
+ }
315
+ const allChecksums = [...this.localIndex];
316
+ if (allChecksums.length === 0)
317
+ return [];
318
+ // Sample without replacement
319
+ const result = [];
320
+ const available = [...allChecksums];
321
+ const numToReturn = Math.min(count, available.length);
322
+ for (let i = 0; i < numToReturn; i++) {
323
+ const randomIndex = Math.floor(Math.random() * available.length);
324
+ result.push(this.hexToChecksum(available[randomIndex]));
325
+ available.splice(randomIndex, 1);
326
+ }
327
+ return result;
328
+ }
329
+ get(_key) {
330
+ // BlockHandle is synchronous but cloud operations are async.
331
+ // Cloud stores should use getData() for async access.
332
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.NotImplemented, undefined, {
333
+ ERROR: 'Synchronous get() is not supported for cloud stores. Use getData() instead.',
334
+ });
335
+ }
336
+ async put(key, data, options) {
337
+ const keyChecksum = typeof key === 'string' ? brightchain_lib_1.Checksum.fromHex(key) : key;
338
+ const block = new brightchain_lib_1.RawDataBlock(this._blockSize, data, new Date(), keyChecksum);
339
+ await this.setData(block, options);
340
+ }
341
+ async delete(key) {
342
+ const keyChecksum = typeof key === 'string' ? brightchain_lib_1.Checksum.fromHex(key) : key;
343
+ await this.deleteData(keyChecksum);
344
+ }
345
+ // =========================================================================
346
+ // IBlockStore — Metadata Operations
347
+ // =========================================================================
348
+ async getMetadata(key) {
349
+ const hex = this.keyToHex(key);
350
+ const metaKey = this.buildMetaKey(hex);
351
+ try {
352
+ const exists = await this.objectExists(metaKey);
353
+ if (!exists)
354
+ return null;
355
+ const data = await this.downloadObject(metaKey);
356
+ return this.deserializeMetadata(data);
357
+ }
358
+ catch {
359
+ return null;
360
+ }
361
+ }
362
+ async updateMetadata(key, updates) {
363
+ const hex = this.keyToHex(key);
364
+ const metaKey = this.buildMetaKey(hex);
365
+ const existing = await this.getMetadata(key);
366
+ if (!existing) {
367
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
368
+ KEY: hex,
369
+ });
370
+ }
371
+ const updated = { ...existing, ...updates };
372
+ await this.withRetry('updateMetadata', hex, () => this.uploadObject(metaKey, this.serializeMetadata(updated)));
373
+ }
374
+ // =========================================================================
375
+ // IBlockStore — FEC/Durability Operations
376
+ // =========================================================================
377
+ async generateParityBlocks(key, parityCount) {
378
+ const hex = this.keyToHex(key);
379
+ if (!this.fecService) {
380
+ throw new brightchain_lib_1.FecError(brightchain_lib_1.FecErrorType.FecEncodingFailed, undefined, {
381
+ ERROR: 'FEC service is not available',
382
+ });
383
+ }
384
+ const isAvailable = await this.fecService.isAvailable();
385
+ if (!isAvailable) {
386
+ throw new brightchain_lib_1.FecError(brightchain_lib_1.FecErrorType.FecEncodingFailed, undefined, {
387
+ ERROR: 'FEC service is not available in this environment',
388
+ });
389
+ }
390
+ // Download block data
391
+ const objectKey = this.buildObjectKey(hex);
392
+ const blockData = await this.withRetry('generateParity.download', hex, () => this.downloadObject(objectKey));
393
+ // Generate parity data
394
+ const parityData = await this.fecService.createParityData(blockData, parityCount);
395
+ // Store parity blocks as separate cloud objects
396
+ const parityBlockIds = [];
397
+ for (let i = 0; i < parityData.length; i++) {
398
+ const parityKey = this.buildParityKey(hex, i);
399
+ await this.withRetry('generateParity.upload', hex, () => this.uploadObject(parityKey, parityData[i].data));
400
+ const parityHex = `${hex}`.slice(0, 62) + i.toString(16).padStart(2, '0');
401
+ parityBlockIds.push((0, brightchain_lib_1.asBlockId)(parityHex));
402
+ }
403
+ // Update metadata with parity block IDs
404
+ try {
405
+ const existing = await this.getMetadata(key);
406
+ if (existing) {
407
+ await this.updateMetadata(key, { parityBlockIds });
408
+ }
409
+ }
410
+ catch {
411
+ // Ignore metadata update errors
412
+ }
413
+ return parityBlockIds.map((id) => {
414
+ const paddedHex = id.padEnd(64, '0').slice(0, 64);
415
+ return brightchain_lib_1.Checksum.fromHex(paddedHex);
416
+ });
417
+ }
418
+ async getParityBlocks(key) {
419
+ const metadata = await this.getMetadata(key);
420
+ if (!metadata)
421
+ return [];
422
+ return metadata.parityBlockIds.map((id) => {
423
+ const paddedHex = id.padEnd(128, '0').slice(0, 128);
424
+ return brightchain_lib_1.Checksum.fromHex(paddedHex);
425
+ });
426
+ }
427
+ async recoverBlock(key) {
428
+ const hex = this.keyToHex(key);
429
+ if (!this.fecService) {
430
+ return { success: false, error: 'FEC service is not available' };
431
+ }
432
+ const isAvailable = await this.fecService.isAvailable();
433
+ if (!isAvailable) {
434
+ return {
435
+ success: false,
436
+ error: 'FEC service is not available in this environment',
437
+ };
438
+ }
439
+ // Load parity data from cloud
440
+ const parityData = await this.loadParityData(hex);
441
+ if (parityData.length === 0) {
442
+ return { success: false, error: 'No parity data available for recovery' };
443
+ }
444
+ const metadata = await this.getMetadata(key);
445
+ if (!metadata) {
446
+ return { success: false, error: 'Block metadata not found' };
447
+ }
448
+ try {
449
+ // Try to get existing (possibly corrupted) data
450
+ let corruptedData = null;
451
+ try {
452
+ const objectKey = this.buildObjectKey(hex);
453
+ corruptedData = await this.downloadObject(objectKey);
454
+ }
455
+ catch {
456
+ // Block may be completely missing
457
+ }
458
+ const result = await this.fecService.recoverFileData(corruptedData, parityData, metadata.size);
459
+ if (result.recovered) {
460
+ const recoveredBlock = new brightchain_lib_1.RawDataBlock(this._blockSize, new Uint8Array(result.data));
461
+ // Re-upload the recovered block
462
+ const objectKey = this.buildObjectKey(hex);
463
+ await this.uploadObject(objectKey, new Uint8Array(result.data));
464
+ return { success: true, recoveredBlock };
465
+ }
466
+ return {
467
+ success: false,
468
+ error: 'Recovery failed - insufficient parity data',
469
+ };
470
+ }
471
+ catch (error) {
472
+ return {
473
+ success: false,
474
+ error: error instanceof Error ? error.message : 'Unknown recovery error',
475
+ };
476
+ }
477
+ }
478
+ async verifyBlockIntegrity(key) {
479
+ const hex = this.keyToHex(key);
480
+ if (!this.fecService) {
481
+ return this.has(key);
482
+ }
483
+ const isAvailable = await this.fecService.isAvailable();
484
+ if (!isAvailable) {
485
+ return this.has(key);
486
+ }
487
+ const objectKey = this.buildObjectKey(hex);
488
+ const exists = await this.objectExists(objectKey).catch(() => false);
489
+ if (!exists)
490
+ return false;
491
+ const parityData = await this.loadParityData(hex);
492
+ if (parityData.length === 0)
493
+ return true;
494
+ try {
495
+ const blockData = await this.downloadObject(objectKey);
496
+ return await this.fecService.verifyFileIntegrity(blockData, parityData);
497
+ }
498
+ catch {
499
+ return false;
500
+ }
501
+ }
502
+ /**
503
+ * Load parity data from cloud for a block.
504
+ */
505
+ async loadParityData(checksumHex) {
506
+ const metadata = await this.getMetadata(checksumHex);
507
+ if (!metadata || metadata.parityBlockIds.length === 0)
508
+ return [];
509
+ const parityData = [];
510
+ for (let i = 0; i < metadata.parityBlockIds.length; i++) {
511
+ try {
512
+ const parityKey = this.buildParityKey(checksumHex, i);
513
+ const data = await this.downloadObject(parityKey);
514
+ parityData.push({ data, index: i });
515
+ }
516
+ catch {
517
+ // Skip missing parity blocks
518
+ }
519
+ }
520
+ return parityData;
521
+ }
522
+ // =========================================================================
523
+ // IBlockStore — Replication Operations
524
+ // =========================================================================
525
+ async getBlocksPendingReplication() {
526
+ // Scan metadata for blocks with Pending status and targetReplicationFactor > 0
527
+ const prefix = this.buildPoolPrefix();
528
+ const keys = await this.listObjects(prefix);
529
+ const results = [];
530
+ for (const key of keys) {
531
+ if (!key.endsWith('.meta'))
532
+ continue;
533
+ try {
534
+ const data = await this.downloadObject(key);
535
+ const metadata = this.deserializeMetadata(data);
536
+ if (metadata.replicationStatus === brightchain_lib_1.ReplicationStatus.Pending &&
537
+ metadata.targetReplicationFactor > 0) {
538
+ results.push(this.hexToChecksum(metadata.checksum));
539
+ }
540
+ }
541
+ catch {
542
+ // Skip unreadable metadata
543
+ }
544
+ }
545
+ return results;
546
+ }
547
+ async getUnderReplicatedBlocks() {
548
+ const prefix = this.buildPoolPrefix();
549
+ const keys = await this.listObjects(prefix);
550
+ const results = [];
551
+ for (const key of keys) {
552
+ if (!key.endsWith('.meta'))
553
+ continue;
554
+ try {
555
+ const data = await this.downloadObject(key);
556
+ const metadata = this.deserializeMetadata(data);
557
+ if (metadata.replicationStatus === brightchain_lib_1.ReplicationStatus.UnderReplicated) {
558
+ results.push(this.hexToChecksum(metadata.checksum));
559
+ }
560
+ }
561
+ catch {
562
+ // Skip unreadable metadata
563
+ }
564
+ }
565
+ return results;
566
+ }
567
+ async recordReplication(key, nodeId) {
568
+ const hex = this.keyToHex(key);
569
+ const metadata = await this.getMetadata(key);
570
+ if (!metadata) {
571
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
572
+ KEY: hex,
573
+ });
574
+ }
575
+ const replicaNodeIds = [...metadata.replicaNodeIds];
576
+ if (!replicaNodeIds.includes(nodeId)) {
577
+ replicaNodeIds.push(nodeId);
578
+ }
579
+ let replicationStatus = metadata.replicationStatus;
580
+ if (replicaNodeIds.length >= metadata.targetReplicationFactor) {
581
+ replicationStatus = brightchain_lib_1.ReplicationStatus.Replicated;
582
+ }
583
+ else if (replicaNodeIds.length > 0) {
584
+ replicationStatus = brightchain_lib_1.ReplicationStatus.UnderReplicated;
585
+ }
586
+ await this.updateMetadata(key, { replicaNodeIds, replicationStatus });
587
+ }
588
+ async recordReplicaLoss(key, nodeId) {
589
+ const hex = this.keyToHex(key);
590
+ const metadata = await this.getMetadata(key);
591
+ if (!metadata) {
592
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
593
+ KEY: hex,
594
+ });
595
+ }
596
+ const replicaNodeIds = metadata.replicaNodeIds.filter((id) => id !== nodeId);
597
+ let replicationStatus = metadata.replicationStatus;
598
+ if (metadata.targetReplicationFactor > 0) {
599
+ if (replicaNodeIds.length >= metadata.targetReplicationFactor) {
600
+ replicationStatus = brightchain_lib_1.ReplicationStatus.Replicated;
601
+ }
602
+ else if (replicaNodeIds.length > 0) {
603
+ replicationStatus = brightchain_lib_1.ReplicationStatus.UnderReplicated;
604
+ }
605
+ else {
606
+ replicationStatus = brightchain_lib_1.ReplicationStatus.Pending;
607
+ }
608
+ }
609
+ await this.updateMetadata(key, { replicaNodeIds, replicationStatus });
610
+ }
611
+ // =========================================================================
612
+ // IBlockStore — XOR Brightening Operations
613
+ // =========================================================================
614
+ async brightenBlock(key, randomBlockCount) {
615
+ const hex = this.keyToHex(key);
616
+ // Verify source block exists
617
+ const objectKey = this.buildObjectKey(hex);
618
+ const exists = await this.withRetry('brightenBlock.exists', hex, () => this.objectExists(objectKey));
619
+ if (!exists) {
620
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
621
+ KEY: hex,
622
+ });
623
+ }
624
+ // Get random blocks for XOR
625
+ const randomBlockChecksums = await this.getRandomBlocks(randomBlockCount);
626
+ if (randomBlockChecksums.length < randomBlockCount) {
627
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.InsufficientRandomBlocks, undefined, {
628
+ REQUESTED: randomBlockCount.toString(),
629
+ AVAILABLE: randomBlockChecksums.length.toString(),
630
+ });
631
+ }
632
+ // Download source block
633
+ const sourceData = await this.withRetry('brightenBlock.download', hex, () => this.downloadObject(objectKey));
634
+ // XOR with all random blocks
635
+ let result = new Uint8Array(sourceData);
636
+ for (const randomChecksum of randomBlockChecksums) {
637
+ const randomHex = randomChecksum.toHex();
638
+ const randomKey = this.buildObjectKey(randomHex);
639
+ const randomData = await this.withRetry('brightenBlock.downloadRandom', randomHex, () => this.downloadObject(randomKey));
640
+ result = new Uint8Array((0, brightchain_lib_1.xorArrays)(result, randomData));
641
+ }
642
+ // Store the brightened block
643
+ const brightenedBlock = new brightchain_lib_1.RawDataBlock(this._blockSize, new Uint8Array(result));
644
+ const brightenedHex = brightenedBlock.idChecksum.toHex();
645
+ const brightenedExists = await this.has(brightenedBlock.idChecksum);
646
+ if (!brightenedExists) {
647
+ await this.setData(brightenedBlock);
648
+ }
649
+ const randomBlockIds = randomBlockChecksums.map((c) => toStorageKey(c.toHex()));
650
+ return {
651
+ brightenedBlockId: toStorageKey(brightenedHex),
652
+ randomBlockIds,
653
+ originalBlockId: toStorageKey(hex),
654
+ };
655
+ }
656
+ // =========================================================================
657
+ // IBlockStore — CBL Whitening Operations
658
+ // =========================================================================
659
+ async storeCBLWithWhitening(cblData, options) {
660
+ if (!cblData || cblData.length === 0) {
661
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.BlockValidationFailed, undefined, {
662
+ ERROR: 'CBL data cannot be empty',
663
+ });
664
+ }
665
+ // Pad CBL to block size (includes length prefix)
666
+ const paddedCbl = (0, brightchain_lib_1.padToBlockSize)(cblData, this._blockSize);
667
+ if (paddedCbl.length > this._blockSize) {
668
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.BlockValidationFailed, undefined, {
669
+ ERROR: `CBL data too large: padded size (${paddedCbl.length}) exceeds block size (${this._blockSize}).`,
670
+ });
671
+ }
672
+ // Select or generate randomizer block
673
+ const randomBlock = await this.selectOrGenerateRandomizer(paddedCbl.length);
674
+ // XOR to create second block
675
+ const xorResult = (0, brightchain_lib_1.xorArrays)(paddedCbl, randomBlock);
676
+ let block1Stored = false;
677
+ let block1Id = toStorageKey('0'.repeat(64));
678
+ try {
679
+ // Store first block (randomizer)
680
+ const block1 = new brightchain_lib_1.RawDataBlock(this._blockSize, randomBlock);
681
+ if (!(await this.has(block1.idChecksum))) {
682
+ await this.setData(block1, options);
683
+ block1Stored = true;
684
+ }
685
+ block1Id = toStorageKey(block1.idChecksum.toHex());
686
+ // Store second block (CBL XOR R)
687
+ const block2 = new brightchain_lib_1.RawDataBlock(this._blockSize, xorResult);
688
+ await this.setData(block2, options);
689
+ const block2Id = toStorageKey(block2.idChecksum.toHex());
690
+ // Get parity block IDs if FEC redundancy was applied
691
+ let block1ParityIds;
692
+ let block2ParityIds;
693
+ const block1Meta = await this.getMetadata(block1Id);
694
+ if (block1Meta?.parityBlockIds?.length) {
695
+ block1ParityIds = block1Meta.parityBlockIds;
696
+ }
697
+ const block2Meta = await this.getMetadata(block2Id);
698
+ if (block2Meta?.parityBlockIds?.length) {
699
+ block2ParityIds = block2Meta.parityBlockIds;
700
+ }
701
+ const magnetUrl = this.generateCBLMagnetUrl(block1Id, block2Id, this._blockSize, block1ParityIds, block2ParityIds, options?.isEncrypted);
702
+ return {
703
+ blockId1: block1Id,
704
+ blockId2: block2Id,
705
+ blockSize: this._blockSize,
706
+ magnetUrl,
707
+ block1ParityIds,
708
+ block2ParityIds,
709
+ isEncrypted: options?.isEncrypted,
710
+ };
711
+ }
712
+ catch (error) {
713
+ // Rollback: delete block1 if it was stored by us
714
+ if (block1Stored && block1Id) {
715
+ try {
716
+ await this.deleteData(this.hexToChecksum(block1Id));
717
+ }
718
+ catch {
719
+ // Ignore rollback errors
720
+ }
721
+ }
722
+ throw error;
723
+ }
724
+ }
725
+ /**
726
+ * Select an existing block as a randomizer, or generate a new one.
727
+ */
728
+ async selectOrGenerateRandomizer(size) {
729
+ try {
730
+ const randomBlocks = await this.getRandomBlocks(1);
731
+ if (randomBlocks.length > 0) {
732
+ const block = await this.getData(randomBlocks[0]);
733
+ if (block && block.data.length >= size) {
734
+ return block.data.slice(0, size);
735
+ }
736
+ }
737
+ }
738
+ catch {
739
+ // Fall through to generation
740
+ }
741
+ return brightchain_lib_1.XorService.generateKey(size);
742
+ }
743
+ async retrieveCBL(blockId1, blockId2, block1ParityIds, block2ParityIds) {
744
+ // Retrieve first block (with recovery if needed)
745
+ const b1Checksum = typeof blockId1 === 'string' ? this.hexToChecksum(blockId1) : blockId1;
746
+ let block1Data;
747
+ try {
748
+ block1Data = await this.getData(b1Checksum);
749
+ }
750
+ catch (error) {
751
+ if (block1ParityIds?.length) {
752
+ const recovery = await this.recoverBlock(b1Checksum);
753
+ if (recovery.success && recovery.recoveredBlock) {
754
+ block1Data = recovery.recoveredBlock;
755
+ }
756
+ else {
757
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
758
+ KEY: this.keyToHex(blockId1),
759
+ });
760
+ }
761
+ }
762
+ else {
763
+ throw error;
764
+ }
765
+ }
766
+ // Retrieve second block (with recovery if needed)
767
+ const b2Checksum = typeof blockId2 === 'string' ? this.hexToChecksum(blockId2) : blockId2;
768
+ let block2Data;
769
+ try {
770
+ block2Data = await this.getData(b2Checksum);
771
+ }
772
+ catch (error) {
773
+ if (block2ParityIds?.length) {
774
+ const recovery = await this.recoverBlock(b2Checksum);
775
+ if (recovery.success && recovery.recoveredBlock) {
776
+ block2Data = recovery.recoveredBlock;
777
+ }
778
+ else {
779
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
780
+ KEY: this.keyToHex(blockId2),
781
+ });
782
+ }
783
+ }
784
+ else {
785
+ throw error;
786
+ }
787
+ }
788
+ // XOR to reconstruct padded CBL
789
+ const reconstructedPadded = (0, brightchain_lib_1.xorArrays)(block1Data.data, block2Data.data);
790
+ // Remove padding to get original CBL
791
+ return (0, brightchain_lib_1.unpadCblData)(reconstructedPadded);
792
+ }
793
+ parseCBLMagnetUrl(magnetUrl) {
794
+ if (!magnetUrl || !magnetUrl.startsWith('magnet:?')) {
795
+ throw new Error('Invalid magnet URL: must start with "magnet:?"');
796
+ }
797
+ const queryString = magnetUrl.substring('magnet:?'.length);
798
+ const params = new URLSearchParams(queryString);
799
+ const xt = params.get('xt');
800
+ if (xt !== 'urn:brightchain:cbl') {
801
+ throw new Error('Invalid magnet URL: xt parameter must be "urn:brightchain:cbl"');
802
+ }
803
+ const blockId1 = params.get('b1');
804
+ const blockId2 = params.get('b2');
805
+ const blockSizeStr = params.get('bs');
806
+ if (!blockId1)
807
+ throw new Error('Invalid magnet URL: missing b1 parameter');
808
+ if (!blockId2)
809
+ throw new Error('Invalid magnet URL: missing b2 parameter');
810
+ if (!blockSizeStr)
811
+ throw new Error('Invalid magnet URL: missing bs (block size) parameter');
812
+ const blockSize = parseInt(blockSizeStr, 10);
813
+ if (isNaN(blockSize) || blockSize <= 0) {
814
+ throw new Error('Invalid magnet URL: invalid block size');
815
+ }
816
+ const p1Param = params.get('p1');
817
+ const p2Param = params.get('p2');
818
+ const block1ParityIds = p1Param
819
+ ? p1Param
820
+ .split(',')
821
+ .filter((id) => id)
822
+ .map(toStorageKey)
823
+ : undefined;
824
+ const block2ParityIds = p2Param
825
+ ? p2Param
826
+ .split(',')
827
+ .filter((id) => id)
828
+ .map(toStorageKey)
829
+ : undefined;
830
+ const isEncrypted = params.get('enc') === '1';
831
+ return {
832
+ blockId1: toStorageKey(blockId1),
833
+ blockId2: toStorageKey(blockId2),
834
+ blockSize,
835
+ block1ParityIds,
836
+ block2ParityIds,
837
+ isEncrypted,
838
+ };
839
+ }
840
+ generateCBLMagnetUrl(blockId1, blockId2, blockSize, block1ParityIds, block2ParityIds, isEncrypted) {
841
+ const b1Id = typeof blockId1 === 'string' ? blockId1 : blockId1.toHex();
842
+ const b2Id = typeof blockId2 === 'string' ? blockId2 : blockId2.toHex();
843
+ const params = new URLSearchParams();
844
+ params.set('xt', 'urn:brightchain:cbl');
845
+ params.set('bs', blockSize.toString());
846
+ params.set('b1', b1Id);
847
+ params.set('b2', b2Id);
848
+ if (block1ParityIds?.length) {
849
+ params.set('p1', block1ParityIds.join(','));
850
+ }
851
+ if (block2ParityIds?.length) {
852
+ params.set('p2', block2ParityIds.join(','));
853
+ }
854
+ if (isEncrypted) {
855
+ params.set('enc', '1');
856
+ }
857
+ return `magnet:?${params.toString()}`;
858
+ }
859
+ // =========================================================================
860
+ // IPooledBlockStore — Pool-Scoped Block Operations
861
+ // =========================================================================
862
+ async hasInPool(pool, hash) {
863
+ (0, brightchain_lib_1.validatePoolId)(pool);
864
+ const objectKey = this.buildObjectKey(hash, pool);
865
+ return this.withRetry('hasInPool', hash, () => this.objectExists(objectKey));
866
+ }
867
+ async getFromPool(pool, hash) {
868
+ (0, brightchain_lib_1.validatePoolId)(pool);
869
+ const objectKey = this.buildObjectKey(hash, pool);
870
+ const data = await this.withRetry('getFromPool', hash, () => this.downloadObject(objectKey));
871
+ // Record access in metadata
872
+ try {
873
+ const metaKey = this.buildMetaKey(hash, pool);
874
+ if (await this.objectExists(metaKey)) {
875
+ const metaData = await this.downloadObject(metaKey);
876
+ const metadata = this.deserializeMetadata(metaData);
877
+ metadata.accessCount++;
878
+ metadata.lastAccessedAt = new Date();
879
+ await this.uploadObject(metaKey, this.serializeMetadata(metadata));
880
+ }
881
+ }
882
+ catch {
883
+ // Ignore metadata access errors
884
+ }
885
+ return data;
886
+ }
887
+ async putInPool(pool, data, options) {
888
+ (0, brightchain_lib_1.validatePoolId)(pool);
889
+ // Compute checksum for the data
890
+ const block = new brightchain_lib_1.RawDataBlock(this._blockSize, data);
891
+ const hash = block.idChecksum.toHex();
892
+ const objectKey = this.buildObjectKey(hash, pool);
893
+ // Idempotent — skip if already exists
894
+ const exists = await this.withRetry('putInPool.exists', hash, () => this.objectExists(objectKey));
895
+ if (exists)
896
+ return hash;
897
+ // Upload block data
898
+ await this.withRetry('putInPool.upload', hash, () => this.uploadObject(objectKey, data));
899
+ // Create and upload metadata sidecar
900
+ const metadata = (0, brightchain_lib_1.createDefaultBlockMetadata)(toStorageKey(hash), data.length, hash, options, pool);
901
+ const metaKey = this.buildMetaKey(hash, pool);
902
+ await this.withRetry('putInPool.meta', hash, () => this.uploadObject(metaKey, this.serializeMetadata(metadata)));
903
+ return hash;
904
+ }
905
+ async deleteFromPool(pool, hash) {
906
+ (0, brightchain_lib_1.validatePoolId)(pool);
907
+ const objectKey = this.buildObjectKey(hash, pool);
908
+ const exists = await this.withRetry('deleteFromPool.exists', hash, () => this.objectExists(objectKey));
909
+ if (!exists) {
910
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.KeyNotFound, undefined, {
911
+ KEY: hash,
912
+ });
913
+ }
914
+ // Delete parity blocks
915
+ try {
916
+ const parityPrefix = this.buildParityPrefix(hash, pool);
917
+ const parityKeys = await this.listObjects(parityPrefix);
918
+ for (const pk of parityKeys) {
919
+ try {
920
+ await this.deleteObject(pk);
921
+ }
922
+ catch {
923
+ // Ignore errors deleting parity files
924
+ }
925
+ }
926
+ }
927
+ catch {
928
+ // Ignore errors listing parity blocks
929
+ }
930
+ // Delete block data
931
+ await this.withRetry('deleteFromPool.delete', hash, () => this.deleteObject(objectKey));
932
+ // Delete metadata sidecar
933
+ try {
934
+ const metaKey = this.buildMetaKey(hash, pool);
935
+ await this.deleteObject(metaKey);
936
+ }
937
+ catch {
938
+ // Ignore errors deleting metadata
939
+ }
940
+ }
941
+ // =========================================================================
942
+ // IPooledBlockStore — Pool Management
943
+ // =========================================================================
944
+ async listPools() {
945
+ const prefix = this.config.keyPrefix ?? '';
946
+ const keys = await this.listObjects(prefix);
947
+ const pools = new Set();
948
+ for (const key of keys) {
949
+ // Strip the prefix and extract the pool segment (first path component)
950
+ const relative = key.substring(prefix.length);
951
+ const slashIndex = relative.indexOf('/');
952
+ if (slashIndex > 0) {
953
+ const poolId = relative.substring(0, slashIndex);
954
+ // Skip 'parity' segments that appear at pool level
955
+ if (poolId !== 'parity') {
956
+ pools.add(poolId);
957
+ }
958
+ }
959
+ }
960
+ return [...pools];
961
+ }
962
+ async *listBlocksInPool(pool, options) {
963
+ (0, brightchain_lib_1.validatePoolId)(pool);
964
+ const poolPrefix = this.buildPoolPrefix(pool);
965
+ const keys = await this.listObjects(poolPrefix);
966
+ const limit = options?.limit;
967
+ const cursor = options?.cursor;
968
+ let pastCursor = cursor === undefined;
969
+ let yielded = 0;
970
+ for (const key of keys) {
971
+ // Skip .meta and parity keys
972
+ if (key.endsWith('.meta'))
973
+ continue;
974
+ if (key.includes('/parity/'))
975
+ continue;
976
+ const hash = key.substring(poolPrefix.length);
977
+ if (!hash || hash.includes('/'))
978
+ continue;
979
+ if (!pastCursor) {
980
+ if (hash === cursor) {
981
+ pastCursor = true;
982
+ }
983
+ continue;
984
+ }
985
+ yield hash;
986
+ yielded++;
987
+ if (limit !== undefined && yielded >= limit) {
988
+ break;
989
+ }
990
+ }
991
+ }
992
+ async getPoolStats(pool) {
993
+ (0, brightchain_lib_1.validatePoolId)(pool);
994
+ const poolPrefix = this.buildPoolPrefix(pool);
995
+ const keys = await this.listObjects(poolPrefix);
996
+ let blockCount = 0;
997
+ let totalBytes = 0;
998
+ let earliestCreated = null;
999
+ let latestAccessed = null;
1000
+ for (const key of keys) {
1001
+ if (key.endsWith('.meta')) {
1002
+ try {
1003
+ const data = await this.downloadObject(key);
1004
+ const metadata = this.deserializeMetadata(data);
1005
+ blockCount++;
1006
+ totalBytes += metadata.size;
1007
+ if (!earliestCreated || metadata.createdAt < earliestCreated) {
1008
+ earliestCreated = metadata.createdAt;
1009
+ }
1010
+ if (!latestAccessed || metadata.lastAccessedAt > latestAccessed) {
1011
+ latestAccessed = metadata.lastAccessedAt;
1012
+ }
1013
+ }
1014
+ catch {
1015
+ // Skip unreadable metadata
1016
+ }
1017
+ }
1018
+ }
1019
+ const now = new Date();
1020
+ return {
1021
+ poolId: pool,
1022
+ blockCount,
1023
+ totalBytes,
1024
+ createdAt: earliestCreated ?? now,
1025
+ lastAccessedAt: latestAccessed ?? now,
1026
+ };
1027
+ }
1028
+ async deletePool(pool) {
1029
+ (0, brightchain_lib_1.validatePoolId)(pool);
1030
+ await this.performPoolDeletion(pool);
1031
+ }
1032
+ async performPoolDeletion(pool) {
1033
+ const poolPrefix = this.buildPoolPrefix(pool);
1034
+ const keys = await this.listObjects(poolPrefix);
1035
+ for (const key of keys) {
1036
+ try {
1037
+ await this.deleteObject(key);
1038
+ }
1039
+ catch {
1040
+ // Best-effort deletion
1041
+ }
1042
+ }
1043
+ }
1044
+ // =========================================================================
1045
+ // IPooledBlockStore — Pool-Scoped Whitening Operations
1046
+ // =========================================================================
1047
+ async getRandomBlocksFromPool(pool, count) {
1048
+ (0, brightchain_lib_1.validatePoolId)(pool);
1049
+ if (count <= 0)
1050
+ return [];
1051
+ const poolPrefix = this.buildPoolPrefix(pool);
1052
+ const keys = await this.listObjects(poolPrefix);
1053
+ // Collect block checksums (skip .meta and parity)
1054
+ const checksums = [];
1055
+ for (const key of keys) {
1056
+ if (key.endsWith('.meta'))
1057
+ continue;
1058
+ if (key.includes('/parity/'))
1059
+ continue;
1060
+ const hash = key.substring(poolPrefix.length);
1061
+ if (hash && !hash.includes('/')) {
1062
+ checksums.push(hash);
1063
+ }
1064
+ }
1065
+ if (checksums.length === 0)
1066
+ return [];
1067
+ // Sample without replacement
1068
+ const result = [];
1069
+ const available = [...checksums];
1070
+ const numToReturn = Math.min(count, available.length);
1071
+ for (let i = 0; i < numToReturn; i++) {
1072
+ const randomIndex = Math.floor(Math.random() * available.length);
1073
+ result.push(this.hexToChecksum(available[randomIndex]));
1074
+ available.splice(randomIndex, 1);
1075
+ }
1076
+ return result;
1077
+ }
1078
+ async bootstrapPool(pool, blockSize, count) {
1079
+ (0, brightchain_lib_1.validatePoolId)(pool);
1080
+ if (count <= 0)
1081
+ return;
1082
+ for (let i = 0; i < count; i++) {
1083
+ const data = brightchain_lib_1.XorService.generateKey(blockSize);
1084
+ await this.putInPool(pool, data);
1085
+ }
1086
+ }
1087
+ async validatePoolDeletion(pool) {
1088
+ (0, brightchain_lib_1.validatePoolId)(pool);
1089
+ // For cloud stores, we do a simplified validation:
1090
+ // We don't have cross-pool CBL dependency tracking in the cloud,
1091
+ // so we return safe=true. Full CBL dependency checking would require
1092
+ // scanning all pools' blocks for CBL references, which is expensive.
1093
+ return {
1094
+ safe: true,
1095
+ dependentPools: [],
1096
+ referencedBlocks: [],
1097
+ };
1098
+ }
1099
+ async forceDeletePool(pool) {
1100
+ (0, brightchain_lib_1.validatePoolId)(pool);
1101
+ await this.performPoolDeletion(pool);
1102
+ }
1103
+ // =========================================================================
1104
+ // IPooledBlockStore — Pool-Scoped CBL Whitening Operations
1105
+ // =========================================================================
1106
+ async storeCBLWithWhiteningInPool(pool, cblData, options) {
1107
+ (0, brightchain_lib_1.validatePoolId)(pool);
1108
+ if (!cblData || cblData.length === 0) {
1109
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.BlockValidationFailed, undefined, {
1110
+ ERROR: 'CBL data cannot be empty',
1111
+ });
1112
+ }
1113
+ const paddedCbl = (0, brightchain_lib_1.padToBlockSize)(cblData, this._blockSize);
1114
+ if (paddedCbl.length > this._blockSize) {
1115
+ throw new brightchain_lib_1.StoreError(brightchain_lib_1.StoreErrorType.BlockValidationFailed, undefined, {
1116
+ ERROR: `CBL data too large: padded size (${paddedCbl.length}) exceeds block size (${this._blockSize}).`,
1117
+ });
1118
+ }
1119
+ // Generate randomizer
1120
+ let randomBlock;
1121
+ try {
1122
+ const poolRandomBlocks = await this.getRandomBlocksFromPool(pool, 1);
1123
+ if (poolRandomBlocks.length > 0) {
1124
+ const blockData = await this.getFromPool(pool, poolRandomBlocks[0].toHex());
1125
+ if (blockData.length >= paddedCbl.length) {
1126
+ randomBlock = blockData.slice(0, paddedCbl.length);
1127
+ }
1128
+ else {
1129
+ randomBlock = brightchain_lib_1.XorService.generateKey(paddedCbl.length);
1130
+ }
1131
+ }
1132
+ else {
1133
+ randomBlock = brightchain_lib_1.XorService.generateKey(paddedCbl.length);
1134
+ }
1135
+ }
1136
+ catch {
1137
+ randomBlock = brightchain_lib_1.XorService.generateKey(paddedCbl.length);
1138
+ }
1139
+ const xorResult = (0, brightchain_lib_1.xorArrays)(paddedCbl, randomBlock);
1140
+ // Store both blocks in the pool
1141
+ const block1Hash = await this.putInPool(pool, randomBlock, options);
1142
+ const block2Hash = await this.putInPool(pool, xorResult, options);
1143
+ const block1Id = toStorageKey(block1Hash);
1144
+ const block2Id = toStorageKey(block2Hash);
1145
+ const magnetUrl = this.generateCBLMagnetUrl(block1Id, block2Id, this._blockSize, undefined, undefined, options?.isEncrypted);
1146
+ return {
1147
+ blockId1: block1Id,
1148
+ blockId2: block2Id,
1149
+ blockSize: this._blockSize,
1150
+ magnetUrl,
1151
+ isEncrypted: options?.isEncrypted,
1152
+ };
1153
+ }
1154
+ async retrieveCBLFromPool(pool, blockId1, blockId2, _block1ParityIds, _block2ParityIds) {
1155
+ (0, brightchain_lib_1.validatePoolId)(pool);
1156
+ const b1Hex = this.keyToHex(blockId1);
1157
+ const b2Hex = this.keyToHex(blockId2);
1158
+ const block1Data = await this.getFromPool(pool, b1Hex);
1159
+ const block2Data = await this.getFromPool(pool, b2Hex);
1160
+ const reconstructedPadded = (0, brightchain_lib_1.xorArrays)(block1Data, block2Data);
1161
+ return (0, brightchain_lib_1.unpadCblData)(reconstructedPadded);
1162
+ }
1163
+ }
1164
+ exports.CloudBlockStoreBase = CloudBlockStoreBase;
1165
+ //# sourceMappingURL=cloudBlockStoreBase.js.map