@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,166 @@
1
+ // Unit tests for LocalEventCollectorChannel.
2
+ // Verifies resource collection in make() and subscriber wiring in connect().
3
+
4
+ open JestGlobals
5
+
6
+ let _ = TestRunner.setup()
7
+
8
+ let testMeta: Reventless.Message.meta = {
9
+ service: "test",
10
+ time: "",
11
+ ip: "",
12
+ user: "test",
13
+ msgId: "",
14
+ correlationId: "",
15
+ }
16
+
17
+ // ─────────────────────────────────────────────────────────────
18
+ // Helper: build a minimal runtime with a completed handler Deferred
19
+ // ─────────────────────────────────────────────────────────────
20
+
21
+ let makeRuntime = (
22
+ handler: LocalRuntimeEnvironment.handler,
23
+ ): ReventlessCore.Runtime.environment<LocalRuntimeEnvironment.parts> => {
24
+ let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
25
+ Deferred.make()->Effect.runSync
26
+ Deferred.succeed(handlerDeferred, handler)->Effect.runSync->ignore
27
+ {
28
+ parts: {
29
+ handlerDeferred,
30
+ subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
31
+ },
32
+ resources: [],
33
+ }
34
+ }
35
+
36
+ describe("LocalEventCollectorChannel", () => {
37
+ describe("make", () => {
38
+ testPromise("collects all event topic resources as channel resources", async () => {
39
+ module TestBus = LocalBus.Make()
40
+ module TestPublisher = LocalEventTopicPublisher.Make(TestBus)
41
+ module TestCollector = LocalEventCollectorChannel.Make(TestBus)
42
+ let pubA = TestPublisher.make(~name="topicA", ~storageResources=[], ~opts={})
43
+ let pubB = TestPublisher.make(~name="topicB", ~storageResources=[], ~opts={})
44
+ let eventTopics = Dict.fromArray([
45
+ ("topicA", {ReventlessInfra.EventTopic.resources: pubA.resources}),
46
+ ("topicB", {ReventlessInfra.EventTopic.resources: pubB.resources}),
47
+ ])
48
+ let ch = TestCollector.make(~name="collector", ~eventTopics, ~opts={})
49
+ // Each publisher returns 1 resource, so 2 total
50
+ expect(ch.resources->Array.length)->toBe(2)
51
+ })
52
+
53
+ testPromise("empty eventTopics produces empty resources", async () => {
54
+ module TestBus = LocalBus.Make()
55
+ module TestCollector = LocalEventCollectorChannel.Make(TestBus)
56
+ let ch = TestCollector.make(~name="collector", ~eventTopics=Dict.make(), ~opts={})
57
+ expect(ch.resources->Array.length)->toBe(0)
58
+ })
59
+ })
60
+
61
+ describe("connect", () => {
62
+ testPromise("subscribes to event topic; published events reach the handler", async () => {
63
+ module TestBus = LocalBus.Make()
64
+ module TestPublisher = LocalEventTopicPublisher.Make(TestBus)
65
+ module TestCollector = LocalEventCollectorChannel.Make(TestBus)
66
+ let received: ref<int> = ref(0)
67
+ let runtime = makeRuntime(async (_, _ctx) => {
68
+ received := received.contents + 1
69
+ })
70
+ let pub = TestPublisher.make(~name="eventA", ~storageResources=[], ~opts={})
71
+ let eventTopics = Dict.fromArray([
72
+ ("eventA", {ReventlessInfra.EventTopic.resources: pub.resources}),
73
+ ])
74
+ let ch = TestCollector.make(~name="collector", ~eventTopics, ~opts={})
75
+ let channelSpec: ReventlessCore.EventCollector_Adapter.channelSpec<JSON.t, unit, unit> = {
76
+ channel: ch,
77
+ eventTopics,
78
+ resources: [],
79
+ }
80
+ let _ = TestCollector.connect(
81
+ ~name="collector",
82
+ ~channelSpecs=[channelSpec],
83
+ ~runtime,
84
+ ~opts={},
85
+ )
86
+ // Await the subscriptionLatch — opens after Output.apply fires and subscription registers
87
+ await runtime.parts.subscriptionLatch->Latch.await_->Effect.runPromise
88
+ let publishFn = await pub.publishJson->TestRunner.resolve
89
+ await publishFn("svc", testMeta, JSON.Null)
90
+ expect(received.contents)->toBe(1)
91
+ })
92
+
93
+ testPromise("multiple event topics all deliver to the same handler", async () => {
94
+ module TestBus = LocalBus.Make()
95
+ module TestPublisher = LocalEventTopicPublisher.Make(TestBus)
96
+ module TestCollector = LocalEventCollectorChannel.Make(TestBus)
97
+ let received: ref<int> = ref(0)
98
+ let runtime = makeRuntime(async (_, _) => {
99
+ received := received.contents + 1
100
+ })
101
+ let pub1 = TestPublisher.make(~name="topicX", ~storageResources=[], ~opts={})
102
+ let pub2 = TestPublisher.make(~name="topicY", ~storageResources=[], ~opts={})
103
+ let eventTopics = Dict.fromArray([
104
+ ("topicX", {ReventlessInfra.EventTopic.resources: pub1.resources}),
105
+ ("topicY", {ReventlessInfra.EventTopic.resources: pub2.resources}),
106
+ ])
107
+ let ch = TestCollector.make(~name="collector", ~eventTopics, ~opts={})
108
+ let channelSpec: ReventlessCore.EventCollector_Adapter.channelSpec<JSON.t, unit, unit> = {
109
+ channel: ch,
110
+ eventTopics,
111
+ resources: [],
112
+ }
113
+ let _ = TestCollector.connect(
114
+ ~name="collector",
115
+ ~channelSpecs=[channelSpec],
116
+ ~runtime,
117
+ ~opts={},
118
+ )
119
+ // Wait for both subscriptions via the publish functions (each Output resolves per-topic)
120
+ let pub1Fn = await pub1.publishJson->TestRunner.resolve
121
+ let pub2Fn = await pub2.publishJson->TestRunner.resolve
122
+ await pub1Fn("svc", testMeta, JSON.Null)
123
+ await pub2Fn("svc", testMeta, JSON.Null)
124
+ expect(received.contents)->toBe(2)
125
+ })
126
+
127
+ testPromise("unresolved Deferred does not crash on event delivery", async () => {
128
+ module TestBus = LocalBus.Make()
129
+ module TestPublisher = LocalEventTopicPublisher.Make(TestBus)
130
+ module TestCollector = LocalEventCollectorChannel.Make(TestBus)
131
+ // Deferred left incomplete — bus callback starts a pending Effect (no crash)
132
+ let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
133
+ Deferred.make()->Effect.runSync
134
+ let runtime: ReventlessCore.Runtime.environment<LocalRuntimeEnvironment.parts> = {
135
+ parts: {
136
+ handlerDeferred,
137
+ subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
138
+ },
139
+ resources: [],
140
+ }
141
+ let pub = TestPublisher.make(~name="noHandlerTopic", ~storageResources=[], ~opts={})
142
+ let eventTopics = Dict.fromArray([
143
+ ("noHandlerTopic", {ReventlessInfra.EventTopic.resources: pub.resources}),
144
+ ])
145
+ let ch = TestCollector.make(~name="collector", ~eventTopics, ~opts={})
146
+ let channelSpec: ReventlessCore.EventCollector_Adapter.channelSpec<JSON.t, unit, unit> = {
147
+ channel: ch,
148
+ eventTopics,
149
+ resources: [],
150
+ }
151
+ let _ = TestCollector.connect(
152
+ ~name="collector",
153
+ ~channelSpecs=[channelSpec],
154
+ ~runtime,
155
+ ~opts={},
156
+ )
157
+ await runtime.parts.subscriptionLatch->Latch.await_->Effect.runPromise
158
+ let publishFn = await pub.publishJson->TestRunner.resolve
159
+ // Fire-and-forget — the Deferred.await_ will stay pending
160
+ publishFn("svc", testMeta, JSON.Null)->ignore
161
+ expect(true)->toBe(true)
162
+ // Complete the Deferred to avoid open handle
163
+ Deferred.succeed(handlerDeferred, async (_, _) => ())->Effect.runSync->ignore
164
+ })
165
+ })
166
+ })
@@ -0,0 +1,178 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Effect from "effect/Effect";
4
+ import * as Deferred from "effect/Deferred";
5
+ import * as LocalBus$ReventlessLocal from "../../src/adapter/LocalBus.res.mjs";
6
+ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
7
+ import * as LocalEventTopicPublisher$ReventlessLocal from "../../src/adapter/EventTopic/LocalEventTopicPublisher.res.mjs";
8
+ import * as LocalEventCollectorChannel$ReventlessLocal from "../../src/adapter/EventCollector/LocalEventCollectorChannel.res.mjs";
9
+
10
+ TestRunner$ReventlessLocal.setup();
11
+
12
+ let testMeta = {
13
+ service: "test",
14
+ time: "",
15
+ ip: "",
16
+ user: "test",
17
+ msgId: "",
18
+ correlationId: ""
19
+ };
20
+
21
+ function makeRuntime(handler) {
22
+ let handlerDeferred = Effect.runSync(Deferred.make());
23
+ Effect.runSync(Deferred.succeed(handlerDeferred, handler));
24
+ return {
25
+ parts: {
26
+ handlerDeferred: handlerDeferred,
27
+ subscriptionLatch: Effect.runSync(Effect.makeLatch(false))
28
+ },
29
+ resources: []
30
+ };
31
+ }
32
+
33
+ globalThis.describe("LocalEventCollectorChannel", () => {
34
+ globalThis.describe("make", () => {
35
+ globalThis.test("collects all event topic resources as channel resources", async () => {
36
+ let TestBus = LocalBus$ReventlessLocal.Make({});
37
+ let TestPublisher = LocalEventTopicPublisher$ReventlessLocal.Make(TestBus);
38
+ let TestCollector = LocalEventCollectorChannel$ReventlessLocal.Make(TestBus);
39
+ let pubA = TestPublisher.make("topicA", [], {});
40
+ let pubB = TestPublisher.make("topicB", [], {});
41
+ let eventTopics = Object.fromEntries([
42
+ [
43
+ "topicA",
44
+ {
45
+ resources: pubA.resources
46
+ }
47
+ ],
48
+ [
49
+ "topicB",
50
+ {
51
+ resources: pubB.resources
52
+ }
53
+ ]
54
+ ]);
55
+ let ch = TestCollector.make("collector", eventTopics, {});
56
+ globalThis.expect(ch.resources.length).toBe(2);
57
+ });
58
+ globalThis.test("empty eventTopics produces empty resources", async () => {
59
+ let TestBus = LocalBus$ReventlessLocal.Make({});
60
+ let TestCollector = LocalEventCollectorChannel$ReventlessLocal.Make(TestBus);
61
+ let ch = TestCollector.make("collector", {}, {});
62
+ globalThis.expect(ch.resources.length).toBe(0);
63
+ });
64
+ });
65
+ globalThis.describe("connect", () => {
66
+ globalThis.test("subscribes to event topic; published events reach the handler", async () => {
67
+ let TestBus = LocalBus$ReventlessLocal.Make({});
68
+ let TestPublisher = LocalEventTopicPublisher$ReventlessLocal.Make(TestBus);
69
+ let TestCollector = LocalEventCollectorChannel$ReventlessLocal.Make(TestBus);
70
+ let received = {
71
+ contents: 0
72
+ };
73
+ let runtime = makeRuntime(async (param, _ctx) => {
74
+ received.contents = received.contents + 1 | 0;
75
+ });
76
+ let pub = TestPublisher.make("eventA", [], {});
77
+ let eventTopics = Object.fromEntries([[
78
+ "eventA",
79
+ {
80
+ resources: pub.resources
81
+ }
82
+ ]]);
83
+ let ch = TestCollector.make("collector", eventTopics, {});
84
+ let channelSpec_resources = [];
85
+ let channelSpec = {
86
+ channel: ch,
87
+ eventTopics: eventTopics,
88
+ resources: channelSpec_resources
89
+ };
90
+ TestCollector.connect("collector", [channelSpec], runtime, {});
91
+ await Effect.runPromise(runtime.parts.subscriptionLatch.await);
92
+ let publishFn = await TestRunner$ReventlessLocal.resolve(pub.publishJson);
93
+ await publishFn("svc", testMeta, null);
94
+ globalThis.expect(received.contents).toBe(1);
95
+ });
96
+ globalThis.test("multiple event topics all deliver to the same handler", async () => {
97
+ let TestBus = LocalBus$ReventlessLocal.Make({});
98
+ let TestPublisher = LocalEventTopicPublisher$ReventlessLocal.Make(TestBus);
99
+ let TestCollector = LocalEventCollectorChannel$ReventlessLocal.Make(TestBus);
100
+ let received = {
101
+ contents: 0
102
+ };
103
+ let runtime = makeRuntime(async (param, param$1) => {
104
+ received.contents = received.contents + 1 | 0;
105
+ });
106
+ let pub1 = TestPublisher.make("topicX", [], {});
107
+ let pub2 = TestPublisher.make("topicY", [], {});
108
+ let eventTopics = Object.fromEntries([
109
+ [
110
+ "topicX",
111
+ {
112
+ resources: pub1.resources
113
+ }
114
+ ],
115
+ [
116
+ "topicY",
117
+ {
118
+ resources: pub2.resources
119
+ }
120
+ ]
121
+ ]);
122
+ let ch = TestCollector.make("collector", eventTopics, {});
123
+ let channelSpec_resources = [];
124
+ let channelSpec = {
125
+ channel: ch,
126
+ eventTopics: eventTopics,
127
+ resources: channelSpec_resources
128
+ };
129
+ TestCollector.connect("collector", [channelSpec], runtime, {});
130
+ let pub1Fn = await TestRunner$ReventlessLocal.resolve(pub1.publishJson);
131
+ let pub2Fn = await TestRunner$ReventlessLocal.resolve(pub2.publishJson);
132
+ await pub1Fn("svc", testMeta, null);
133
+ await pub2Fn("svc", testMeta, null);
134
+ globalThis.expect(received.contents).toBe(2);
135
+ });
136
+ globalThis.test("unresolved Deferred does not crash on event delivery", async () => {
137
+ let TestBus = LocalBus$ReventlessLocal.Make({});
138
+ let TestPublisher = LocalEventTopicPublisher$ReventlessLocal.Make(TestBus);
139
+ let TestCollector = LocalEventCollectorChannel$ReventlessLocal.Make(TestBus);
140
+ let handlerDeferred = Effect.runSync(Deferred.make());
141
+ let runtime_parts = {
142
+ handlerDeferred: handlerDeferred,
143
+ subscriptionLatch: Effect.runSync(Effect.makeLatch(false))
144
+ };
145
+ let runtime_resources = [];
146
+ let runtime = {
147
+ parts: runtime_parts,
148
+ resources: runtime_resources
149
+ };
150
+ let pub = TestPublisher.make("noHandlerTopic", [], {});
151
+ let eventTopics = Object.fromEntries([[
152
+ "noHandlerTopic",
153
+ {
154
+ resources: pub.resources
155
+ }
156
+ ]]);
157
+ let ch = TestCollector.make("collector", eventTopics, {});
158
+ let channelSpec_resources = [];
159
+ let channelSpec = {
160
+ channel: ch,
161
+ eventTopics: eventTopics,
162
+ resources: channelSpec_resources
163
+ };
164
+ TestCollector.connect("collector", [channelSpec], runtime, {});
165
+ await Effect.runPromise(runtime_parts.subscriptionLatch.await);
166
+ let publishFn = await TestRunner$ReventlessLocal.resolve(pub.publishJson);
167
+ publishFn("svc", testMeta, null);
168
+ globalThis.expect(true).toBe(true);
169
+ Effect.runSync(Deferred.succeed(handlerDeferred, async (param, param$1) => {}));
170
+ });
171
+ });
172
+ });
173
+
174
+ export {
175
+ testMeta,
176
+ makeRuntime,
177
+ }
178
+ /* Not a pure module */
@@ -0,0 +1,105 @@
1
+ // Round-trip test for EventLogStorage_Sqlite.
2
+ // Mirrors the shape of the Memory variant but uses an in-memory SQLite database.
3
+
4
+ open JestGlobals
5
+
6
+ let _ = TestRunner.setup()
7
+ let opts: Pulumi.CustomResourceOptions.t = {}
8
+
9
+ let makeFreshDb = () => SqliteDriver.openDb(~path=":memory:")
10
+
11
+ describe("EventLogStorage_Sqlite", () => {
12
+ testPromise("append + replay round-trips events in order", async () => {
13
+ module TestBus = LocalBus.Make()
14
+ module DbProvider = {
15
+ let db = makeFreshDb()
16
+ }
17
+ module Storage = EventLogStorage_Sqlite.Make(TestBus, DbProvider)
18
+
19
+ let s = Storage.make(~name="agg", ~opts)
20
+ let ops = await s.operations->TestRunner.resolve
21
+
22
+ let event1 = JSON.Encode.object(
23
+ Dict.fromArray([("tag", JSON.Encode.string("Created"))]),
24
+ )
25
+ let event2 = JSON.Encode.object(
26
+ Dict.fromArray([("tag", JSON.Encode.string("Renamed"))]),
27
+ )
28
+
29
+ let r1 = await ops.append(0, "id-1", [event1])
30
+ expect(r1)->toEqual(Ok())
31
+
32
+ let r2 = await ops.append(1, "id-1", [event2])
33
+ expect(r2)->toEqual(Ok())
34
+
35
+ let replayed = await ops.replay("id-1")
36
+ expect(replayed->Array.length)->toBe(2)
37
+ expect(replayed->Array.getUnsafe(0))->toEqual(event1)
38
+ expect(replayed->Array.getUnsafe(1))->toEqual(event2)
39
+ })
40
+
41
+ testPromise("append detects concurrency conflicts via PK collision", async () => {
42
+ module TestBus = LocalBus.Make()
43
+ module DbProvider = {
44
+ let db = makeFreshDb()
45
+ }
46
+ module Storage = EventLogStorage_Sqlite.Make(TestBus, DbProvider)
47
+
48
+ let s = Storage.make(~name="agg", ~opts)
49
+ let ops = await s.operations->TestRunner.resolve
50
+
51
+ let e = JSON.Encode.object(Dict.fromArray([("t", JSON.Encode.string("X"))]))
52
+ let _ = await ops.append(0, "id-c", [e])
53
+
54
+ // Caller re-uses seqNr=0 — conflict.
55
+ let result = await ops.append(0, "id-c", [e])
56
+ switch result {
57
+ | Error(_) => expect(true)->toBe(true)
58
+ | Ok() => expect("expected conflict")->toBe("actual Ok")
59
+ }
60
+ })
61
+
62
+ testPromise("replay returns empty array for unknown id", async () => {
63
+ module TestBus = LocalBus.Make()
64
+ module DbProvider = {
65
+ let db = makeFreshDb()
66
+ }
67
+ module Storage = EventLogStorage_Sqlite.Make(TestBus, DbProvider)
68
+
69
+ let s = Storage.make(~name="agg", ~opts)
70
+ let ops = await s.operations->TestRunner.resolve
71
+
72
+ let replayed = await ops.replay("not-there")
73
+ expect(replayed->Array.length)->toBe(0)
74
+ })
75
+
76
+ testPromise("events persist across a reopen of the database file", async () => {
77
+ let path = `/tmp/reventless-test-eventlog-${Float.toString(Date.now())}.db`
78
+
79
+ // Session 1: write
80
+ {
81
+ module TestBus = LocalBus.Make()
82
+ module DbProvider = {
83
+ let db = SqliteDriver.openDb(~path)
84
+ }
85
+ module Storage = EventLogStorage_Sqlite.Make(TestBus, DbProvider)
86
+ let s = Storage.make(~name="persist", ~opts)
87
+ let ops = await s.operations->TestRunner.resolve
88
+ let ev = JSON.Encode.object(Dict.fromArray([("v", JSON.Encode.int(42))]))
89
+ let _ = await ops.append(0, "id-p", [ev])
90
+ DbProvider.db->SqliteDriver.close
91
+ }
92
+
93
+ // Session 2: read back
94
+ module TestBus2 = LocalBus.Make()
95
+ module DbProvider2 = {
96
+ let db = SqliteDriver.openDb(~path)
97
+ }
98
+ module Storage2 = EventLogStorage_Sqlite.Make(TestBus2, DbProvider2)
99
+ let s2 = Storage2.make(~name="persist", ~opts)
100
+ let ops2 = await s2.operations->TestRunner.resolve
101
+ let replayed = await ops2.replay("id-p")
102
+ expect(replayed->Array.length)->toBe(1)
103
+ DbProvider2.db->SqliteDriver.close
104
+ })
105
+ })
@@ -0,0 +1,116 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as LocalBus$ReventlessLocal from "../../src/adapter/LocalBus.res.mjs";
4
+ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
5
+ import * as SqliteDriver$ReventlessLocal from "../../src/adapter/SqliteDriver.res.mjs";
6
+ import * as EventLogStorage_Sqlite$ReventlessLocal from "../../src/adapter/EventLog/EventLogStorage_Sqlite.res.mjs";
7
+
8
+ TestRunner$ReventlessLocal.setup();
9
+
10
+ let opts = {};
11
+
12
+ function makeFreshDb() {
13
+ return SqliteDriver$ReventlessLocal.openDb(":memory:");
14
+ }
15
+
16
+ globalThis.describe("EventLogStorage_Sqlite", () => {
17
+ globalThis.test("append + replay round-trips events in order", async () => {
18
+ let TestBus = LocalBus$ReventlessLocal.Make({});
19
+ let db = SqliteDriver$ReventlessLocal.openDb(":memory:");
20
+ let DbProvider = {
21
+ db: db
22
+ };
23
+ let Storage = EventLogStorage_Sqlite$ReventlessLocal.Make(TestBus)(DbProvider);
24
+ let s = Storage.make("agg", opts);
25
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
26
+ let event1 = Object.fromEntries([[
27
+ "tag",
28
+ "Created"
29
+ ]]);
30
+ let event2 = Object.fromEntries([[
31
+ "tag",
32
+ "Renamed"
33
+ ]]);
34
+ let r1 = await ops.append(0, "id-1", [event1]);
35
+ globalThis.expect(r1).toEqual({
36
+ TAG: "Ok",
37
+ _0: undefined
38
+ });
39
+ let r2 = await ops.append(1, "id-1", [event2]);
40
+ globalThis.expect(r2).toEqual({
41
+ TAG: "Ok",
42
+ _0: undefined
43
+ });
44
+ let replayed = await ops.replay("id-1");
45
+ globalThis.expect(replayed.length).toBe(2);
46
+ globalThis.expect(replayed[0]).toEqual(event1);
47
+ globalThis.expect(replayed[1]).toEqual(event2);
48
+ });
49
+ globalThis.test("append detects concurrency conflicts via PK collision", async () => {
50
+ let TestBus = LocalBus$ReventlessLocal.Make({});
51
+ let db = SqliteDriver$ReventlessLocal.openDb(":memory:");
52
+ let DbProvider = {
53
+ db: db
54
+ };
55
+ let Storage = EventLogStorage_Sqlite$ReventlessLocal.Make(TestBus)(DbProvider);
56
+ let s = Storage.make("agg", opts);
57
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
58
+ let e = Object.fromEntries([[
59
+ "t",
60
+ "X"
61
+ ]]);
62
+ await ops.append(0, "id-c", [e]);
63
+ let result = await ops.append(0, "id-c", [e]);
64
+ if (result.TAG === "Ok") {
65
+ globalThis.expect("expected conflict").toBe("actual Ok");
66
+ return;
67
+ }
68
+ globalThis.expect(true).toBe(true);
69
+ });
70
+ globalThis.test("replay returns empty array for unknown id", async () => {
71
+ let TestBus = LocalBus$ReventlessLocal.Make({});
72
+ let db = SqliteDriver$ReventlessLocal.openDb(":memory:");
73
+ let DbProvider = {
74
+ db: db
75
+ };
76
+ let Storage = EventLogStorage_Sqlite$ReventlessLocal.Make(TestBus)(DbProvider);
77
+ let s = Storage.make("agg", opts);
78
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
79
+ let replayed = await ops.replay("not-there");
80
+ globalThis.expect(replayed.length).toBe(0);
81
+ });
82
+ globalThis.test("events persist across a reopen of the database file", async () => {
83
+ let path = `/tmp/reventless-test-eventlog-` + Date.now().toString() + `.db`;
84
+ let TestBus = LocalBus$ReventlessLocal.Make({});
85
+ let db = SqliteDriver$ReventlessLocal.openDb(path);
86
+ let DbProvider = {
87
+ db: db
88
+ };
89
+ let Storage = EventLogStorage_Sqlite$ReventlessLocal.Make(TestBus)(DbProvider);
90
+ let s = Storage.make("persist", opts);
91
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
92
+ let ev = Object.fromEntries([[
93
+ "v",
94
+ 42
95
+ ]]);
96
+ await ops.append(0, "id-p", [ev]);
97
+ SqliteDriver$ReventlessLocal.close(db);
98
+ let TestBus2 = LocalBus$ReventlessLocal.Make({});
99
+ let db$1 = SqliteDriver$ReventlessLocal.openDb(path);
100
+ let DbProvider2 = {
101
+ db: db$1
102
+ };
103
+ let Storage2 = EventLogStorage_Sqlite$ReventlessLocal.Make(TestBus2)(DbProvider2);
104
+ let s2 = Storage2.make("persist", opts);
105
+ let ops2 = await TestRunner$ReventlessLocal.resolve(s2.operations);
106
+ let replayed = await ops2.replay("id-p");
107
+ globalThis.expect(replayed.length).toBe(1);
108
+ return SqliteDriver$ReventlessLocal.close(db$1);
109
+ });
110
+ });
111
+
112
+ export {
113
+ opts,
114
+ makeFreshDb,
115
+ }
116
+ /* Not a pure module */
@@ -0,0 +1,102 @@
1
+ // Tests for the opt-in NDJSON domain-event tap (features plan Phase 9 — the VS
2
+ // Code local platform runner). The tap lives in LocalBus.publishEvent: when
3
+ // REVENTLESS_EVENT_TAP is set it emits one sentinel-prefixed JSON line per
4
+ // published event to stdout (console.log), with the event's real topic name and
5
+ // payload. Off by default so normal runs stay quiet.
6
+
7
+ open JestGlobals
8
+
9
+ let _ = TestRunner.setup()
10
+
11
+ let defaultMeta: Reventless.Message.meta = {
12
+ service: "test",
13
+ time: "",
14
+ ip: "",
15
+ user: "test",
16
+ msgId: "",
17
+ correlationId: "",
18
+ }
19
+
20
+ @val external processEnv: Dict.t<string> = "process.env"
21
+
22
+ type consoleObj = {mutable log: string => unit}
23
+ @val external console: consoleObj = "console"
24
+
25
+ let sentinel = "@@RVLESS_EVT@@ "
26
+
27
+ // Run `fn` with console.log captured; returns every logged line, restoring the
28
+ // original console.log even if `fn` throws.
29
+ let captureLogs = async (fn: unit => promise<unit>): array<string> => {
30
+ let captured: array<string> = []
31
+ let original = console.log
32
+ console.log = s => captured->Array.push(s)
33
+ let result = try {
34
+ await fn()
35
+ Ok()
36
+ } catch {
37
+ | e => Error(e)
38
+ }
39
+ console.log = original
40
+ switch result {
41
+ | Ok() => captured
42
+ | Error(e) => throw(e)
43
+ }
44
+ }
45
+
46
+ let tapLines = (logs: array<string>): array<string> =>
47
+ logs->Array.filter(l => l->String.startsWith(sentinel))
48
+
49
+ describe("LocalBus event tap (Phase 9)", () => {
50
+ // Each test owns the env flag; always clear it afterwards so cases don't leak.
51
+ let clearEnv = () => processEnv->Dict.delete("REVENTLESS_EVENT_TAP")
52
+
53
+ testPromise("tap off → no sentinel line is emitted", async () => {
54
+ clearEnv()
55
+ module TestBus = LocalBus.MakeSilent()
56
+ let logs = await captureLogs(async () => {
57
+ await TestBus.publishEvent("SomeTopic", "svc", defaultMeta, JSON.parseOrThrow(`{"a":1}`))
58
+ })
59
+ expect(tapLines(logs)->Array.length)->toBe(0)
60
+ })
61
+
62
+ testPromise("tap on → one well-formed line per published event", async () => {
63
+ processEnv->Dict.set("REVENTLESS_EVENT_TAP", "ndjson")
64
+ module TestBus = LocalBus.MakeSilent()
65
+ let logs = await captureLogs(async () => {
66
+ await TestBus.publishEvent(
67
+ "CatalogEventTopic",
68
+ "CatalogDcbEventLog",
69
+ defaultMeta,
70
+ JSON.parseOrThrow(`{"event":{"TAG":"ProductAdded","productId":"p-1"}}`),
71
+ )
72
+ await TestBus.publishEvent("OrderingEventTopic", "svc", defaultMeta, JSON.parseOrThrow(`{}`))
73
+ })
74
+ clearEnv()
75
+ let lines = tapLines(logs)
76
+ expect(lines->Array.length)->toBe(2)
77
+
78
+ // First line decodes to the expected envelope: event="domainEvent", the real
79
+ // topic name, and the payload passed to publishEvent (no topic-name guessing).
80
+ let first = lines->Array.getUnsafe(0)
81
+ let json =
82
+ first->String.slice(~start=sentinel->String.length, ~end=first->String.length)->JSON.parseOrThrow
83
+ let obj = json->JSON.Decode.object->Option.getOrThrow
84
+ expect(obj->Dict.get("event")->Option.flatMap(JSON.Decode.string))->toEqual(Some("domainEvent"))
85
+ expect(obj->Dict.get("topic")->Option.flatMap(JSON.Decode.string))->toEqual(
86
+ Some("CatalogEventTopic"),
87
+ )
88
+ expect(obj->Dict.get("seq")->Option.flatMap(JSON.Decode.float))->toEqual(Some(1.0))
89
+ expect(obj->Dict.get("payload")->Option.isSome)->toBe(true)
90
+ })
91
+
92
+ testPromise("tap emits even when the topic has no subscribers", async () => {
93
+ processEnv->Dict.set("REVENTLESS_EVENT_TAP", "ndjson")
94
+ module TestBus = LocalBus.MakeSilent()
95
+ let logs = await captureLogs(async () => {
96
+ // No subscribeToEvents call — the tap fires before the subscriber-count gate.
97
+ await TestBus.publishEvent("Lonely", "svc", defaultMeta, JSON.Null)
98
+ })
99
+ clearEnv()
100
+ expect(tapLines(logs)->Array.length)->toBe(1)
101
+ })
102
+ })