@effect/cluster 0.28.3 → 0.29.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 (626) hide show
  1. package/ClusterError/package.json +6 -0
  2. package/ClusterMetrics/package.json +6 -0
  3. package/ClusterSchema/package.json +6 -0
  4. package/DeliverAt/package.json +6 -0
  5. package/Entity/package.json +6 -0
  6. package/EntityAddress/package.json +6 -0
  7. package/EntityId/package.json +6 -0
  8. package/EntityType/package.json +6 -0
  9. package/Envelope/package.json +6 -0
  10. package/HttpCommon/package.json +6 -0
  11. package/HttpRunner/package.json +6 -0
  12. package/HttpShardManager/package.json +6 -0
  13. package/MachineId/package.json +6 -0
  14. package/MessageStorage/package.json +6 -0
  15. package/README.md +2 -2
  16. package/Reply/package.json +6 -0
  17. package/Runner/package.json +6 -0
  18. package/RunnerAddress/package.json +6 -0
  19. package/RunnerHealth/package.json +6 -0
  20. package/RunnerServer/package.json +6 -0
  21. package/Runners/package.json +6 -0
  22. package/ShardStorage/package.json +6 -0
  23. package/Singleton/package.json +6 -0
  24. package/SingletonAddress/package.json +6 -0
  25. package/Snowflake/package.json +6 -0
  26. package/SocketRunner/package.json +6 -0
  27. package/SocketShardManager/package.json +6 -0
  28. package/SqlMessageStorage/package.json +6 -0
  29. package/SqlShardStorage/package.json +6 -0
  30. package/SynchronizedClock/package.json +6 -0
  31. package/dist/cjs/ClusterError.js +180 -0
  32. package/dist/cjs/ClusterError.js.map +1 -0
  33. package/dist/cjs/ClusterMetrics.js +63 -0
  34. package/dist/cjs/ClusterMetrics.js.map +1 -0
  35. package/dist/cjs/{Pods.js → ClusterSchema.js} +10 -22
  36. package/dist/cjs/ClusterSchema.js.map +1 -0
  37. package/dist/cjs/DeliverAt.js +30 -0
  38. package/dist/cjs/DeliverAt.js.map +1 -0
  39. package/dist/cjs/Entity.js +187 -0
  40. package/dist/cjs/Entity.js.map +1 -0
  41. package/dist/cjs/EntityAddress.js +54 -0
  42. package/dist/cjs/EntityAddress.js.map +1 -0
  43. package/dist/cjs/{AtLeastOnce.js → EntityId.js} +6 -7
  44. package/dist/cjs/EntityId.js.map +1 -0
  45. package/dist/cjs/{ShardManagerClient.js → EntityType.js} +5 -16
  46. package/dist/cjs/EntityType.js.map +1 -0
  47. package/dist/cjs/Envelope.js +168 -0
  48. package/dist/cjs/Envelope.js.map +1 -0
  49. package/dist/cjs/HttpCommon.js +49 -0
  50. package/dist/cjs/HttpCommon.js.map +1 -0
  51. package/dist/cjs/HttpRunner.js +108 -0
  52. package/dist/cjs/HttpRunner.js.map +1 -0
  53. package/dist/cjs/HttpShardManager.js +140 -0
  54. package/dist/cjs/HttpShardManager.js.map +1 -0
  55. package/dist/cjs/{AtLeastOnceStorage.js → MachineId.js} +11 -9
  56. package/dist/cjs/MachineId.js.map +1 -0
  57. package/dist/cjs/Message.js +99 -18
  58. package/dist/cjs/Message.js.map +1 -1
  59. package/dist/cjs/MessageStorage.js +356 -0
  60. package/dist/cjs/MessageStorage.js.map +1 -0
  61. package/dist/cjs/Reply.js +200 -0
  62. package/dist/cjs/Reply.js.map +1 -0
  63. package/dist/cjs/Runner.js +79 -0
  64. package/dist/cjs/Runner.js.map +1 -0
  65. package/dist/cjs/RunnerAddress.js +63 -0
  66. package/dist/cjs/RunnerAddress.js.map +1 -0
  67. package/dist/cjs/RunnerHealth.js +68 -0
  68. package/dist/cjs/RunnerHealth.js.map +1 -0
  69. package/dist/cjs/RunnerServer.js +125 -0
  70. package/dist/cjs/RunnerServer.js.map +1 -0
  71. package/dist/cjs/Runners.js +344 -0
  72. package/dist/cjs/Runners.js.map +1 -0
  73. package/dist/cjs/ShardId.js +7 -46
  74. package/dist/cjs/ShardId.js.map +1 -1
  75. package/dist/cjs/ShardManager.js +493 -8
  76. package/dist/cjs/ShardManager.js.map +1 -1
  77. package/dist/cjs/ShardStorage.js +139 -0
  78. package/dist/cjs/ShardStorage.js.map +1 -0
  79. package/dist/cjs/Sharding.js +732 -88
  80. package/dist/cjs/Sharding.js.map +1 -1
  81. package/dist/cjs/ShardingConfig.js +85 -18
  82. package/dist/cjs/ShardingConfig.js.map +1 -1
  83. package/dist/cjs/ShardingRegistrationEvent.js +26 -32
  84. package/dist/cjs/ShardingRegistrationEvent.js.map +1 -1
  85. package/dist/cjs/{ManagerConfig.js → Singleton.js} +11 -20
  86. package/dist/cjs/Singleton.js.map +1 -0
  87. package/dist/cjs/SingletonAddress.js +50 -0
  88. package/dist/cjs/SingletonAddress.js.map +1 -0
  89. package/dist/cjs/Snowflake.js +133 -0
  90. package/dist/cjs/Snowflake.js.map +1 -0
  91. package/dist/cjs/SocketRunner.js +40 -0
  92. package/dist/cjs/SocketRunner.js.map +1 -0
  93. package/dist/cjs/SocketShardManager.js +33 -0
  94. package/dist/cjs/SocketShardManager.js.map +1 -0
  95. package/dist/cjs/SqlMessageStorage.js +668 -0
  96. package/dist/cjs/SqlMessageStorage.js.map +1 -0
  97. package/dist/cjs/SqlShardStorage.js +228 -0
  98. package/dist/cjs/SqlShardStorage.js.map +1 -0
  99. package/dist/cjs/SynchronizedClock.js +66 -0
  100. package/dist/cjs/SynchronizedClock.js.map +1 -0
  101. package/dist/cjs/index.js +57 -45
  102. package/dist/cjs/internal/entityManager.js +311 -143
  103. package/dist/cjs/internal/entityManager.js.map +1 -1
  104. package/dist/cjs/internal/entityReaper.js +47 -0
  105. package/dist/cjs/internal/entityReaper.js.map +1 -0
  106. package/dist/cjs/internal/hash.js +20 -0
  107. package/dist/cjs/internal/hash.js.map +1 -0
  108. package/dist/cjs/internal/interruptors.js +9 -0
  109. package/dist/cjs/internal/interruptors.js.map +1 -0
  110. package/dist/cjs/internal/resourceMap.js +88 -0
  111. package/dist/cjs/internal/resourceMap.js.map +1 -0
  112. package/dist/cjs/internal/resourceRef.js +92 -0
  113. package/dist/cjs/internal/resourceRef.js.map +1 -0
  114. package/dist/cjs/internal/shardManager.js +219 -235
  115. package/dist/cjs/internal/shardManager.js.map +1 -1
  116. package/dist/dts/ClusterError.d.ts +169 -0
  117. package/dist/dts/ClusterError.d.ts.map +1 -0
  118. package/dist/dts/ClusterMetrics.d.ts +50 -0
  119. package/dist/dts/ClusterMetrics.d.ts.map +1 -0
  120. package/dist/dts/ClusterSchema.d.ts +13 -0
  121. package/dist/dts/ClusterSchema.d.ts.map +1 -0
  122. package/dist/dts/DeliverAt.d.ts +27 -0
  123. package/dist/dts/DeliverAt.d.ts.map +1 -0
  124. package/dist/dts/Entity.d.ts +180 -0
  125. package/dist/dts/Entity.d.ts.map +1 -0
  126. package/dist/dts/EntityAddress.d.ts +55 -0
  127. package/dist/dts/EntityAddress.d.ts.map +1 -0
  128. package/dist/dts/EntityId.d.ts +15 -0
  129. package/dist/dts/EntityId.d.ts.map +1 -0
  130. package/dist/dts/EntityType.d.ts +15 -0
  131. package/dist/dts/EntityType.d.ts.map +1 -0
  132. package/dist/dts/Envelope.d.ts +252 -0
  133. package/dist/dts/Envelope.d.ts.map +1 -0
  134. package/dist/dts/HttpCommon.d.ts +25 -0
  135. package/dist/dts/HttpCommon.d.ts.map +1 -0
  136. package/dist/dts/HttpRunner.d.ts +76 -0
  137. package/dist/dts/HttpRunner.d.ts.map +1 -0
  138. package/dist/dts/HttpShardManager.d.ts +119 -0
  139. package/dist/dts/HttpShardManager.d.ts.map +1 -0
  140. package/dist/dts/MachineId.d.ts +20 -0
  141. package/dist/dts/MachineId.d.ts.map +1 -0
  142. package/dist/dts/Message.d.ts +91 -74
  143. package/dist/dts/Message.d.ts.map +1 -1
  144. package/dist/dts/MessageStorage.d.ts +336 -0
  145. package/dist/dts/MessageStorage.d.ts.map +1 -0
  146. package/dist/dts/Reply.d.ts +171 -0
  147. package/dist/dts/Reply.d.ts.map +1 -0
  148. package/dist/dts/Runner.d.ts +81 -0
  149. package/dist/dts/Runner.d.ts.map +1 -0
  150. package/dist/dts/RunnerAddress.d.ts +56 -0
  151. package/dist/dts/RunnerAddress.d.ts.map +1 -0
  152. package/dist/dts/RunnerHealth.d.ts +54 -0
  153. package/dist/dts/RunnerHealth.d.ts.map +1 -0
  154. package/dist/dts/RunnerServer.d.ts +44 -0
  155. package/dist/dts/RunnerServer.d.ts.map +1 -0
  156. package/dist/dts/Runners.d.ts +161 -0
  157. package/dist/dts/Runners.d.ts.map +1 -0
  158. package/dist/dts/ShardId.d.ts +5 -55
  159. package/dist/dts/ShardId.d.ts.map +1 -1
  160. package/dist/dts/ShardManager.d.ts +435 -23
  161. package/dist/dts/ShardManager.d.ts.map +1 -1
  162. package/dist/dts/ShardStorage.d.ts +200 -0
  163. package/dist/dts/ShardStorage.d.ts.map +1 -0
  164. package/dist/dts/Sharding.d.ts +109 -131
  165. package/dist/dts/Sharding.d.ts.map +1 -1
  166. package/dist/dts/ShardingConfig.d.ts +147 -44
  167. package/dist/dts/ShardingConfig.d.ts.map +1 -1
  168. package/dist/dts/ShardingRegistrationEvent.d.ts +38 -23
  169. package/dist/dts/ShardingRegistrationEvent.d.ts.map +1 -1
  170. package/dist/dts/Singleton.d.ts +13 -0
  171. package/dist/dts/Singleton.d.ts.map +1 -0
  172. package/dist/dts/SingletonAddress.d.ts +49 -0
  173. package/dist/dts/SingletonAddress.d.ts.map +1 -0
  174. package/dist/dts/Snowflake.d.ts +121 -0
  175. package/dist/dts/Snowflake.d.ts.map +1 -0
  176. package/dist/dts/SocketRunner.d.ts +22 -0
  177. package/dist/dts/SocketRunner.d.ts.map +1 -0
  178. package/dist/dts/SocketShardManager.d.ts +17 -0
  179. package/dist/dts/SocketShardManager.d.ts.map +1 -0
  180. package/dist/dts/SqlMessageStorage.d.ts +43 -0
  181. package/dist/dts/SqlMessageStorage.d.ts.map +1 -0
  182. package/dist/dts/SqlShardStorage.d.ts +38 -0
  183. package/dist/dts/SqlShardStorage.d.ts.map +1 -0
  184. package/dist/dts/SynchronizedClock.d.ts +19 -0
  185. package/dist/dts/SynchronizedClock.d.ts.map +1 -0
  186. package/dist/dts/index.d.ts +48 -24
  187. package/dist/dts/index.d.ts.map +1 -1
  188. package/dist/dts/internal/entityReaper.d.ts +2 -0
  189. package/dist/dts/internal/entityReaper.d.ts.map +1 -0
  190. package/dist/dts/internal/hash.d.ts +2 -0
  191. package/dist/dts/internal/hash.d.ts.map +1 -0
  192. package/dist/dts/internal/interruptors.d.ts +2 -0
  193. package/dist/dts/internal/interruptors.d.ts.map +1 -0
  194. package/dist/dts/internal/resourceMap.d.ts +22 -0
  195. package/dist/dts/internal/resourceMap.d.ts.map +1 -0
  196. package/dist/dts/internal/resourceRef.d.ts +25 -0
  197. package/dist/dts/internal/resourceRef.d.ts.map +1 -0
  198. package/dist/dts/internal/shardManager.d.ts +1 -11
  199. package/dist/dts/internal/shardManager.d.ts.map +1 -1
  200. package/dist/esm/ClusterError.js +164 -0
  201. package/dist/esm/ClusterError.js.map +1 -0
  202. package/dist/esm/ClusterMetrics.js +54 -0
  203. package/dist/esm/ClusterMetrics.js.map +1 -0
  204. package/dist/esm/ClusterSchema.js +13 -0
  205. package/dist/esm/ClusterSchema.js.map +1 -0
  206. package/dist/esm/DeliverAt.js +22 -0
  207. package/dist/esm/DeliverAt.js.map +1 -0
  208. package/dist/esm/Entity.js +173 -0
  209. package/dist/esm/Entity.js.map +1 -0
  210. package/dist/esm/EntityAddress.js +44 -0
  211. package/dist/esm/EntityAddress.js.map +1 -0
  212. package/dist/esm/EntityId.js +10 -0
  213. package/dist/esm/EntityId.js.map +1 -0
  214. package/dist/esm/EntityType.js +10 -0
  215. package/dist/esm/EntityType.js.map +1 -0
  216. package/dist/esm/Envelope.js +154 -0
  217. package/dist/esm/Envelope.js.map +1 -0
  218. package/dist/esm/HttpCommon.js +38 -0
  219. package/dist/esm/HttpCommon.js.map +1 -0
  220. package/dist/esm/HttpRunner.js +98 -0
  221. package/dist/esm/HttpRunner.js.map +1 -0
  222. package/dist/esm/HttpShardManager.js +128 -0
  223. package/dist/esm/HttpShardManager.js.map +1 -0
  224. package/dist/esm/MachineId.js +17 -0
  225. package/dist/esm/MachineId.js.map +1 -0
  226. package/dist/esm/Message.js +88 -17
  227. package/dist/esm/Message.js.map +1 -1
  228. package/dist/esm/MessageStorage.js +345 -0
  229. package/dist/esm/MessageStorage.js.map +1 -0
  230. package/dist/esm/Reply.js +184 -0
  231. package/dist/esm/Reply.js.map +1 -0
  232. package/dist/esm/Runner.js +68 -0
  233. package/dist/esm/Runner.js.map +1 -0
  234. package/dist/esm/RunnerAddress.js +52 -0
  235. package/dist/esm/RunnerAddress.js.map +1 -0
  236. package/dist/esm/RunnerHealth.js +58 -0
  237. package/dist/esm/RunnerHealth.js.map +1 -0
  238. package/dist/esm/RunnerServer.js +116 -0
  239. package/dist/esm/RunnerServer.js.map +1 -0
  240. package/dist/esm/Runners.js +332 -0
  241. package/dist/esm/Runners.js.map +1 -0
  242. package/dist/esm/ShardId.js +5 -42
  243. package/dist/esm/ShardId.js.map +1 -1
  244. package/dist/esm/ShardManager.js +486 -7
  245. package/dist/esm/ShardManager.js.map +1 -1
  246. package/dist/esm/ShardStorage.js +129 -0
  247. package/dist/esm/ShardStorage.js.map +1 -0
  248. package/dist/esm/Sharding.js +730 -87
  249. package/dist/esm/Sharding.js.map +1 -1
  250. package/dist/esm/ShardingConfig.js +80 -17
  251. package/dist/esm/ShardingConfig.js.map +1 -1
  252. package/dist/esm/ShardingRegistrationEvent.js +19 -29
  253. package/dist/esm/ShardingRegistrationEvent.js.map +1 -1
  254. package/dist/esm/Singleton.js +15 -0
  255. package/dist/esm/Singleton.js.map +1 -0
  256. package/dist/esm/SingletonAddress.js +40 -0
  257. package/dist/esm/SingletonAddress.js.map +1 -0
  258. package/dist/esm/Snowflake.js +117 -0
  259. package/dist/esm/Snowflake.js.map +1 -0
  260. package/dist/esm/SocketRunner.js +31 -0
  261. package/dist/esm/SocketRunner.js.map +1 -0
  262. package/dist/esm/SocketShardManager.js +24 -0
  263. package/dist/esm/SocketShardManager.js.map +1 -0
  264. package/dist/esm/SqlMessageStorage.js +658 -0
  265. package/dist/esm/SqlMessageStorage.js.map +1 -0
  266. package/dist/esm/SqlShardStorage.js +218 -0
  267. package/dist/esm/SqlShardStorage.js.map +1 -0
  268. package/dist/esm/SynchronizedClock.js +57 -0
  269. package/dist/esm/SynchronizedClock.js.map +1 -0
  270. package/dist/esm/index.js +48 -24
  271. package/dist/esm/index.js.map +1 -1
  272. package/dist/esm/internal/entityManager.js +311 -142
  273. package/dist/esm/internal/entityManager.js.map +1 -1
  274. package/dist/esm/internal/entityReaper.js +38 -0
  275. package/dist/esm/internal/entityReaper.js.map +1 -0
  276. package/dist/esm/internal/hash.js +12 -0
  277. package/dist/esm/internal/hash.js.map +1 -0
  278. package/dist/esm/internal/interruptors.js +3 -0
  279. package/dist/esm/internal/interruptors.js.map +1 -0
  280. package/dist/esm/internal/resourceMap.js +79 -0
  281. package/dist/esm/internal/resourceMap.js.map +1 -0
  282. package/dist/esm/internal/resourceRef.js +83 -0
  283. package/dist/esm/internal/resourceRef.js.map +1 -0
  284. package/dist/esm/internal/shardManager.js +217 -233
  285. package/dist/esm/internal/shardManager.js.map +1 -1
  286. package/package.json +212 -154
  287. package/src/ClusterError.ts +193 -0
  288. package/src/ClusterMetrics.ts +62 -0
  289. package/src/ClusterSchema.ts +13 -0
  290. package/src/DeliverAt.ts +36 -0
  291. package/src/Entity.ts +438 -0
  292. package/src/EntityAddress.ts +55 -0
  293. package/src/EntityId.ts +16 -0
  294. package/src/EntityType.ts +16 -0
  295. package/src/Envelope.ts +352 -0
  296. package/src/HttpCommon.ts +73 -0
  297. package/src/HttpRunner.ts +196 -0
  298. package/src/HttpShardManager.ts +273 -0
  299. package/src/MachineId.ts +27 -0
  300. package/src/Message.ts +143 -92
  301. package/src/MessageStorage.ts +697 -0
  302. package/src/Reply.ts +295 -0
  303. package/src/Runner.ts +84 -0
  304. package/src/RunnerAddress.ts +61 -0
  305. package/src/RunnerHealth.ts +87 -0
  306. package/src/RunnerServer.ts +156 -0
  307. package/src/Runners.ts +533 -0
  308. package/src/ShardId.ts +10 -62
  309. package/src/ShardManager.ts +780 -29
  310. package/src/ShardStorage.ts +289 -0
  311. package/src/Sharding.ts +1060 -183
  312. package/src/ShardingConfig.ts +186 -45
  313. package/src/ShardingRegistrationEvent.ts +38 -39
  314. package/src/Singleton.ts +20 -0
  315. package/src/SingletonAddress.ts +47 -0
  316. package/src/Snowflake.ts +194 -0
  317. package/src/SocketRunner.ts +59 -0
  318. package/src/SocketShardManager.ts +48 -0
  319. package/src/SqlMessageStorage.ts +833 -0
  320. package/src/SqlShardStorage.ts +292 -0
  321. package/src/SynchronizedClock.ts +82 -0
  322. package/src/index.ts +54 -24
  323. package/src/internal/entityManager.ts +464 -361
  324. package/src/internal/entityReaper.ts +53 -0
  325. package/src/internal/hash.ts +11 -0
  326. package/src/internal/interruptors.ts +4 -0
  327. package/src/internal/resourceMap.ts +89 -0
  328. package/src/internal/resourceRef.ts +88 -0
  329. package/src/internal/shardManager.ts +273 -546
  330. package/AtLeastOnce/package.json +0 -6
  331. package/AtLeastOnceStorage/package.json +0 -6
  332. package/Broadcaster/package.json +0 -6
  333. package/ManagerConfig/package.json +0 -6
  334. package/MessageState/package.json +0 -6
  335. package/Messenger/package.json +0 -6
  336. package/Pod/package.json +0 -6
  337. package/PodAddress/package.json +0 -6
  338. package/Pods/package.json +0 -6
  339. package/PodsHealth/package.json +0 -6
  340. package/PoisonPill/package.json +0 -6
  341. package/RecipientAddress/package.json +0 -6
  342. package/RecipientBehaviour/package.json +0 -6
  343. package/RecipientBehaviourContext/package.json +0 -6
  344. package/RecipientType/package.json +0 -6
  345. package/Serialization/package.json +0 -6
  346. package/SerializedEnvelope/package.json +0 -6
  347. package/SerializedMessage/package.json +0 -6
  348. package/ShardManagerClient/package.json +0 -6
  349. package/ShardingEvent/package.json +0 -6
  350. package/ShardingException/package.json +0 -6
  351. package/Storage/package.json +0 -6
  352. package/dist/cjs/AtLeastOnce.js.map +0 -1
  353. package/dist/cjs/AtLeastOnceStorage.js.map +0 -1
  354. package/dist/cjs/Broadcaster.js +0 -6
  355. package/dist/cjs/Broadcaster.js.map +0 -1
  356. package/dist/cjs/ManagerConfig.js.map +0 -1
  357. package/dist/cjs/MessageState.js +0 -55
  358. package/dist/cjs/MessageState.js.map +0 -1
  359. package/dist/cjs/Messenger.js +0 -6
  360. package/dist/cjs/Messenger.js.map +0 -1
  361. package/dist/cjs/Pod.js +0 -78
  362. package/dist/cjs/Pod.js.map +0 -1
  363. package/dist/cjs/PodAddress.js +0 -77
  364. package/dist/cjs/PodAddress.js.map +0 -1
  365. package/dist/cjs/Pods.js.map +0 -1
  366. package/dist/cjs/PodsHealth.js +0 -41
  367. package/dist/cjs/PodsHealth.js.map +0 -1
  368. package/dist/cjs/PoisonPill.js +0 -78
  369. package/dist/cjs/PoisonPill.js.map +0 -1
  370. package/dist/cjs/RecipientAddress.js +0 -79
  371. package/dist/cjs/RecipientAddress.js.map +0 -1
  372. package/dist/cjs/RecipientBehaviour.js +0 -38
  373. package/dist/cjs/RecipientBehaviour.js.map +0 -1
  374. package/dist/cjs/RecipientBehaviourContext.js +0 -64
  375. package/dist/cjs/RecipientBehaviourContext.js.map +0 -1
  376. package/dist/cjs/RecipientType.js +0 -123
  377. package/dist/cjs/RecipientType.js.map +0 -1
  378. package/dist/cjs/Serialization.js +0 -32
  379. package/dist/cjs/Serialization.js.map +0 -1
  380. package/dist/cjs/SerializedEnvelope.js +0 -87
  381. package/dist/cjs/SerializedEnvelope.js.map +0 -1
  382. package/dist/cjs/SerializedMessage.js +0 -64
  383. package/dist/cjs/SerializedMessage.js.map +0 -1
  384. package/dist/cjs/ShardManagerClient.js.map +0 -1
  385. package/dist/cjs/ShardingEvent.js +0 -72
  386. package/dist/cjs/ShardingEvent.js.map +0 -1
  387. package/dist/cjs/ShardingException.js +0 -107
  388. package/dist/cjs/ShardingException.js.map +0 -1
  389. package/dist/cjs/Storage.js +0 -40
  390. package/dist/cjs/Storage.js.map +0 -1
  391. package/dist/cjs/internal/atLeastOnce.js +0 -35
  392. package/dist/cjs/internal/atLeastOnce.js.map +0 -1
  393. package/dist/cjs/internal/atLeastOnceStorage.js +0 -163
  394. package/dist/cjs/internal/atLeastOnceStorage.js.map +0 -1
  395. package/dist/cjs/internal/entityState.js +0 -47
  396. package/dist/cjs/internal/entityState.js.map +0 -1
  397. package/dist/cjs/internal/managerConfig.js +0 -46
  398. package/dist/cjs/internal/managerConfig.js.map +0 -1
  399. package/dist/cjs/internal/message.js +0 -48
  400. package/dist/cjs/internal/message.js.map +0 -1
  401. package/dist/cjs/internal/messageState.js +0 -79
  402. package/dist/cjs/internal/messageState.js.map +0 -1
  403. package/dist/cjs/internal/podWithMetadata.js +0 -54
  404. package/dist/cjs/internal/podWithMetadata.js.map +0 -1
  405. package/dist/cjs/internal/pods.js +0 -35
  406. package/dist/cjs/internal/pods.js.map +0 -1
  407. package/dist/cjs/internal/podsHealth.js +0 -40
  408. package/dist/cjs/internal/podsHealth.js.map +0 -1
  409. package/dist/cjs/internal/recipientBehaviour.js +0 -52
  410. package/dist/cjs/internal/recipientBehaviour.js.map +0 -1
  411. package/dist/cjs/internal/recipientBehaviourContext.js +0 -36
  412. package/dist/cjs/internal/recipientBehaviourContext.js.map +0 -1
  413. package/dist/cjs/internal/serialization.js +0 -48
  414. package/dist/cjs/internal/serialization.js.map +0 -1
  415. package/dist/cjs/internal/shardManagerClient.js +0 -48
  416. package/dist/cjs/internal/shardManagerClient.js.map +0 -1
  417. package/dist/cjs/internal/shardManagerState.js +0 -44
  418. package/dist/cjs/internal/shardManagerState.js.map +0 -1
  419. package/dist/cjs/internal/sharding.js +0 -306
  420. package/dist/cjs/internal/sharding.js.map +0 -1
  421. package/dist/cjs/internal/shardingConfig.js +0 -56
  422. package/dist/cjs/internal/shardingConfig.js.map +0 -1
  423. package/dist/cjs/internal/storage.js +0 -52
  424. package/dist/cjs/internal/storage.js.map +0 -1
  425. package/dist/cjs/internal/utils.js +0 -69
  426. package/dist/cjs/internal/utils.js.map +0 -1
  427. package/dist/dts/AtLeastOnce.d.ts +0 -20
  428. package/dist/dts/AtLeastOnce.d.ts.map +0 -1
  429. package/dist/dts/AtLeastOnceStorage.d.ts +0 -75
  430. package/dist/dts/AtLeastOnceStorage.d.ts.map +0 -1
  431. package/dist/dts/Broadcaster.d.ts +0 -32
  432. package/dist/dts/Broadcaster.d.ts.map +0 -1
  433. package/dist/dts/ManagerConfig.d.ts +0 -61
  434. package/dist/dts/ManagerConfig.d.ts.map +0 -1
  435. package/dist/dts/MessageState.d.ts +0 -107
  436. package/dist/dts/MessageState.d.ts.map +0 -1
  437. package/dist/dts/Messenger.d.ts +0 -32
  438. package/dist/dts/Messenger.d.ts.map +0 -1
  439. package/dist/dts/Pod.d.ts +0 -81
  440. package/dist/dts/Pod.d.ts.map +0 -1
  441. package/dist/dts/PodAddress.d.ts +0 -80
  442. package/dist/dts/PodAddress.d.ts.map +0 -1
  443. package/dist/dts/Pods.d.ts +0 -78
  444. package/dist/dts/Pods.d.ts.map +0 -1
  445. package/dist/dts/PodsHealth.d.ts +0 -66
  446. package/dist/dts/PodsHealth.d.ts.map +0 -1
  447. package/dist/dts/PoisonPill.d.ts +0 -78
  448. package/dist/dts/PoisonPill.d.ts.map +0 -1
  449. package/dist/dts/RecipientAddress.d.ts +0 -57
  450. package/dist/dts/RecipientAddress.d.ts.map +0 -1
  451. package/dist/dts/RecipientBehaviour.d.ts +0 -72
  452. package/dist/dts/RecipientBehaviour.d.ts.map +0 -1
  453. package/dist/dts/RecipientBehaviourContext.d.ts +0 -83
  454. package/dist/dts/RecipientBehaviourContext.d.ts.map +0 -1
  455. package/dist/dts/RecipientType.d.ts +0 -93
  456. package/dist/dts/RecipientType.d.ts.map +0 -1
  457. package/dist/dts/Serialization.d.ts +0 -58
  458. package/dist/dts/Serialization.d.ts.map +0 -1
  459. package/dist/dts/SerializedEnvelope.d.ts +0 -86
  460. package/dist/dts/SerializedEnvelope.d.ts.map +0 -1
  461. package/dist/dts/SerializedMessage.d.ts +0 -66
  462. package/dist/dts/SerializedMessage.d.ts.map +0 -1
  463. package/dist/dts/ShardManagerClient.d.ts +0 -50
  464. package/dist/dts/ShardManagerClient.d.ts.map +0 -1
  465. package/dist/dts/ShardingEvent.d.ts +0 -90
  466. package/dist/dts/ShardingEvent.d.ts.map +0 -1
  467. package/dist/dts/ShardingException.d.ts +0 -125
  468. package/dist/dts/ShardingException.d.ts.map +0 -1
  469. package/dist/dts/Storage.d.ts +0 -78
  470. package/dist/dts/Storage.d.ts.map +0 -1
  471. package/dist/dts/internal/atLeastOnce.d.ts +0 -2
  472. package/dist/dts/internal/atLeastOnce.d.ts.map +0 -1
  473. package/dist/dts/internal/atLeastOnceStorage.d.ts +0 -2
  474. package/dist/dts/internal/atLeastOnceStorage.d.ts.map +0 -1
  475. package/dist/dts/internal/entityState.d.ts +0 -21
  476. package/dist/dts/internal/entityState.d.ts.map +0 -1
  477. package/dist/dts/internal/managerConfig.d.ts +0 -2
  478. package/dist/dts/internal/managerConfig.d.ts.map +0 -1
  479. package/dist/dts/internal/message.d.ts +0 -9
  480. package/dist/dts/internal/message.d.ts.map +0 -1
  481. package/dist/dts/internal/messageState.d.ts +0 -2
  482. package/dist/dts/internal/messageState.d.ts.map +0 -1
  483. package/dist/dts/internal/podWithMetadata.d.ts +0 -2
  484. package/dist/dts/internal/podWithMetadata.d.ts.map +0 -1
  485. package/dist/dts/internal/pods.d.ts +0 -2
  486. package/dist/dts/internal/pods.d.ts.map +0 -1
  487. package/dist/dts/internal/podsHealth.d.ts +0 -2
  488. package/dist/dts/internal/podsHealth.d.ts.map +0 -1
  489. package/dist/dts/internal/recipientBehaviour.d.ts +0 -2
  490. package/dist/dts/internal/recipientBehaviour.d.ts.map +0 -1
  491. package/dist/dts/internal/recipientBehaviourContext.d.ts +0 -2
  492. package/dist/dts/internal/recipientBehaviourContext.d.ts.map +0 -1
  493. package/dist/dts/internal/serialization.d.ts +0 -2
  494. package/dist/dts/internal/serialization.d.ts.map +0 -1
  495. package/dist/dts/internal/shardManagerClient.d.ts +0 -2
  496. package/dist/dts/internal/shardManagerClient.d.ts.map +0 -1
  497. package/dist/dts/internal/shardManagerState.d.ts +0 -26
  498. package/dist/dts/internal/shardManagerState.d.ts.map +0 -1
  499. package/dist/dts/internal/sharding.d.ts +0 -2
  500. package/dist/dts/internal/sharding.d.ts.map +0 -1
  501. package/dist/dts/internal/shardingConfig.d.ts +0 -2
  502. package/dist/dts/internal/shardingConfig.d.ts.map +0 -1
  503. package/dist/dts/internal/storage.d.ts +0 -2
  504. package/dist/dts/internal/storage.d.ts.map +0 -1
  505. package/dist/dts/internal/utils.d.ts +0 -2
  506. package/dist/dts/internal/utils.d.ts.map +0 -1
  507. package/dist/esm/AtLeastOnce.js +0 -12
  508. package/dist/esm/AtLeastOnce.js.map +0 -1
  509. package/dist/esm/AtLeastOnceStorage.js +0 -17
  510. package/dist/esm/AtLeastOnceStorage.js.map +0 -1
  511. package/dist/esm/Broadcaster.js +0 -2
  512. package/dist/esm/Broadcaster.js.map +0 -1
  513. package/dist/esm/ManagerConfig.js +0 -26
  514. package/dist/esm/ManagerConfig.js.map +0 -1
  515. package/dist/esm/MessageState.js +0 -47
  516. package/dist/esm/MessageState.js.map +0 -1
  517. package/dist/esm/Messenger.js +0 -2
  518. package/dist/esm/Messenger.js.map +0 -1
  519. package/dist/esm/Pod.js +0 -65
  520. package/dist/esm/Pod.js.map +0 -1
  521. package/dist/esm/PodAddress.js +0 -64
  522. package/dist/esm/PodAddress.js.map +0 -1
  523. package/dist/esm/Pods.js +0 -27
  524. package/dist/esm/Pods.js.map +0 -1
  525. package/dist/esm/PodsHealth.js +0 -33
  526. package/dist/esm/PodsHealth.js.map +0 -1
  527. package/dist/esm/PoisonPill.js +0 -65
  528. package/dist/esm/PoisonPill.js.map +0 -1
  529. package/dist/esm/RecipientAddress.js +0 -67
  530. package/dist/esm/RecipientAddress.js.map +0 -1
  531. package/dist/esm/RecipientBehaviour.js +0 -30
  532. package/dist/esm/RecipientBehaviour.js.map +0 -1
  533. package/dist/esm/RecipientBehaviourContext.js +0 -56
  534. package/dist/esm/RecipientBehaviourContext.js.map +0 -1
  535. package/dist/esm/RecipientType.js +0 -108
  536. package/dist/esm/RecipientType.js.map +0 -1
  537. package/dist/esm/Serialization.js +0 -24
  538. package/dist/esm/Serialization.js.map +0 -1
  539. package/dist/esm/SerializedEnvelope.js +0 -74
  540. package/dist/esm/SerializedEnvelope.js.map +0 -1
  541. package/dist/esm/SerializedMessage.js +0 -51
  542. package/dist/esm/SerializedMessage.js.map +0 -1
  543. package/dist/esm/ShardManagerClient.js +0 -22
  544. package/dist/esm/ShardManagerClient.js.map +0 -1
  545. package/dist/esm/ShardingEvent.js +0 -62
  546. package/dist/esm/ShardingEvent.js.map +0 -1
  547. package/dist/esm/ShardingException.js +0 -91
  548. package/dist/esm/ShardingException.js.map +0 -1
  549. package/dist/esm/Storage.js +0 -32
  550. package/dist/esm/Storage.js.map +0 -1
  551. package/dist/esm/internal/atLeastOnce.js +0 -26
  552. package/dist/esm/internal/atLeastOnce.js.map +0 -1
  553. package/dist/esm/internal/atLeastOnceStorage.js +0 -154
  554. package/dist/esm/internal/atLeastOnceStorage.js.map +0 -1
  555. package/dist/esm/internal/entityState.js +0 -35
  556. package/dist/esm/internal/entityState.js.map +0 -1
  557. package/dist/esm/internal/managerConfig.js +0 -38
  558. package/dist/esm/internal/managerConfig.js.map +0 -1
  559. package/dist/esm/internal/message.js +0 -35
  560. package/dist/esm/internal/message.js.map +0 -1
  561. package/dist/esm/internal/messageState.js +0 -66
  562. package/dist/esm/internal/messageState.js.map +0 -1
  563. package/dist/esm/internal/podWithMetadata.js +0 -41
  564. package/dist/esm/internal/podWithMetadata.js.map +0 -1
  565. package/dist/esm/internal/pods.js +0 -25
  566. package/dist/esm/internal/pods.js.map +0 -1
  567. package/dist/esm/internal/podsHealth.js +0 -30
  568. package/dist/esm/internal/podsHealth.js.map +0 -1
  569. package/dist/esm/internal/recipientBehaviour.js +0 -42
  570. package/dist/esm/internal/recipientBehaviour.js.map +0 -1
  571. package/dist/esm/internal/recipientBehaviourContext.js +0 -26
  572. package/dist/esm/internal/recipientBehaviourContext.js.map +0 -1
  573. package/dist/esm/internal/serialization.js +0 -38
  574. package/dist/esm/internal/serialization.js.map +0 -1
  575. package/dist/esm/internal/shardManagerClient.js +0 -38
  576. package/dist/esm/internal/shardManagerClient.js.map +0 -1
  577. package/dist/esm/internal/shardManagerState.js +0 -36
  578. package/dist/esm/internal/shardManagerState.js.map +0 -1
  579. package/dist/esm/internal/sharding.js +0 -288
  580. package/dist/esm/internal/sharding.js.map +0 -1
  581. package/dist/esm/internal/shardingConfig.js +0 -47
  582. package/dist/esm/internal/shardingConfig.js.map +0 -1
  583. package/dist/esm/internal/storage.js +0 -42
  584. package/dist/esm/internal/storage.js.map +0 -1
  585. package/dist/esm/internal/utils.js +0 -56
  586. package/dist/esm/internal/utils.js.map +0 -1
  587. package/src/AtLeastOnce.ts +0 -28
  588. package/src/AtLeastOnceStorage.ts +0 -96
  589. package/src/Broadcaster.ts +0 -48
  590. package/src/ManagerConfig.ts +0 -67
  591. package/src/MessageState.ts +0 -126
  592. package/src/Messenger.ts +0 -40
  593. package/src/Pod.ts +0 -95
  594. package/src/PodAddress.ts +0 -94
  595. package/src/Pods.ts +0 -100
  596. package/src/PodsHealth.ts +0 -74
  597. package/src/PoisonPill.ts +0 -105
  598. package/src/RecipientAddress.ts +0 -72
  599. package/src/RecipientBehaviour.ts +0 -108
  600. package/src/RecipientBehaviourContext.ts +0 -101
  601. package/src/RecipientType.ts +0 -134
  602. package/src/Serialization.ts +0 -72
  603. package/src/SerializedEnvelope.ts +0 -108
  604. package/src/SerializedMessage.ts +0 -82
  605. package/src/ShardManagerClient.ts +0 -57
  606. package/src/ShardingEvent.ts +0 -121
  607. package/src/ShardingException.ts +0 -151
  608. package/src/Storage.ts +0 -92
  609. package/src/internal/atLeastOnce.ts +0 -59
  610. package/src/internal/atLeastOnceStorage.ts +0 -218
  611. package/src/internal/entityState.ts +0 -64
  612. package/src/internal/managerConfig.ts +0 -84
  613. package/src/internal/message.ts +0 -63
  614. package/src/internal/messageState.ts +0 -98
  615. package/src/internal/podWithMetadata.ts +0 -72
  616. package/src/internal/pods.ts +0 -29
  617. package/src/internal/podsHealth.ts +0 -39
  618. package/src/internal/recipientBehaviour.ts +0 -133
  619. package/src/internal/recipientBehaviourContext.ts +0 -70
  620. package/src/internal/serialization.ts +0 -63
  621. package/src/internal/shardManagerClient.ts +0 -49
  622. package/src/internal/shardManagerState.ts +0 -80
  623. package/src/internal/sharding.ts +0 -789
  624. package/src/internal/shardingConfig.ts +0 -97
  625. package/src/internal/storage.ts +0 -60
  626. package/src/internal/utils.ts +0 -54
