@reventlessdev/reventless-local 3.0.0-alpha.113

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 (334) hide show
  1. package/CHANGELOG.md +1197 -0
  2. package/LICENSE +202 -0
  3. package/__mocks__/emptyModule.js +2 -0
  4. package/__mocks__/nodeSqlite.mjs +6 -0
  5. package/package.json +67 -0
  6. package/rescript.json +39 -0
  7. package/src/Platform.res +2162 -0
  8. package/src/Platform.res.mjs +3389 -0
  9. package/src/adapter/Api/LocalGraphQL_Adapter.res +29 -0
  10. package/src/adapter/Api/LocalGraphQL_Adapter.res.mjs +26 -0
  11. package/src/adapter/Api/LocalGraphQL_SubscriptionResolvers.res +146 -0
  12. package/src/adapter/Api/LocalGraphQL_SubscriptionResolvers.res.mjs +88 -0
  13. package/src/adapter/Auth/Auth_GraphqlContext.res +83 -0
  14. package/src/adapter/Auth/Auth_GraphqlContext.res.mjs +76 -0
  15. package/src/adapter/Auth/LocalAuth.res +239 -0
  16. package/src/adapter/Auth/LocalAuth.res.mjs +247 -0
  17. package/src/adapter/Auth/UserStore.res +134 -0
  18. package/src/adapter/Auth/UserStore.res.mjs +146 -0
  19. package/src/adapter/Backend.res +46 -0
  20. package/src/adapter/Backend.res.mjs +66 -0
  21. package/src/adapter/BackendState.res +34 -0
  22. package/src/adapter/BackendState.res.mjs +42 -0
  23. package/src/adapter/Cloner/LocalClonerRunner.res +13 -0
  24. package/src/adapter/Cloner/LocalClonerRunner.res.mjs +12 -0
  25. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +329 -0
  26. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res.mjs +301 -0
  27. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +76 -0
  28. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res.mjs +57 -0
  29. package/src/adapter/CommandGenerator/LocalCommandGeneratorResolvers.res +19 -0
  30. package/src/adapter/CommandGenerator/LocalCommandGeneratorResolvers.res.mjs +19 -0
  31. package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +104 -0
  32. package/src/adapter/CommandTopic/LocalCommandTopicChannel.res.mjs +82 -0
  33. package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +32 -0
  34. package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res.mjs +38 -0
  35. package/src/adapter/Counter/LocalCounterHandler.res +42 -0
  36. package/src/adapter/Counter/LocalCounterHandler.res.mjs +45 -0
  37. package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +131 -0
  38. package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res.mjs +140 -0
  39. package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +334 -0
  40. package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res.mjs +299 -0
  41. package/src/adapter/DomainGraphQL_Server.res +565 -0
  42. package/src/adapter/DomainGraphQL_Server.res.mjs +576 -0
  43. package/src/adapter/DomainMCP_Server.res +369 -0
  44. package/src/adapter/DomainMCP_Server.res.mjs +358 -0
  45. package/src/adapter/EventCollector/LocalEventCollectorChannel.res +87 -0
  46. package/src/adapter/EventCollector/LocalEventCollectorChannel.res.mjs +45 -0
  47. package/src/adapter/EventLog/EventLogStorage_InMemory.res +105 -0
  48. package/src/adapter/EventLog/EventLogStorage_InMemory.res.mjs +117 -0
  49. package/src/adapter/EventLog/EventLogStorage_Sqlite.res +145 -0
  50. package/src/adapter/EventLog/EventLogStorage_Sqlite.res.mjs +155 -0
  51. package/src/adapter/EventTopic/LocalEventTopicPublisher.res +36 -0
  52. package/src/adapter/EventTopic/LocalEventTopicPublisher.res.mjs +31 -0
  53. package/src/adapter/GraphQL_Server.res +6 -0
  54. package/src/adapter/GraphQL_Server.res.mjs +154 -0
  55. package/src/adapter/GraphQL_ServerInstance.res +310 -0
  56. package/src/adapter/GraphQL_ServerInstance.res.mjs +257 -0
  57. package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +57 -0
  58. package/src/adapter/Heartbeat/LocalHeartbeatRunner.res.mjs +34 -0
  59. package/src/adapter/LocalBus.res +498 -0
  60. package/src/adapter/LocalBus.res.mjs +1011 -0
  61. package/src/adapter/LocalPluginSpec.res +16 -0
  62. package/src/adapter/LocalPluginSpec.res.mjs +33 -0
  63. package/src/adapter/LocalSideEffectHandler.res +44 -0
  64. package/src/adapter/LocalSideEffectHandler.res.mjs +34 -0
  65. package/src/adapter/MCP_Server.res +4 -0
  66. package/src/adapter/MCP_Server.res.mjs +67 -0
  67. package/src/adapter/MCP_ServerInstance.res +362 -0
  68. package/src/adapter/MCP_ServerInstance.res.mjs +313 -0
  69. package/src/adapter/PlatformGraphQL_Server.res +75 -0
  70. package/src/adapter/PlatformGraphQL_Server.res.mjs +84 -0
  71. package/src/adapter/PlatformMCP_Server.res +23 -0
  72. package/src/adapter/PlatformMCP_Server.res.mjs +46 -0
  73. package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +793 -0
  74. package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res.mjs +569 -0
  75. package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +242 -0
  76. package/src/adapter/QueryDb/QueryDbStorage_InMemory.res.mjs +241 -0
  77. package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +339 -0
  78. package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res.mjs +318 -0
  79. package/src/adapter/QueryDb/SortKey_Filter.res +48 -0
  80. package/src/adapter/QueryDb/SortKey_Filter.res.mjs +46 -0
  81. package/src/adapter/QueryEngine/LocalQueryEngine.res +57 -0
  82. package/src/adapter/QueryEngine/LocalQueryEngine.res.mjs +56 -0
  83. package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +91 -0
  84. package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res.mjs +50 -0
  85. package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +47 -0
  86. package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res.mjs +37 -0
  87. package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +11 -0
  88. package/src/adapter/Runtime/LocalPluginRuntime_Builder.res.mjs +30 -0
  89. package/src/adapter/Runtime/LocalRuntimeEnvironment.res +54 -0
  90. package/src/adapter/Runtime/LocalRuntimeEnvironment.res.mjs +40 -0
  91. package/src/adapter/Scheduler/LocalScheduledPublisher.res +102 -0
  92. package/src/adapter/Scheduler/LocalScheduledPublisher.res.mjs +84 -0
  93. package/src/adapter/SqliteDriver.res +52 -0
  94. package/src/adapter/SqliteDriver.res.mjs +76 -0
  95. package/src/adapter/SqliteDriver.resi +31 -0
  96. package/src/adapter/Task/LocalTaskBucket.res +75 -0
  97. package/src/adapter/Task/LocalTaskBucket.res.mjs +48 -0
  98. package/src/adapter/Task/TaskBucket_Sqlite.res +47 -0
  99. package/src/adapter/Task/TaskBucket_Sqlite.res.mjs +40 -0
  100. package/src/components/Aggregate_Builder.res +55 -0
  101. package/src/components/Aggregate_Builder.res.mjs +140 -0
  102. package/src/components/AutomationSlice_Builder.res +41 -0
  103. package/src/components/AutomationSlice_Builder.res.mjs +57 -0
  104. package/src/components/Counter_Builder.res +14 -0
  105. package/src/components/Counter_Builder.res.mjs +32 -0
  106. package/src/components/DcbEventLog_Builder.res +18 -0
  107. package/src/components/DcbEventLog_Builder.res.mjs +24 -0
  108. package/src/components/ExtensionPoint_Builder.res +25 -0
  109. package/src/components/ExtensionPoint_Builder.res.mjs +44 -0
  110. package/src/components/InboundTranslationSlice_Builder.res +34 -0
  111. package/src/components/InboundTranslationSlice_Builder.res.mjs +45 -0
  112. package/src/components/OutboundTranslationSlice_Builder.res +43 -0
  113. package/src/components/OutboundTranslationSlice_Builder.res.mjs +59 -0
  114. package/src/components/Plugin_Builder.res +37 -0
  115. package/src/components/Plugin_Builder.res.mjs +67 -0
  116. package/src/components/ReadModel_Builder.res +47 -0
  117. package/src/components/ReadModel_Builder.res.mjs +54 -0
  118. package/src/components/StateChangeSlice_Builder.res +19 -0
  119. package/src/components/StateChangeSlice_Builder.res.mjs +21 -0
  120. package/src/components/StateViewSlice_Builder.res +42 -0
  121. package/src/components/StateViewSlice_Builder.res.mjs +58 -0
  122. package/src/components/Task_Builder.res +28 -0
  123. package/src/components/Task_Builder.res.mjs +41 -0
  124. package/src/reexport/CommandTopic.res +3 -0
  125. package/src/reexport/CommandTopic.res.mjs +55 -0
  126. package/src/test/Mocks/MockDcbEventLogStorage.res +136 -0
  127. package/src/test/Mocks/MockDcbEventLogStorage.res.mjs +146 -0
  128. package/src/test/Mocks/MockEventLogStorage.res +57 -0
  129. package/src/test/Mocks/MockEventLogStorage.res.mjs +65 -0
  130. package/src/test/Mocks/MockPublisher.res +29 -0
  131. package/src/test/Mocks/MockPublisher.res.mjs +28 -0
  132. package/src/test/Mocks/MockQueryDbStorage.res +104 -0
  133. package/src/test/Mocks/MockQueryDbStorage.res.mjs +136 -0
  134. package/src/test/TestRunner.res +96 -0
  135. package/src/test/TestRunner.res.mjs +71 -0
  136. package/tests/SplitApiFixtures.res +84 -0
  137. package/tests/SplitApiFixtures.res.mjs +88 -0
  138. package/tests/SplitApiTest.res +102 -0
  139. package/tests/SplitApiTest.res.mjs +82 -0
  140. package/tests/TestFixtures.res +54 -0
  141. package/tests/TestFixtures.res.mjs +65 -0
  142. package/tests/adapter/BackendParityTest.res +94 -0
  143. package/tests/adapter/BackendParityTest.res.mjs +96 -0
  144. package/tests/adapter/CollectNEventsTest.res +82 -0
  145. package/tests/adapter/CollectNEventsTest.res.mjs +83 -0
  146. package/tests/adapter/CommandAuthorizationTest.res +200 -0
  147. package/tests/adapter/CommandAuthorizationTest.res.mjs +190 -0
  148. package/tests/adapter/CommandTopicChannelTest.res +174 -0
  149. package/tests/adapter/CommandTopicChannelTest.res.mjs +170 -0
  150. package/tests/adapter/CounterHandlerTest.res +113 -0
  151. package/tests/adapter/CounterHandlerTest.res.mjs +96 -0
  152. package/tests/adapter/DcbEventLogStorageSqliteTest.res +157 -0
  153. package/tests/adapter/DcbEventLogStorageSqliteTest.res.mjs +165 -0
  154. package/tests/adapter/DcbEventLogStorageTest.res +187 -0
  155. package/tests/adapter/DcbEventLogStorageTest.res.mjs +195 -0
  156. package/tests/adapter/EventCollectorChannelTest.res +166 -0
  157. package/tests/adapter/EventCollectorChannelTest.res.mjs +178 -0
  158. package/tests/adapter/EventLogStorageSqliteTest.res +105 -0
  159. package/tests/adapter/EventLogStorageSqliteTest.res.mjs +116 -0
  160. package/tests/adapter/EventTapTest.res +102 -0
  161. package/tests/adapter/EventTapTest.res.mjs +94 -0
  162. package/tests/adapter/EventTopicPublisherTest.res +76 -0
  163. package/tests/adapter/EventTopicPublisherTest.res.mjs +86 -0
  164. package/tests/adapter/GraphQL_SchemaInspectorTest.res +763 -0
  165. package/tests/adapter/GraphQL_SchemaInspectorTest.res.mjs +578 -0
  166. package/tests/adapter/GraphQL_SubscriptionResolversTest.res +161 -0
  167. package/tests/adapter/GraphQL_SubscriptionResolversTest.res.mjs +134 -0
  168. package/tests/adapter/HeartbeatRunnerTest.res +136 -0
  169. package/tests/adapter/HeartbeatRunnerTest.res.mjs +96 -0
  170. package/tests/adapter/LocalAuthHttpTest.res +224 -0
  171. package/tests/adapter/LocalAuthHttpTest.res.mjs +237 -0
  172. package/tests/adapter/LocalAuthLoginTest.res +180 -0
  173. package/tests/adapter/LocalAuthLoginTest.res.mjs +207 -0
  174. package/tests/adapter/LocalAuthTest.res +106 -0
  175. package/tests/adapter/LocalAuthTest.res.mjs +145 -0
  176. package/tests/adapter/LocalAuthUserStoreTest.res +172 -0
  177. package/tests/adapter/LocalAuthUserStoreTest.res.mjs +208 -0
  178. package/tests/adapter/LocalBusBoundedTest.res +157 -0
  179. package/tests/adapter/LocalBusBoundedTest.res.mjs +168 -0
  180. package/tests/adapter/LocalBusPubSubTest.res +81 -0
  181. package/tests/adapter/LocalBusPubSubTest.res.mjs +81 -0
  182. package/tests/adapter/QueryDbGsiTtlTest.res +268 -0
  183. package/tests/adapter/QueryDbGsiTtlTest.res.mjs +209 -0
  184. package/tests/adapter/QueryDbListResolverTest.res +361 -0
  185. package/tests/adapter/QueryDbListResolverTest.res.mjs +426 -0
  186. package/tests/adapter/QueryDbStorageSqliteTest.res +159 -0
  187. package/tests/adapter/QueryDbStorageSqliteTest.res.mjs +126 -0
  188. package/tests/adapter/QueryDbStorageTest.res +171 -0
  189. package/tests/adapter/QueryDbStorageTest.res.mjs +170 -0
  190. package/tests/adapter/QueryEngineTest.res +152 -0
  191. package/tests/adapter/QueryEngineTest.res.mjs +148 -0
  192. package/tests/adapter/ScheduledPublisherTest.res +199 -0
  193. package/tests/adapter/ScheduledPublisherTest.res.mjs +203 -0
  194. package/tests/adapter/SortKey_FilterTest.res +103 -0
  195. package/tests/adapter/SortKey_FilterTest.res.mjs +135 -0
  196. package/tests/adapter/SqliteDriverTest.res +86 -0
  197. package/tests/adapter/SqliteDriverTest.res.mjs +101 -0
  198. package/tests/adapter/TaskBucketSqliteTest.res +44 -0
  199. package/tests/adapter/TaskBucketSqliteTest.res.mjs +40 -0
  200. package/tests/adapter/TaskBucketTest.res +106 -0
  201. package/tests/adapter/TaskBucketTest.res.mjs +118 -0
  202. package/tests/components/aggregate/AggregateFixtures.res +78 -0
  203. package/tests/components/aggregate/AggregateFixtures.res.mjs +109 -0
  204. package/tests/components/aggregate/AggregateTest.res +129 -0
  205. package/tests/components/aggregate/AggregateTest.res.mjs +129 -0
  206. package/tests/components/automationslice/AutomationSliceCallbackTest.res +212 -0
  207. package/tests/components/automationslice/AutomationSliceCallbackTest.res.mjs +233 -0
  208. package/tests/components/automationslice/AutomationSliceFixtures.res +189 -0
  209. package/tests/components/automationslice/AutomationSliceFixtures.res.mjs +276 -0
  210. package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +289 -0
  211. package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res.mjs +453 -0
  212. package/tests/components/automationslice/AutomationSliceSelfDeadlockTest.res +47 -0
  213. package/tests/components/automationslice/AutomationSliceSelfDeadlockTest.res.mjs +31 -0
  214. package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +213 -0
  215. package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res.mjs +268 -0
  216. package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +118 -0
  217. package/tests/components/automationslice/MixedSourceAutomationSliceTest.res.mjs +99 -0
  218. package/tests/components/commandgenerator/CommandGeneratorFixtures.res +73 -0
  219. package/tests/components/commandgenerator/CommandGeneratorFixtures.res.mjs +109 -0
  220. package/tests/components/commandgenerator/CommandGeneratorTest.res +43 -0
  221. package/tests/components/commandgenerator/CommandGeneratorTest.res.mjs +46 -0
  222. package/tests/components/commandtopic/CommandTopicFixtures.res +37 -0
  223. package/tests/components/commandtopic/CommandTopicFixtures.res.mjs +68 -0
  224. package/tests/components/commandtopic/CommandTopicStreamFixtures.res +43 -0
  225. package/tests/components/commandtopic/CommandTopicStreamFixtures.res.mjs +91 -0
  226. package/tests/components/commandtopic/CommandTopicStreamTest.res +30 -0
  227. package/tests/components/commandtopic/CommandTopicStreamTest.res.mjs +35 -0
  228. package/tests/components/commandtopic/CommandTopicTest.res +55 -0
  229. package/tests/components/commandtopic/CommandTopicTest.res.mjs +62 -0
  230. package/tests/components/counter/CounterFixtures.res +42 -0
  231. package/tests/components/counter/CounterFixtures.res.mjs +34 -0
  232. package/tests/components/counter/CounterTest.res +46 -0
  233. package/tests/components/counter/CounterTest.res.mjs +61 -0
  234. package/tests/components/dcb/DcbCrossPartitionFixtures.res +170 -0
  235. package/tests/components/dcb/DcbCrossPartitionFixtures.res.mjs +276 -0
  236. package/tests/components/dcb/DcbCrossPartitionReadTest.res +68 -0
  237. package/tests/components/dcb/DcbCrossPartitionReadTest.res.mjs +78 -0
  238. package/tests/components/dcb/DcbEventLogAppendStreamTest.res +72 -0
  239. package/tests/components/dcb/DcbEventLogAppendStreamTest.res.mjs +82 -0
  240. package/tests/components/dcb/DcbEventLogStreamTest.res +103 -0
  241. package/tests/components/dcb/DcbEventLogStreamTest.res.mjs +91 -0
  242. package/tests/components/dcb/DcbFixtures.res +145 -0
  243. package/tests/components/dcb/DcbFixtures.res.mjs +221 -0
  244. package/tests/components/dcb/DcbTest.res +55 -0
  245. package/tests/components/dcb/DcbTest.res.mjs +55 -0
  246. package/tests/components/eventcollector/EventCollectorFixtures.res +42 -0
  247. package/tests/components/eventcollector/EventCollectorFixtures.res.mjs +49 -0
  248. package/tests/components/eventcollector/EventCollectorTest.res +37 -0
  249. package/tests/components/eventcollector/EventCollectorTest.res.mjs +36 -0
  250. package/tests/components/eventlog/EventLogAppendStreamTest.res +93 -0
  251. package/tests/components/eventlog/EventLogAppendStreamTest.res.mjs +113 -0
  252. package/tests/components/eventlog/EventLogConflictTest.res +86 -0
  253. package/tests/components/eventlog/EventLogConflictTest.res.mjs +81 -0
  254. package/tests/components/eventlog/EventLogFixtures.res +52 -0
  255. package/tests/components/eventlog/EventLogFixtures.res.mjs +80 -0
  256. package/tests/components/eventlog/EventLogStreamTest.res +98 -0
  257. package/tests/components/eventlog/EventLogStreamTest.res.mjs +142 -0
  258. package/tests/components/eventlog/EventLogTest.res +53 -0
  259. package/tests/components/eventlog/EventLogTest.res.mjs +74 -0
  260. package/tests/components/eventtopic/EventTopicFixtures.res +47 -0
  261. package/tests/components/eventtopic/EventTopicFixtures.res.mjs +77 -0
  262. package/tests/components/eventtopic/EventTopicStreamFixtures.res +27 -0
  263. package/tests/components/eventtopic/EventTopicStreamFixtures.res.mjs +62 -0
  264. package/tests/components/eventtopic/EventTopicStreamTest.res +35 -0
  265. package/tests/components/eventtopic/EventTopicStreamTest.res.mjs +44 -0
  266. package/tests/components/eventtopic/EventTopicTest.res +35 -0
  267. package/tests/components/eventtopic/EventTopicTest.res.mjs +43 -0
  268. package/tests/components/extensionpoint/ExtensionPointFixtures.res +145 -0
  269. package/tests/components/extensionpoint/ExtensionPointFixtures.res.mjs +188 -0
  270. package/tests/components/extensionpoint/ExtensionPointTest.res +62 -0
  271. package/tests/components/extensionpoint/ExtensionPointTest.res.mjs +55 -0
  272. package/tests/components/heartbeat/HeartbeatFixtures.res +48 -0
  273. package/tests/components/heartbeat/HeartbeatFixtures.res.mjs +46 -0
  274. package/tests/components/heartbeat/HeartbeatTest.res +67 -0
  275. package/tests/components/heartbeat/HeartbeatTest.res.mjs +65 -0
  276. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +241 -0
  277. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res.mjs +239 -0
  278. package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +36 -0
  279. package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res.mjs +73 -0
  280. package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +191 -0
  281. package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res.mjs +297 -0
  282. package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +78 -0
  283. package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res.mjs +137 -0
  284. package/tests/components/querydb/QueryDbFixtures.res +39 -0
  285. package/tests/components/querydb/QueryDbFixtures.res.mjs +73 -0
  286. package/tests/components/querydb/QueryDbSubIdFixtures.res +44 -0
  287. package/tests/components/querydb/QueryDbSubIdFixtures.res.mjs +80 -0
  288. package/tests/components/querydb/QueryDbSubIdTest.res +104 -0
  289. package/tests/components/querydb/QueryDbSubIdTest.res.mjs +104 -0
  290. package/tests/components/querydb/QueryDbTest.res +81 -0
  291. package/tests/components/querydb/QueryDbTest.res.mjs +126 -0
  292. package/tests/components/readmodel/DcbReadModelE2EFixtures.res +215 -0
  293. package/tests/components/readmodel/DcbReadModelE2EFixtures.res.mjs +308 -0
  294. package/tests/components/readmodel/DcbReadModelE2ETest.res +45 -0
  295. package/tests/components/readmodel/DcbReadModelE2ETest.res.mjs +37 -0
  296. package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res +88 -0
  297. package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res.mjs +152 -0
  298. package/tests/components/readmodel/MixedSourceReadModelFixtures.res +181 -0
  299. package/tests/components/readmodel/MixedSourceReadModelFixtures.res.mjs +277 -0
  300. package/tests/components/readmodel/MixedSourceReadModelTest.res +61 -0
  301. package/tests/components/readmodel/MixedSourceReadModelTest.res.mjs +68 -0
  302. package/tests/components/readmodel/ReadModelFixtures.res +138 -0
  303. package/tests/components/readmodel/ReadModelFixtures.res.mjs +169 -0
  304. package/tests/components/readmodel/ReadModelTest.res +46 -0
  305. package/tests/components/readmodel/ReadModelTest.res.mjs +36 -0
  306. package/tests/components/scheduler/SchedulerFixtures.res +59 -0
  307. package/tests/components/scheduler/SchedulerFixtures.res.mjs +63 -0
  308. package/tests/components/scheduler/SchedulerTest.res +76 -0
  309. package/tests/components/scheduler/SchedulerTest.res.mjs +86 -0
  310. package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +133 -0
  311. package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res.mjs +149 -0
  312. package/tests/components/sideeffecthandler/SideEffectHandlerTest.res +39 -0
  313. package/tests/components/sideeffecthandler/SideEffectHandlerTest.res.mjs +28 -0
  314. package/tests/components/stateviewslice/StateViewSliceFixtures.res +117 -0
  315. package/tests/components/stateviewslice/StateViewSliceFixtures.res.mjs +188 -0
  316. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +117 -0
  317. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res.mjs +183 -0
  318. package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +78 -0
  319. package/tests/components/stateviewslice/StateViewSliceSubIdTest.res.mjs +107 -0
  320. package/tests/components/stateviewslice/StateViewSliceTest.res +59 -0
  321. package/tests/components/stateviewslice/StateViewSliceTest.res.mjs +72 -0
  322. package/tests/components/task/TaskFixtures.res +87 -0
  323. package/tests/components/task/TaskFixtures.res.mjs +82 -0
  324. package/tests/components/task/TaskTest.res +98 -0
  325. package/tests/components/task/TaskTest.res.mjs +46 -0
  326. package/tests/plugin/PluginBehavior_GWT.res +146 -0
  327. package/tests/plugin/PluginBehavior_GWT.res.mjs +281 -0
  328. package/tests/plugin/Plugin_Fixtures.res +61 -0
  329. package/tests/plugin/Plugin_Fixtures.res.mjs +105 -0
  330. package/tests/plugin/PluginsProjection_GWT.res +95 -0
  331. package/tests/plugin/PluginsProjection_GWT.res.mjs +120 -0
  332. package/tests/plugin/UIFragmentRegistryProjection_GWT.res +72 -0
  333. package/tests/plugin/UIFragmentRegistryProjection_GWT.res.mjs +117 -0
  334. package/tests/setup/sqliteGlobal.cjs +12 -0