@@ -0,0 +1,833 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as SqlClient from "@effect/sql/SqlClient"
5
+ import type { Row } from "@effect/sql/SqlConnection"
6
+ import type { SqlError } from "@effect/sql/SqlError"
7
+ import * as Arr from "effect/Array"
8
+ import type { DurationInput } from "effect/Duration"
9
+ import * as Effect from "effect/Effect"
10
+ import * as Layer from "effect/Layer"
11
+ import * as Option from "effect/Option"
12
+ import * as Schedule from "effect/Schedule"
13
+ import { PersistenceError } from "./ClusterError.js"
14
+ import type * as Envelope from "./Envelope.js"
15
+ import * as MessageStorage from "./MessageStorage.js"
16
+ import { SaveResultEncoded } from "./MessageStorage.js"
17
+ import type * as Reply from "./Reply.js"
18
+ import type { ShardingConfig } from "./ShardingConfig.js"
19
+ import * as Snowflake from "./Snowflake.js"
20
+
21
+ /**
22
+ * @since 1.0.0
23
+ * @category Constructors
24
+ */
25
+ export const make = Effect.fnUntraced(function*(options?: {
26
+ readonly prefix?: string | undefined
27
+ }) {
28
+ const sql = (yield* SqlClient.SqlClient).withoutTransforms()
29
+ const prefix = options?.prefix ?? "cluster"
30
+ const table = (name: string) => `${prefix}_${name}`
31
+
32
+ const messageKindAckChunk = sql.literal(String(messageKind.AckChunk))
33
+ const replyKindWithExit = sql.literal(String(replyKind.WithExit))
34
+
35
+ const messagesTable = table("messages")
36
+ const messagesTableSql = sql(messagesTable)
37
+
38
+ const repliesTable = table("replies")
39
+ const repliesTableSql = sql(repliesTable)
40
+
41
+ yield* sql.onDialectOrElse({
42
+ mssql: () =>
43
+ sql`
44
+ IF OBJECT_ID(N'${messagesTableSql}', N'U') IS NULL
45
+ CREATE TABLE ${messagesTableSql} (
46
+ id BIGINT PRIMARY KEY,
47
+ rowid BIGINT IDENTITY(1,1),
48
+ message_id VARCHAR(255),
49
+ shard_id INT NOT NULL,
50
+ entity_type VARCHAR(255) NOT NULL,
51
+ entity_id VARCHAR(255) NOT NULL,
52
+ kind INT NOT NULL,
53
+ tag VARCHAR(255),
54
+ payload TEXT,
55
+ headers TEXT,
56
+ trace_id VARCHAR(255),
57
+ span_id VARCHAR(255),
58
+ sampled BIT,
59
+ processed BIT NOT NULL DEFAULT 0,
60
+ request_id BIGINT NOT NULL,
61
+ reply_id BIGINT,
62
+ last_reply_id BIGINT,
63
+ last_read DATETIME,
64
+ deliver_at BIGINT,
65
+ UNIQUE (message_id),
66
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
67
+ )
68
+ `,
69
+ mysql: () =>
70
+ sql`
71
+ CREATE TABLE IF NOT EXISTS ${messagesTableSql} (
72
+ id BIGINT NOT NULL,
73
+ rowid BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
74
+ message_id VARCHAR(255),
75
+ shard_id INT NOT NULL,
76
+ entity_type VARCHAR(255) NOT NULL,
77
+ entity_id VARCHAR(255) NOT NULL,
78
+ kind INT NOT NULL,
79
+ tag VARCHAR(255),
80
+ payload TEXT,
81
+ headers TEXT,
82
+ trace_id VARCHAR(255),
83
+ span_id VARCHAR(255),
84
+ sampled BOOLEAN,
85
+ processed BOOLEAN NOT NULL DEFAULT FALSE,
86
+ request_id BIGINT NOT NULL,
87
+ reply_id BIGINT,
88
+ last_reply_id BIGINT,
89
+ last_read DATETIME,
90
+ deliver_at BIGINT,
91
+ UNIQUE (id),
92
+ UNIQUE (message_id),
93
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
94
+ )
95
+ `,
96
+ pg: () =>
97
+ sql`
98
+ CREATE TABLE IF NOT EXISTS ${messagesTableSql} (
99
+ id BIGINT PRIMARY KEY,
100
+ rowid BIGSERIAL,
101
+ message_id VARCHAR(255),
102
+ shard_id INT NOT NULL,
103
+ entity_type VARCHAR(255) NOT NULL,
104
+ entity_id VARCHAR(255) NOT NULL,
105
+ kind INT NOT NULL,
106
+ tag VARCHAR(255),
107
+ payload TEXT,
108
+ headers TEXT,
109
+ trace_id VARCHAR(255),
110
+ span_id VARCHAR(255),
111
+ sampled BOOLEAN,
112
+ processed BOOLEAN NOT NULL DEFAULT FALSE,
113
+ request_id BIGINT NOT NULL,
114
+ reply_id BIGINT,
115
+ last_reply_id BIGINT,
116
+ last_read TIMESTAMP,
117
+ deliver_at BIGINT,
118
+ UNIQUE (message_id),
119
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
120
+ )
121
+ `.pipe(Effect.ignore),
122
+ orElse: () =>
123
+ // sqlite
124
+ sql`
125
+ CREATE TABLE IF NOT EXISTS ${messagesTableSql} (
126
+ id INTEGER PRIMARY KEY,
127
+ message_id TEXT,
128
+ shard_id INTEGER NOT NULL,
129
+ entity_type TEXT NOT NULL,
130
+ entity_id TEXT NOT NULL,
131
+ kind INTEGER NOT NULL,
132
+ tag TEXT,
133
+ payload TEXT,
134
+ headers TEXT,
135
+ trace_id TEXT,
136
+ span_id TEXT,
137
+ sampled BOOLEAN,
138
+ processed BOOLEAN NOT NULL DEFAULT FALSE,
139
+ request_id INTEGER NOT NULL,
140
+ reply_id INTEGER,
141
+ last_reply_id INTEGER,
142
+ last_read TEXT,
143
+ deliver_at INTEGER,
144
+ UNIQUE (message_id),
145
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
146
+ )
147
+ `
148
+ })
149
+
150
+ // Add message indexes optimized for the specific query patterns
151
+ const shardLookupIndex = `${messagesTable}_shard_idx`
152
+ const requestIdLookupIndex = `${messagesTable}_request_id_idx`
153
+ yield* sql.onDialectOrElse({
154
+ mssql: () =>
155
+ sql`
156
+ IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = ${shardLookupIndex})
157
+ CREATE INDEX ${sql(shardLookupIndex)}
158
+ ON ${messagesTableSql} (shard_id, processed, last_read, deliver_at);
159
+
160
+ IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = ${requestIdLookupIndex})
161
+ CREATE INDEX ${sql(requestIdLookupIndex)}
162
+ ON ${messagesTableSql} (request_id);
163
+ `,
164
+ mysql: () =>
165
+ sql`
166
+ CREATE INDEX ${sql(shardLookupIndex)}
167
+ ON ${messagesTableSql} (shard_id, processed, last_read, deliver_at);
168
+
169
+ CREATE INDEX ${sql(requestIdLookupIndex)}
170
+ ON ${messagesTableSql} (request_id);
171
+ `.unprepared.pipe(Effect.ignore),
172
+ pg: () =>
173
+ sql`
174
+ CREATE INDEX IF NOT EXISTS ${sql(shardLookupIndex)}
175
+ ON ${messagesTableSql} (shard_id, processed, last_read, deliver_at);
176
+
177
+ CREATE INDEX IF NOT EXISTS ${sql(requestIdLookupIndex)}
178
+ ON ${messagesTableSql} (request_id);
179
+ `.pipe(
180
+ Effect.tapDefect((error) =>
181
+ Effect.annotateLogs(Effect.logDebug("Failed to create indexes", error), {
182
+ package: "@effect/cluster",
183
+ module: "SqlMessageStorage"
184
+ })
185
+ ),
186
+ Effect.retry({
187
+ schedule: Schedule.spaced(1000)
188
+ })
189
+ ),
190
+ orElse: () =>
191
+ // sqlite
192
+ Effect.all([
193
+ sql`
194
+ CREATE INDEX IF NOT EXISTS ${sql(shardLookupIndex)}
195
+ ON ${messagesTableSql} (shard_id, processed, last_read, deliver_at)
196
+ `,
197
+ sql`
198
+ CREATE INDEX IF NOT EXISTS ${sql(requestIdLookupIndex)}
199
+ ON ${messagesTableSql} (request_id)
200
+ `
201
+ ]).pipe(sql.withTransaction)
202
+ })
203
+
204
+ yield* sql.onDialectOrElse({
205
+ mssql: () =>
206
+ sql`
207
+ IF OBJECT_ID(N'${repliesTableSql}', N'U') IS NULL
208
+ CREATE TABLE ${repliesTableSql} (
209
+ id BIGINT PRIMARY KEY,
210
+ rowid BIGINT IDENTITY(1,1),
211
+ kind INT,
212
+ request_id BIGINT NOT NULL,
213
+ payload TEXT NOT NULL,
214
+ sequence INT,
215
+ acked BIT NOT NULL DEFAULT 0,
216
+ CONSTRAINT ${sql(repliesTable + "_one_exit")} UNIQUE (request_id, kind),
217
+ CONSTRAINT ${sql(repliesTable + "_sequence")} UNIQUE (request_id, sequence),
218
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
219
+ )
220
+ `,
221
+ mysql: () =>
222
+ sql`
223
+ CREATE TABLE IF NOT EXISTS ${repliesTableSql} (
224
+ id BIGINT NOT NULL,
225
+ rowid BIGINT AUTO_INCREMENT PRIMARY KEY,
226
+ kind INT,
227
+ request_id BIGINT NOT NULL,
228
+ payload TEXT NOT NULL,
229
+ sequence INT,
230
+ acked BOOLEAN NOT NULL DEFAULT FALSE,
231
+ UNIQUE (id),
232
+ UNIQUE (request_id, kind),
233
+ UNIQUE (request_id, sequence),
234
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
235
+ )
236
+ `,
237
+ pg: () =>
238
+ sql`
239
+ CREATE TABLE IF NOT EXISTS ${repliesTableSql} (
240
+ id BIGINT PRIMARY KEY,
241
+ rowid BIGSERIAL,
242
+ kind INT,
243
+ request_id BIGINT NOT NULL,
244
+ payload TEXT NOT NULL,
245
+ sequence INT,
246
+ acked BOOLEAN NOT NULL DEFAULT FALSE,
247
+ UNIQUE (request_id, kind),
248
+ UNIQUE (request_id, sequence),
249
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
250
+ )
251
+ `,
252
+ orElse: () =>
253
+ // sqlite
254
+ sql`
255
+ CREATE TABLE IF NOT EXISTS ${repliesTableSql} (
256
+ id INTEGER PRIMARY KEY,
257
+ kind INTEGER,
258
+ request_id INTEGER NOT NULL,
259
+ payload TEXT NOT NULL,
260
+ sequence INTEGER,
261
+ acked BOOLEAN NOT NULL DEFAULT FALSE,
262
+ UNIQUE (request_id, kind),
263
+ UNIQUE (request_id, sequence),
264
+ FOREIGN KEY (request_id) REFERENCES ${messagesTableSql} (id) ON DELETE CASCADE
265
+ )
266
+ `
267
+ })
268
+
269
+ // Add reply indexes optimized for request_id lookups
270
+ const replyLookupIndex = `${repliesTable}_request_lookup_idx`
271
+ yield* sql.onDialectOrElse({
272
+ mssql: () =>
273
+ sql`
274
+ IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = ${replyLookupIndex})
275
+ CREATE INDEX ${sql(replyLookupIndex)}
276
+ ON ${repliesTableSql} (request_id, kind, acked);
277
+ `,
278
+ mysql: () =>
279
+ sql`
280
+ CREATE INDEX ${sql(replyLookupIndex)}
281
+ ON ${repliesTableSql} (request_id, kind, acked);
282
+ `.unprepared.pipe(Effect.ignore),
283
+ pg: () =>
284
+ sql`
285
+ CREATE INDEX IF NOT EXISTS ${sql(replyLookupIndex)}
286
+ ON ${repliesTableSql} (request_id, kind, acked);
287
+ `.pipe(
288
+ Effect.tapDefect((error) =>
289
+ Effect.annotateLogs(Effect.logDebug("Failed to create indexes", error), {
290
+ package: "@effect/cluster",
291
+ module: "SqlMessageStorage"
292
+ })
293
+ ),
294
+ Effect.retry({
295
+ schedule: Schedule.spaced(1000)
296
+ })
297
+ ),
298
+ orElse: () =>
299
+ // sqlite
300
+ sql`
301
+ CREATE INDEX IF NOT EXISTS ${sql(replyLookupIndex)}
302
+ ON ${repliesTableSql} (request_id, kind, acked);
303
+ `
304
+ })
305
+
306
+ const envelopeToRow = (
307
+ envelope: Envelope.Envelope.Encoded,
308
+ message_id: string | null,
309
+ deliver_at: number | null
310
+ ): MessageRow => {
311
+ switch (envelope._tag) {
312
+ case "Request":
313
+ return {
314
+ id: envelope.requestId,
315
+ message_id,
316
+ shard_id: envelope.address.shardId,
317
+ entity_type: envelope.address.entityType,
318
+ entity_id: envelope.address.entityId,
319
+ kind: messageKind.Request,
320
+ tag: envelope.tag,
321
+ payload: JSON.stringify(envelope.payload),
322
+ headers: JSON.stringify(envelope.headers),
323
+ trace_id: envelope.traceId,
324
+ span_id: envelope.spanId,
325
+ sampled: supportsBooleans ? envelope.sampled : envelope.sampled ? 1 : 0,
326
+ request_id: envelope.requestId,
327
+ reply_id: null,
328
+ deliver_at
329
+ }
330
+ case "AckChunk":
331
+ return {
332
+ id: envelope.id,
333
+ message_id,
334
+ shard_id: envelope.address.shardId,
335
+ entity_type: envelope.address.entityType,
336
+ entity_id: envelope.address.entityId,
337
+ kind: messageKind.AckChunk,
338
+ tag: null,
339
+ payload: null,
340
+ headers: null,
341
+ trace_id: null,
342
+ span_id: null,
343
+ sampled: null,
344
+ request_id: envelope.requestId,
345
+ reply_id: envelope.replyId,
346
+ deliver_at
347
+ }
348
+ case "Interrupt":
349
+ return {
350
+ id: envelope.id,
351
+ message_id,
352
+ shard_id: envelope.address.shardId,
353
+ entity_type: envelope.address.entityType,
354
+ entity_id: envelope.address.entityId,
355
+ kind: messageKind.Interrupt,
356
+ payload: null,
357
+ tag: null,
358
+ headers: null,
359
+ trace_id: null,
360
+ span_id: null,
361
+ sampled: null,
362
+ request_id: envelope.requestId,
363
+ reply_id: null,
364
+ deliver_at
365
+ }
366
+ }
367
+ }
368
+
369
+ const replyToRow = (reply: Reply.ReplyEncoded<any>): ReplyRow => ({
370
+ id: reply.id,
371
+ kind: replyKind[reply._tag],
372
+ request_id: reply.requestId,
373
+ payload: reply._tag === "WithExit" ? JSON.stringify(reply.exit) : JSON.stringify(reply.values),
374
+ sequence: reply._tag === "Chunk" ? reply.sequence : null
375
+ })
376
+
377
+ const supportsBooleans = sql.onDialectOrElse({
378
+ mssql: () => false,
379
+ sqlite: () => false,
380
+ orElse: () => true
381
+ })
382
+
383
+ const messageFromRow = (row: MessageRow & ReplyJoinRow): {
384
+ readonly envelope: Envelope.Envelope.Encoded
385
+ readonly lastSentReply: Option.Option<Reply.ReplyEncoded<any>>
386
+ } => {
387
+ switch (Number(row.kind) as 0 | 1 | 2) {
388
+ case 0:
389
+ return {
390
+ envelope: {
391
+ _tag: "Request",
392
+ requestId: String(row.id),
393
+ address: {
394
+ shardId: Number(row.shard_id),
395
+ entityType: row.entity_type,
396
+ entityId: row.entity_id
397
+ },
398
+ tag: row.tag!,
399
+ payload: JSON.parse(row.payload!),
400
+ headers: JSON.parse(row.headers!),
401
+ traceId: row.trace_id!,
402
+ spanId: row.span_id!,
403
+ sampled: !!row.sampled
404
+ },
405
+ lastSentReply: row.reply_reply_id ?
406
+ Option.some({
407
+ _tag: "Chunk",
408
+ id: String(row.reply_reply_id),
409
+ requestId: String(row.request_id),
410
+ sequence: Number(row.reply_sequence!),
411
+ values: JSON.parse(row.reply_payload!)
412
+ } as any) :
413
+ Option.none()
414
+ }
415
+ case 1:
416
+ return {
417
+ envelope: {
418
+ _tag: "AckChunk",
419
+ id: String(row.id),
420
+ requestId: String(row.request_id!),
421
+ replyId: String(row.reply_id!),
422
+ address: {
423
+ shardId: Number(row.shard_id),
424
+ entityType: row.entity_type,
425
+ entityId: row.entity_id
426
+ }
427
+ },
428
+ lastSentReply: Option.none()
429
+ }
430
+ case 2:
431
+ return {
432
+ envelope: {
433
+ _tag: "Interrupt",
434
+ id: String(row.id),
435
+ requestId: String(row.request_id!),
436
+ address: {
437
+ shardId: Number(row.shard_id),
438
+ entityType: row.entity_type,
439
+ entityId: row.entity_id
440
+ }
441
+ },
442
+ lastSentReply: Option.none()
443
+ }
444
+ }
445
+ }
446
+
447
+ const sqlFalse = sql.literal(supportsBooleans ? "FALSE" : "0")
448
+ const sqlTrue = sql.literal(supportsBooleans ? "TRUE" : "1")
449
+
450
+ const insertEnvelope: (
451
+ row: MessageRow,
452
+ message_id: string
453
+ ) => Effect.Effect<ReadonlyArray<Row>, SqlError> = sql.onDialectOrElse({
454
+ pg: () => (row, message_id) =>
455
+ sql`
456
+ WITH inserted AS (
457
+ INSERT INTO ${messagesTableSql} ${sql.insert(row)}
458
+ ON CONFLICT (message_id) DO NOTHING
459
+ RETURNING id
460
+ ),
461
+ existing AS (
462
+ SELECT m.id, r.id as reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
463
+ FROM ${messagesTableSql} m
464
+ LEFT JOIN ${repliesTableSql} r ON r.id = m.last_reply_id
465
+ WHERE m.message_id = ${message_id}
466
+ AND NOT EXISTS (SELECT 1 FROM inserted)
467
+ )
468
+ SELECT * FROM existing
469
+ `,
470
+ mysql: () => (row, message_id) =>
471
+ sql`
472
+ SELECT m.id, r.id as reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
473
+ FROM ${messagesTableSql} m
474
+ LEFT JOIN ${repliesTableSql} r ON r.id = m.last_reply_id
475
+ WHERE m.message_id = ${message_id};
476
+ INSERT INTO ${messagesTableSql} ${sql.insert(row)}
477
+ ON DUPLICATE KEY UPDATE id = id;
478
+ `.unprepared.pipe(
479
+ // we need 2 queries for mysql, so we need to run them in a
480
+ // transaction with retries
481
+ sql.withTransaction,
482
+ Effect.retry({ times: 3 }),
483
+ Effect.map(([rows]) => rows as any as ReadonlyArray<Row>)
484
+ ),
485
+ mssql: () => (row, message_id) =>
486
+ sql`
487
+ MERGE ${messagesTableSql} WITH (HOLDLOCK) AS target
488
+ USING (SELECT ${message_id} as message_id) AS source
489
+ ON target.message_id = source.message_id
490
+ WHEN NOT MATCHED THEN
491
+ INSERT ${sql.insert(row)}
492
+ OUTPUT
493
+ inserted.id,
494
+ CASE
495
+ WHEN inserted.id IS NULL THEN (
496
+ SELECT r.id, r.kind, r.payload
497
+ FROM ${repliesTableSql} r
498
+ WHERE r.id = target.last_reply_id
499
+ )
500
+ END as reply_id,
501
+ CASE
502
+ WHEN inserted.id IS NULL THEN (
503
+ SELECT r.kind
504
+ FROM ${repliesTableSql} r
505
+ WHERE r.id = target.last_reply_id
506
+ )
507
+ END as reply_kind,
508
+ CASE
509
+ WHEN inserted.id IS NULL THEN (
510
+ SELECT r.payload
511
+ FROM ${repliesTableSql} r
512
+ WHERE r.id = target.last_reply_id
513
+ )
514
+ END as reply_payload,
515
+ CASE
516
+ WHEN inserted.id IS NULL THEN (
517
+ SELECT r.sequence
518
+ FROM ${repliesTableSql} r
519
+ WHERE r.id = target.last_reply_id
520
+ )
521
+ END as reply_sequence;
522
+ `,
523
+ orElse: () => (row, message_id) =>
524
+ sql`
525
+ SELECT m.id, r.id as reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
526
+ FROM ${messagesTableSql} m
527
+ LEFT JOIN ${repliesTableSql} r ON r.id = m.last_reply_id
528
+ WHERE m.message_id = ${message_id}
529
+ `.pipe(
530
+ Effect.tap(sql`INSERT OR IGNORE INTO ${messagesTableSql} ${sql.insert(row)}`),
531
+ sql.withTransaction,
532
+ Effect.retry({ times: 3 })
533
+ )
534
+ })
535
+
536
+ const fiveMinutesAgo = sql.onDialectOrElse({
537
+ mssql: () => sql.literal(`DATEADD(MINUTE, -5, GETDATE())`),
538
+ mysql: () => sql.literal(`NOW() - INTERVAL 5 MINUTE`),
539
+ pg: () => sql.literal(`NOW() - INTERVAL '5 minutes'`),
540
+ orElse: () => sql.literal(`DATETIME('now', '-5 minute')`)
541
+ })
542
+ const sqlNowString = sql.onDialectOrElse({
543
+ pg: () => "NOW()",
544
+ mysql: () => "NOW()",
545
+ mssql: () => "GETDATE()",
546
+ orElse: () => "CURRENT_TIMESTAMP"
547
+ })
548
+ const sqlNow = sql.literal(sqlNowString)
549
+
550
+ const getUnprocessedMessages = sql.onDialectOrElse({
551
+ pg: () => (shardIds: ReadonlyArray<number>, now: number) =>
552
+ sql<MessageJoinRow>`
553
+ UPDATE ${messagesTableSql} m
554
+ SET last_read = ${sqlNow}
555
+ FROM (
556
+ SELECT m.*
557
+ FROM ${messagesTableSql} m
558
+ WHERE m.shard_id IN (${sql.literal(shardIds.map(String).join(","))})
559
+ AND NOT EXISTS (
560
+ SELECT 1 FROM ${repliesTableSql}
561
+ WHERE request_id = m.request_id
562
+ AND (kind = ${replyKindWithExit} OR acked = ${sqlFalse})
563
+ )
564
+ AND m.processed = ${sqlFalse}
565
+ AND (m.last_read IS NULL OR m.last_read < ${fiveMinutesAgo})
566
+ AND (m.deliver_at IS NULL OR m.deliver_at <= ${sql.literal(String(now))})
567
+ ORDER BY m.rowid ASC
568
+ FOR UPDATE
569
+ ) AS ids
570
+ LEFT JOIN ${repliesTableSql} r ON r.id = ids.last_reply_id
571
+ WHERE m.id = ids.id
572
+ RETURNING ids.*, r.id as reply_reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
573
+ `,
574
+ orElse: () => (shardIds: ReadonlyArray<number>, now: number) =>
575
+ sql<MessageJoinRow>`
576
+ SELECT m.*, r.id as reply_reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
577
+ FROM ${messagesTableSql} m
578
+ LEFT JOIN ${repliesTableSql} r ON r.id = m.last_reply_id
579
+ WHERE m.shard_id IN (${sql.literal(shardIds.map(String).join(","))})
580
+ AND NOT EXISTS (
581
+ SELECT 1 FROM ${repliesTableSql}
582
+ WHERE request_id = m.request_id
583
+ AND (kind = ${replyKindWithExit} OR acked = ${sqlFalse})
584
+ )
585
+ AND processed = ${sqlFalse}
586
+ AND (m.last_read IS NULL OR m.last_read < ${fiveMinutesAgo})
587
+ AND (m.deliver_at IS NULL OR m.deliver_at <= ${sql.literal(String(now))})
588
+ ORDER BY m.rowid ASC
589
+ `.unprepared.pipe(
590
+ Effect.tap((rows) => {
591
+ if (rows.length === 0) {
592
+ return Effect.void
593
+ }
594
+ return sql`
595
+ UPDATE ${messagesTableSql}
596
+ SET last_read = ${sqlNow}
597
+ WHERE id IN (${sql.literal(rows.map((row) => row.id).join(","))})
598
+ `.unprepared
599
+ }),
600
+ sql.withTransaction
601
+ )
602
+ })
603
+
604
+ return yield* MessageStorage.makeEncoded({
605
+ saveEnvelope: ({ deliverAt, envelope, primaryKey }) =>
606
+ Effect.suspend(() => {
607
+ const row = envelopeToRow(envelope, primaryKey, deliverAt)
608
+ let insert = primaryKey
609
+ ? insertEnvelope(row, primaryKey)
610
+ : Effect.as(sql`INSERT INTO ${messagesTableSql} ${sql.insert(row)}`.unprepared, [])
611
+ if (envelope._tag === "AckChunk") {
612
+ insert = sql`UPDATE ${repliesTableSql} SET acked = ${sqlTrue} WHERE id = ${envelope.replyId}`.pipe(
613
+ Effect.andThen(
614
+ sql`UPDATE ${messagesTableSql} SET processed = ${sqlTrue} WHERE processed = ${sqlFalse} AND request_id = ${envelope.requestId} AND kind = ${messageKindAckChunk}`
615
+ ),
616
+ Effect.andThen(insert),
617
+ sql.withTransaction
618
+ )
619
+ }
620
+ return insert.pipe(
621
+ Effect.map((rows) => {
622
+ if (rows.length === 0) {
623
+ return SaveResultEncoded.Success()
624
+ }
625
+ const row = rows[0]
626
+ return SaveResultEncoded.Duplicate({
627
+ originalId: Snowflake.Snowflake(row.id as any),
628
+ lastReceivedReply: row.reply_id ?
629
+ Option.some({
630
+ id: String(row.reply_id),
631
+ requestId: String(row.id),
632
+ _tag: row.reply_kind === replyKind.WithExit ? "WithExit" : "Chunk",
633
+ ...(row.reply_kind === replyKind.WithExit
634
+ ? { exit: JSON.parse(row.reply_payload as string) }
635
+ : {
636
+ sequence: Number(row.reply_sequence),
637
+ values: JSON.parse(row.reply_payload as string)
638
+ })
639
+ } as any) :
640
+ Option.none()
641
+ })
642
+ })
643
+ )
644
+ }).pipe(
645
+ Effect.provideService(SqlClient.SafeIntegers, true),
646
+ PersistenceError.refail
647
+ ),
648
+
649
+ saveReply: (reply) =>
650
+ Effect.suspend(() => {
651
+ const row = replyToRow(reply)
652
+ const update = reply._tag === "Chunk" ?
653
+ sql`UPDATE ${messagesTableSql} SET last_reply_id = ${reply.id} WHERE id = ${reply.requestId}` :
654
+ sql`UPDATE ${messagesTableSql} SET processed = ${sqlTrue}, last_reply_id = NULL WHERE request_id = ${reply.requestId}`
655
+ return update.unprepared.pipe(
656
+ Effect.andThen(sql`INSERT INTO ${repliesTableSql} ${sql.insert(row)}`),
657
+ sql.withTransaction
658
+ )
659
+ }).pipe(
660
+ Effect.asVoid,
661
+ PersistenceError.refail
662
+ ),
663
+
664
+ repliesFor: (requestIds) =>
665
+ // replies where:
666
+ // - the request is in the list
667
+ // - the kind is WithExit
668
+ // - or the kind is Chunk and has not been acked yet
669
+ sql<ReplyRow>`
670
+ SELECT id, kind, request_id, payload, sequence
671
+ FROM ${repliesTableSql}
672
+ WHERE request_id IN (${sql.literal(requestIds.join(","))})
673
+ AND (
674
+ kind = ${replyKindWithExit}
675
+ OR (
676
+ kind IS NULL
677
+ AND acked = ${sqlFalse}
678
+ )
679
+ )
680
+ ORDER BY rowid ASC
681
+ `.unprepared.pipe(
682
+ Effect.provideService(SqlClient.SafeIntegers, true),
683
+ Effect.map(Arr.map((row): Reply.ReplyEncoded<any> =>
684
+ row.kind === replyKind.WithExit ?
685
+ ({
686
+ _tag: "WithExit",
687
+ id: String(row.id),
688
+ requestId: String(row.request_id),
689
+ exit: JSON.parse(row.payload)
690
+ }) :
691
+ {
692
+ _tag: "Chunk",
693
+ id: String(row.id),
694
+ requestId: String(row.request_id),
695
+ values: JSON.parse(row.payload),
696
+ sequence: Number(row.sequence!)
697
+ }
698
+ )),
699
+ PersistenceError.refail
700
+ ),
701
+
702
+ unprocessedMessages: Effect.fnUntraced(
703
+ function*(shardIds, now) {
704
+ const rows = yield* getUnprocessedMessages(shardIds, now)
705
+ if (rows.length === 0) {
706
+ return []
707
+ }
708
+ const messages: Array<{
709
+ readonly envelope: Envelope.Envelope.Encoded
710
+ readonly lastSentReply: Option.Option<Reply.ReplyEncoded<any>>
711
+ }> = new Array(rows.length)
712
+ const ids = new Array<string>(rows.length)
713
+ for (let i = 0; i < rows.length; i++) {
714
+ messages[i] = messageFromRow(rows[i])
715
+ ids[i] = String(rows[i].id)
716
+ }
717
+ return messages
718
+ },
719
+ Effect.provideService(SqlClient.SafeIntegers, true),
720
+ PersistenceError.refail
721
+ ),
722
+
723
+ unprocessedMessagesById(ids, now) {
724
+ const idArr = Array.from(ids, (id) => String(id))
725
+ return sql<MessageRow & ReplyJoinRow>`
726
+ SELECT m.*, r.id as reply_id, r.kind as reply_kind, r.payload as reply_payload, r.sequence as reply_sequence
727
+ FROM ${messagesTableSql} m
728
+ LEFT JOIN ${repliesTableSql} r ON r.id = m.last_reply_id
729
+ WHERE m.id IN (${sql.literal(idArr.join(","))})
730
+ AND NOT EXISTS (
731
+ SELECT 1 FROM ${repliesTableSql}
732
+ WHERE request_id = m.request_id
733
+ AND (kind = ${replyKindWithExit} OR acked = ${sqlFalse})
734
+ )
735
+ AND m.processed = ${sqlFalse}
736
+ AND (m.deliver_at IS NULL OR m.deliver_at <= ${sql.literal(String(now))})
737
+ ORDER BY m.rowid ASC
738
+ `.unprepared.pipe(
739
+ Effect.map(Arr.map(messageFromRow)),
740
+ Effect.provideService(SqlClient.SafeIntegers, true),
741
+ PersistenceError.refail
742
+ )
743
+ },
744
+
745
+ resetAddress: (address) =>
746
+ sql`
747
+ UPDATE ${messagesTableSql}
748
+ SET last_read = NULL
749
+ WHERE processed = ${sqlFalse}
750
+ AND shard_id = ${address.shardId}
751
+ AND entity_type = ${address.entityType}
752
+ AND entity_id = ${address.entityId}
753
+ `.pipe(
754
+ Effect.asVoid,
755
+ PersistenceError.refail
756
+ )
757
+ })
758
+ })
759
+
760
+ /**
761
+ * @since 1.0.0
762
+ * @category Layers
763
+ */
764
+ export const layer: Layer.Layer<
765
+ MessageStorage.MessageStorage,
766
+ SqlError,
767
+ SqlClient.SqlClient | ShardingConfig
768
+ > = Layer.scoped(MessageStorage.MessageStorage, make()).pipe(
769
+ Layer.provide(Snowflake.layerGenerator)
770
+ )
771
+
772
+ /**
773
+ * @since 1.0.0
774
+ * @category Layers
775
+ */
776
+ export const layerWith = (options: {
777
+ readonly prefix?: string | undefined
778
+ readonly replyPollInterval?: DurationInput | undefined
779
+ }): Layer.Layer<MessageStorage.MessageStorage, SqlError, SqlClient.SqlClient | ShardingConfig> =>
780
+ Layer.scoped(MessageStorage.MessageStorage, make(options)).pipe(
781
+ Layer.provide(Snowflake.layerGenerator)
782
+ )
783
+
784
+ // -------------------------------------------------------------------------------------------------
785
+ // internal
786
+ // -------------------------------------------------------------------------------------------------
787
+
788
+ const messageKind = {
789
+ "Request": 0,
790
+ "AckChunk": 1,
791
+ "Interrupt": 2
792
+ } as const satisfies Record<Envelope.Envelope.Any["_tag"], number>
793
+
794
+ const replyKind = {
795
+ "WithExit": 0,
796
+ "Chunk": null
797
+ } as const satisfies Record<Reply.Reply<any>["_tag"], number | null>
798
+
799
+ type MessageRow = {
800
+ readonly id: string | bigint
801
+ readonly message_id: string | null
802
+ readonly shard_id: number | bigint
803
+ readonly entity_type: string
804
+ readonly entity_id: string
805
+ readonly kind: 0 | 1 | 2 | 0n | 1n | 2n
806
+ readonly tag: string | null
807
+ readonly payload: string | null
808
+ readonly headers: string | null
809
+ readonly trace_id: string | null
810
+ readonly span_id: string | null
811
+ readonly sampled: boolean | number | bigint | null
812
+ readonly request_id: string | bigint | null
813
+ readonly reply_id: string | bigint | null
814
+ readonly deliver_at: number | bigint | null
815
+ }
816
+
817
+ type ReplyRow = {
818
+ readonly id: string | bigint
819
+ readonly kind: 0 | null | 0n
820
+ readonly request_id: string | bigint
821
+ readonly payload: string
822
+ readonly sequence: number | bigint | null
823
+ }
824
+
825
+ type ReplyJoinRow = {
826
+ readonly reply_reply_id: string | bigint | null
827
+ readonly reply_payload: string | null
828
+ readonly reply_sequence: number | bigint | null
829
+ }
830
+
831
+ type MessageJoinRow = MessageRow & ReplyJoinRow & {
832
+ readonly sequence: number | bigint
833
+ }