@@ -0,0 +1,191 @@
1
+ // Unit tests for OutboundTranslationSlice_Callback — tests collect and translate phases directly.
2
+
3
+ open JestGlobals
4
+ open OutboundTranslationSliceFixtures
5
+
6
+ module SendTrackingEmailTranslation = {
7
+ let collect = SendTrackingEmailSpec.collect
8
+ let translate = SendTrackingEmailSpec.translate
9
+ let moduleUrl = SendTrackingEmailSpec.moduleUrl
10
+ }
11
+ module ProcessPaymentTranslation = {
12
+ let collect = ProcessPaymentSpec.collect
13
+ let translate = ProcessPaymentSpec.translate
14
+ let moduleUrl = ProcessPaymentSpec.moduleUrl
15
+ }
16
+ module FireForgetCallback = ReventlessCore.OutboundTranslationSlice_Callback.Make(
17
+ SendTrackingEmailSpec,
18
+ SendTrackingEmailTranslation,
19
+ )
20
+ module CommandBackCallback = ReventlessCore.OutboundTranslationSlice_Callback.Make(
21
+ ProcessPaymentSpec,
22
+ ProcessPaymentTranslation,
23
+ )
24
+
25
+ open ReventlessCore.OutboundTranslationSlice_Callback
26
+
27
+ describe("OutboundTranslationSlice Callback", () => {
28
+ let _ = beforeEach(() => {
29
+ FireForgetCallback.todoItems->Dict.keysToArray->Array.forEach(k => FireForgetCallback.todoItems->Dict.delete(k))
30
+ CommandBackCallback.todoItems->Dict.keysToArray->Array.forEach(k => CommandBackCallback.todoItems->Dict.delete(k))
31
+ // Reset the translate function to its default
32
+ ProcessPaymentSpec.translateFn :=
33
+ (async (id, _item) => Ok(Some((id, ProcessPaymentSpec.ConfirmPayment({orderId: id})))))
34
+ })
35
+
36
+ describe("Phase 1 — collect", () => {
37
+ testPromise("OrderShipped event creates a pending outbound item", async () => {
38
+ FireForgetCallback.phase1([OrderShipped({orderId: "ord-1", email: "test@example.com"})])
39
+ let items = FireForgetCallback.todoItems
40
+ expect(items->Dict.toArray->Array.length)->toBe(1)
41
+ let row = items->Dict.get("ord-1")
42
+ expect(row->Option.isSome)->toBe(true)
43
+ let r = row->Option.getOrThrow
44
+ expect(r.status)->toBe(Pending)
45
+ expect(r.retryCount)->toBe(0)
46
+ })
47
+
48
+ testPromise("duplicate event does not create a second item (idempotent)", async () => {
49
+ FireForgetCallback.phase1([OrderShipped({orderId: "ord-1", email: "test@example.com"})])
50
+ FireForgetCallback.phase1([OrderShipped({orderId: "ord-1", email: "other@example.com"})])
51
+ let items = FireForgetCallback.todoItems
52
+ expect(items->Dict.toArray->Array.length)->toBe(1)
53
+ })
54
+
55
+ testPromise("multiple different events create multiple items", async () => {
56
+ FireForgetCallback.phase1([
57
+ OrderShipped({orderId: "ord-1", email: "a@example.com"}),
58
+ OrderShipped({orderId: "ord-2", email: "b@example.com"}),
59
+ ])
60
+ let items = FireForgetCallback.todoItems
61
+ expect(items->Dict.toArray->Array.length)->toBe(2)
62
+ })
63
+
64
+ })
65
+
66
+ describe("Phase 2 — translate (fire-and-forget)", () => {
67
+ testPromise("Ok(None) marks item as Completed, no command published", async () => {
68
+ FireForgetCallback.phase1([OrderShipped({orderId: "ord-1", email: "test@example.com"})])
69
+ let publishedCommands = ref([])
70
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
71
+ publishedCommands := cmds
72
+ }
73
+ await FireForgetCallback.phase2(mockPublish)
74
+ expect(publishedCommands.contents->Array.length)->toBe(0)
75
+ let row = FireForgetCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
76
+ expect(row.status)->toBe(Completed)
77
+ })
78
+
79
+ testPromise("empty TODO list produces no commands", async () => {
80
+ let publishedCommands = ref([])
81
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
82
+ publishedCommands := cmds
83
+ }
84
+ await FireForgetCallback.phase2(mockPublish)
85
+ expect(publishedCommands.contents->Array.length)->toBe(0)
86
+ })
87
+ })
88
+
89
+ describe("Phase 2 — translate (command-back)", () => {
90
+ testPromise("Ok(Some(...)) marks item as Completed and publishes command", async () => {
91
+ CommandBackCallback.phase1([PaymentReceived({orderId: "ord-1", amount: 50.0})])
92
+ let publishedCommands = ref([])
93
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
94
+ publishedCommands := Array.concat(publishedCommands.contents, cmds)
95
+ }
96
+ await CommandBackCallback.phase2(mockPublish)
97
+ expect(publishedCommands.contents->Array.length)->toBe(1)
98
+ let cmd = publishedCommands.contents->Array.getUnsafe(0)
99
+ expect(cmd.id)->toBe("ord-1")
100
+ let row = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
101
+ expect(row.status)->toBe(Completed)
102
+ })
103
+
104
+ testPromise("Error marks item as Failed with incremented retryCount", async () => {
105
+ ProcessPaymentSpec.translateFn := (async (_id, _item) => Error("gateway timeout"))
106
+
107
+ CommandBackCallback.phase1([PaymentReceived({orderId: "ord-1", amount: 50.0})])
108
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async _cmds => ()
109
+ await CommandBackCallback.phase2(mockPublish)
110
+
111
+ let row = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
112
+ expect(row.status)->toBe(Failed)
113
+ expect(row.retryCount)->toBe(1)
114
+ })
115
+
116
+ testPromise("failed items with retryCount < maxRetries are retried", async () => {
117
+ // First attempt fails
118
+ ProcessPaymentSpec.translateFn := (async (_id, _item) => Error("timeout"))
119
+ CommandBackCallback.phase1([PaymentReceived({orderId: "ord-1", amount: 50.0})])
120
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async _cmds => ()
121
+ await CommandBackCallback.phase2(mockPublish)
122
+ let row1 = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
123
+ expect(row1.retryCount)->toBe(1)
124
+
125
+ // Second attempt succeeds
126
+ ProcessPaymentSpec.translateFn :=
127
+ (async (id, _item) => Ok(Some((id, ProcessPaymentSpec.ConfirmPayment({orderId: id})))))
128
+ let publishedCommands = ref([])
129
+ let successPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
130
+ publishedCommands := cmds
131
+ }
132
+ await CommandBackCallback.phase2(successPublish)
133
+ expect(publishedCommands.contents->Array.length)->toBe(1)
134
+ let row2 = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
135
+ expect(row2.status)->toBe(Completed)
136
+ })
137
+
138
+ testPromise("failed items beyond maxRetries are not retried", async () => {
139
+ // ProcessPaymentSpec.maxRetries = 2, so after 2 failures it should stop
140
+ ProcessPaymentSpec.translateFn := (async (_id, _item) => Error("timeout"))
141
+ CommandBackCallback.phase1([PaymentReceived({orderId: "ord-1", amount: 50.0})])
142
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async _cmds => ()
143
+
144
+ // Fail twice
145
+ await CommandBackCallback.phase2(mockPublish)
146
+ await CommandBackCallback.phase2(mockPublish)
147
+ let row = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
148
+ expect(row.retryCount)->toBe(2)
149
+
150
+ // Third attempt should not be tried
151
+ let publishedCommands = ref([])
152
+ let trackPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
153
+ publishedCommands := cmds
154
+ }
155
+ await CommandBackCallback.phase2(trackPublish)
156
+ expect(publishedCommands.contents->Array.length)->toBe(0)
157
+ let row2 = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
158
+ // retryCount should still be 2 — not retried
159
+ expect(row2.retryCount)->toBe(2)
160
+ })
161
+
162
+ testPromise("individual item failure does not affect other items", async () => {
163
+ let callCount = ref(0)
164
+ ProcessPaymentSpec.translateFn := (async (id, _item) => {
165
+ callCount := callCount.contents + 1
166
+ if callCount.contents == 1 {
167
+ Error("first item fails")
168
+ } else {
169
+ Ok(Some((id, ProcessPaymentSpec.ConfirmPayment({orderId: id}))))
170
+ }
171
+ })
172
+
173
+ CommandBackCallback.phase1([
174
+ PaymentReceived({orderId: "ord-1", amount: 50.0}),
175
+ PaymentReceived({orderId: "ord-2", amount: 75.0}),
176
+ ])
177
+ let publishedCommands = ref([])
178
+ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
179
+ publishedCommands := Array.concat(publishedCommands.contents, cmds)
180
+ }
181
+ await CommandBackCallback.phase2(mockPublish)
182
+
183
+ // ord-1 should be Failed, ord-2 should be Completed
184
+ let row1 = CommandBackCallback.todoItems->Dict.get("ord-1")->Option.getOrThrow
185
+ expect(row1.status)->toBe(Failed)
186
+ let row2 = CommandBackCallback.todoItems->Dict.get("ord-2")->Option.getOrThrow
187
+ expect(row2.status)->toBe(Completed)
188
+ expect(publishedCommands.contents->Array.length)->toBe(1)
189
+ })
190
+ })
191
+ })
@@ -0,0 +1,297 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
4
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
+ import * as OutboundTranslationSliceFixtures$ReventlessLocal from "./OutboundTranslationSliceFixtures.res.mjs";
6
+ import * as OutboundTranslationSlice_Callback$ReventlessCore from "@reventlessdev/reventless-core/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Callback.res.mjs";
7
+
8
+ let collect = OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.collect;
9
+
10
+ let translate = OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.translate;
11
+
12
+ let moduleUrl = OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.moduleUrl;
13
+
14
+ let SendTrackingEmailTranslation = {
15
+ collect: collect,
16
+ translate: translate,
17
+ moduleUrl: moduleUrl
18
+ };
19
+
20
+ let collect$1 = OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.collect;
21
+
22
+ let translate$1 = OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translate;
23
+
24
+ let moduleUrl$1 = OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.moduleUrl;
25
+
26
+ let ProcessPaymentTranslation = {
27
+ collect: collect$1,
28
+ translate: translate$1,
29
+ moduleUrl: moduleUrl$1
30
+ };
31
+
32
+ let FireForgetCallback = OutboundTranslationSlice_Callback$ReventlessCore.Make({
33
+ name: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.name,
34
+ moduleUrl: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.moduleUrl,
35
+ consumedEventSchema: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.consumedEventSchema,
36
+ outboundItemSchema: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.outboundItemSchema,
37
+ inboundCommandSchema: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.inboundCommandSchema,
38
+ maxRetries: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.maxRetries,
39
+ heartbeatInterval: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.heartbeatInterval,
40
+ targetName: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.targetName
41
+ })(SendTrackingEmailTranslation);
42
+
43
+ let CommandBackCallback = OutboundTranslationSlice_Callback$ReventlessCore.Make({
44
+ name: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.name,
45
+ moduleUrl: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.moduleUrl,
46
+ consumedEventSchema: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.consumedEventSchema,
47
+ outboundItemSchema: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.outboundItemSchema,
48
+ inboundCommandSchema: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.inboundCommandSchema,
49
+ maxRetries: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.maxRetries,
50
+ heartbeatInterval: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.heartbeatInterval,
51
+ targetName: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.targetName
52
+ })(ProcessPaymentTranslation);
53
+
54
+ globalThis.describe("OutboundTranslationSlice Callback", () => {
55
+ globalThis.beforeEach(() => {
56
+ Object.keys(FireForgetCallback.todoItems).forEach(k => Stdlib_Dict.$$delete(FireForgetCallback.todoItems, k));
57
+ Object.keys(CommandBackCallback.todoItems).forEach(k => Stdlib_Dict.$$delete(CommandBackCallback.todoItems, k));
58
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (id, _item) => ({
59
+ TAG: "Ok",
60
+ _0: [
61
+ id,
62
+ {
63
+ TAG: "ConfirmPayment",
64
+ orderId: id
65
+ }
66
+ ]
67
+ });
68
+ });
69
+ globalThis.describe("Phase 1 — collect", () => {
70
+ globalThis.test("OrderShipped event creates a pending outbound item", async () => {
71
+ FireForgetCallback.phase1([{
72
+ TAG: "OrderShipped",
73
+ orderId: "ord-1",
74
+ email: "test@example.com"
75
+ }]);
76
+ let items = FireForgetCallback.todoItems;
77
+ globalThis.expect(Object.entries(items).length).toBe(1);
78
+ let row = items["ord-1"];
79
+ globalThis.expect(Stdlib_Option.isSome(row)).toBe(true);
80
+ let r = Stdlib_Option.getOrThrow(row, undefined);
81
+ globalThis.expect(r.status).toBe("Pending");
82
+ globalThis.expect(r.retryCount).toBe(0);
83
+ });
84
+ globalThis.test("duplicate event does not create a second item (idempotent)", async () => {
85
+ FireForgetCallback.phase1([{
86
+ TAG: "OrderShipped",
87
+ orderId: "ord-1",
88
+ email: "test@example.com"
89
+ }]);
90
+ FireForgetCallback.phase1([{
91
+ TAG: "OrderShipped",
92
+ orderId: "ord-1",
93
+ email: "other@example.com"
94
+ }]);
95
+ globalThis.expect(Object.entries(FireForgetCallback.todoItems).length).toBe(1);
96
+ });
97
+ globalThis.test("multiple different events create multiple items", async () => {
98
+ FireForgetCallback.phase1([
99
+ {
100
+ TAG: "OrderShipped",
101
+ orderId: "ord-1",
102
+ email: "a@example.com"
103
+ },
104
+ {
105
+ TAG: "OrderShipped",
106
+ orderId: "ord-2",
107
+ email: "b@example.com"
108
+ }
109
+ ]);
110
+ globalThis.expect(Object.entries(FireForgetCallback.todoItems).length).toBe(2);
111
+ });
112
+ });
113
+ globalThis.describe("Phase 2 — translate (fire-and-forget)", () => {
114
+ globalThis.test("Ok(None) marks item as Completed, no command published", async () => {
115
+ FireForgetCallback.phase1([{
116
+ TAG: "OrderShipped",
117
+ orderId: "ord-1",
118
+ email: "test@example.com"
119
+ }]);
120
+ let publishedCommands = {
121
+ contents: []
122
+ };
123
+ let mockPublish = async cmds => {
124
+ publishedCommands.contents = cmds;
125
+ };
126
+ await FireForgetCallback.phase2(mockPublish);
127
+ globalThis.expect(publishedCommands.contents.length).toBe(0);
128
+ let row = Stdlib_Option.getOrThrow(FireForgetCallback.todoItems["ord-1"], undefined);
129
+ globalThis.expect(row.status).toBe("Completed");
130
+ });
131
+ globalThis.test("empty TODO list produces no commands", async () => {
132
+ let publishedCommands = {
133
+ contents: []
134
+ };
135
+ let mockPublish = async cmds => {
136
+ publishedCommands.contents = cmds;
137
+ };
138
+ await FireForgetCallback.phase2(mockPublish);
139
+ globalThis.expect(publishedCommands.contents.length).toBe(0);
140
+ });
141
+ });
142
+ globalThis.describe("Phase 2 — translate (command-back)", () => {
143
+ globalThis.test("Ok(Some(...)) marks item as Completed and publishes command", async () => {
144
+ CommandBackCallback.phase1([{
145
+ TAG: "PaymentReceived",
146
+ orderId: "ord-1",
147
+ amount: 50.0
148
+ }]);
149
+ let publishedCommands = {
150
+ contents: []
151
+ };
152
+ let mockPublish = async cmds => {
153
+ publishedCommands.contents = publishedCommands.contents.concat(cmds);
154
+ };
155
+ await CommandBackCallback.phase2(mockPublish);
156
+ globalThis.expect(publishedCommands.contents.length).toBe(1);
157
+ let cmd = publishedCommands.contents[0];
158
+ globalThis.expect(cmd.id).toBe("ord-1");
159
+ let row = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
160
+ globalThis.expect(row.status).toBe("Completed");
161
+ });
162
+ globalThis.test("Error marks item as Failed with incremented retryCount", async () => {
163
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (_id, _item) => ({
164
+ TAG: "Error",
165
+ _0: "gateway timeout"
166
+ });
167
+ CommandBackCallback.phase1([{
168
+ TAG: "PaymentReceived",
169
+ orderId: "ord-1",
170
+ amount: 50.0
171
+ }]);
172
+ let mockPublish = async _cmds => {};
173
+ await CommandBackCallback.phase2(mockPublish);
174
+ let row = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
175
+ globalThis.expect(row.status).toBe("Failed");
176
+ globalThis.expect(row.retryCount).toBe(1);
177
+ });
178
+ globalThis.test("failed items with retryCount < maxRetries are retried", async () => {
179
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (_id, _item) => ({
180
+ TAG: "Error",
181
+ _0: "timeout"
182
+ });
183
+ CommandBackCallback.phase1([{
184
+ TAG: "PaymentReceived",
185
+ orderId: "ord-1",
186
+ amount: 50.0
187
+ }]);
188
+ let mockPublish = async _cmds => {};
189
+ await CommandBackCallback.phase2(mockPublish);
190
+ let row1 = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
191
+ globalThis.expect(row1.retryCount).toBe(1);
192
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (id, _item) => ({
193
+ TAG: "Ok",
194
+ _0: [
195
+ id,
196
+ {
197
+ TAG: "ConfirmPayment",
198
+ orderId: id
199
+ }
200
+ ]
201
+ });
202
+ let publishedCommands = {
203
+ contents: []
204
+ };
205
+ let successPublish = async cmds => {
206
+ publishedCommands.contents = cmds;
207
+ };
208
+ await CommandBackCallback.phase2(successPublish);
209
+ globalThis.expect(publishedCommands.contents.length).toBe(1);
210
+ let row2 = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
211
+ globalThis.expect(row2.status).toBe("Completed");
212
+ });
213
+ globalThis.test("failed items beyond maxRetries are not retried", async () => {
214
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (_id, _item) => ({
215
+ TAG: "Error",
216
+ _0: "timeout"
217
+ });
218
+ CommandBackCallback.phase1([{
219
+ TAG: "PaymentReceived",
220
+ orderId: "ord-1",
221
+ amount: 50.0
222
+ }]);
223
+ let mockPublish = async _cmds => {};
224
+ await CommandBackCallback.phase2(mockPublish);
225
+ await CommandBackCallback.phase2(mockPublish);
226
+ let row = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
227
+ globalThis.expect(row.retryCount).toBe(2);
228
+ let publishedCommands = {
229
+ contents: []
230
+ };
231
+ let trackPublish = async cmds => {
232
+ publishedCommands.contents = cmds;
233
+ };
234
+ await CommandBackCallback.phase2(trackPublish);
235
+ globalThis.expect(publishedCommands.contents.length).toBe(0);
236
+ let row2 = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
237
+ globalThis.expect(row2.retryCount).toBe(2);
238
+ });
239
+ globalThis.test("individual item failure does not affect other items", async () => {
240
+ let callCount = {
241
+ contents: 0
242
+ };
243
+ OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.translateFn.contents = async (id, _item) => {
244
+ callCount.contents = callCount.contents + 1 | 0;
245
+ if (callCount.contents === 1) {
246
+ return {
247
+ TAG: "Error",
248
+ _0: "first item fails"
249
+ };
250
+ } else {
251
+ return {
252
+ TAG: "Ok",
253
+ _0: [
254
+ id,
255
+ {
256
+ TAG: "ConfirmPayment",
257
+ orderId: id
258
+ }
259
+ ]
260
+ };
261
+ }
262
+ };
263
+ CommandBackCallback.phase1([
264
+ {
265
+ TAG: "PaymentReceived",
266
+ orderId: "ord-1",
267
+ amount: 50.0
268
+ },
269
+ {
270
+ TAG: "PaymentReceived",
271
+ orderId: "ord-2",
272
+ amount: 75.0
273
+ }
274
+ ]);
275
+ let publishedCommands = {
276
+ contents: []
277
+ };
278
+ let mockPublish = async cmds => {
279
+ publishedCommands.contents = publishedCommands.contents.concat(cmds);
280
+ };
281
+ await CommandBackCallback.phase2(mockPublish);
282
+ let row1 = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-1"], undefined);
283
+ globalThis.expect(row1.status).toBe("Failed");
284
+ let row2 = Stdlib_Option.getOrThrow(CommandBackCallback.todoItems["ord-2"], undefined);
285
+ globalThis.expect(row2.status).toBe("Completed");
286
+ globalThis.expect(publishedCommands.contents.length).toBe(1);
287
+ });
288
+ });
289
+ });
290
+
291
+ export {
292
+ SendTrackingEmailTranslation,
293
+ ProcessPaymentTranslation,
294
+ FireForgetCallback,
295
+ CommandBackCallback,
296
+ }
297
+ /* FireForgetCallback Not a pure module */
@@ -0,0 +1,78 @@
1
+ // Test fixtures for OutboundTranslationSlice callback tests.
2
+
3
+ // ─────────────────────────────────────────────────────────────
4
+ // Minimal DcbEventLog spec
5
+ // ─────────────────────────────────────────────────────────────
6
+
7
+ module OrderEventLog = {
8
+ let moduleUrl: string = %raw(`import.meta.url`)
9
+ @schema
10
+ type event =
11
+ | OrderShipped({orderId: @s.matches(Reventless.DcbTag.string) string, email: string})
12
+ | PaymentReceived({orderId: @s.matches(Reventless.DcbTag.string) string, amount: float})
13
+ }
14
+
15
+ // ─────────────────────────────────────────────────────────────
16
+ // Fire-and-forget spec — translate returns Ok(None)
17
+ // ─────────────────────────────────────────────────────────────
18
+
19
+ module SendTrackingEmailSpec = {
20
+ let name = "SendTrackingEmail"
21
+ let moduleUrl: string = %raw(`import.meta.url`)
22
+
23
+ @schema
24
+ type consumedEvent =
25
+ | OrderShipped({orderId: string, email: string})
26
+
27
+ @schema
28
+ type outboundItem = {orderId: string, email: string}
29
+
30
+ @schema
31
+ type inboundCommand = unit
32
+
33
+ let collect = event =>
34
+ switch event {
35
+ | OrderShipped({orderId, email}) => [(orderId, {orderId, email})]
36
+ }
37
+
38
+ let translate = async (_id, _item) => Ok(None)
39
+
40
+ let maxRetries = 3
41
+ let heartbeatInterval = 60
42
+ let targetName = None
43
+ }
44
+
45
+ // ─────────────────────────────────────────────────────────────
46
+ // Command-back spec — translate returns Ok(Some(...))
47
+ // ─────────────────────────────────────────────────────────────
48
+
49
+ module ProcessPaymentSpec = {
50
+ let name = "ProcessPayment"
51
+ let moduleUrl: string = %raw(`import.meta.url`)
52
+
53
+ @schema
54
+ type consumedEvent =
55
+ | PaymentReceived({orderId: string, amount: float})
56
+
57
+ @schema
58
+ type outboundItem = {orderId: string, amount: float}
59
+
60
+ @schema
61
+ type inboundCommand = ConfirmPayment({orderId: @s.matches(Reventless.DcbTag.string) string})
62
+
63
+ let collect = event =>
64
+ switch event {
65
+ | PaymentReceived({orderId, amount}) => [(orderId, {orderId, amount})]
66
+ }
67
+
68
+ // Simulate calling external payment gateway, then return a command
69
+ let translateFn: ref<(string, outboundItem) => promise<result<option<(string, inboundCommand)>, string>>> = ref(
70
+ async (id, _item) => Ok(Some((id, ConfirmPayment({orderId: id}))))
71
+ )
72
+
73
+ let translate = (id, item) => translateFn.contents(id, item)
74
+
75
+ let maxRetries = 2
76
+ let heartbeatInterval = 30
77
+ let targetName = Some("ConfirmPayment")
78
+ }