@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,76 @@
1
+ // GraphQL mutation resolvers for in-memory InboundTranslationSlices.
2
+ // Registers one GraphQL mutation field per InboundTranslationSlice.
3
+ // Each resolver calls `receive(argsJson)` directly — the InboundTranslationSlice
4
+ // handles parsing, validation, translation, and command publishing internally.
5
+
6
+ @@warning("-44")
7
+ open ReventlessCore
8
+
9
+ // Mutable registry: fieldName → receive function.
10
+ // Pre-populated synchronously in Phase 1 via a queuing forwarder so callers
11
+ // (e.g. PlatformInspector's onPlatformDeployedHook) can invoke receive before
12
+ // Phase 2 bindReceive runs. Calls park in a Promise queue and drain once bound.
13
+ let receiveRegistry: dict<JSON.t => promise<result<array<string>, string>>> = Dict.make()
14
+
15
+ type pendingCall = {
16
+ inputJson: JSON.t,
17
+ resolve: result<array<string>, string> => unit,
18
+ }
19
+
20
+ // Per-field pending-call queues — drained when bindReceive fires.
21
+ let pendingQueueRegistry: dict<ref<array<pendingCall>>> = Dict.make()
22
+
23
+ // Phase 1: Register SDL + resolver stub synchronously (before server starts).
24
+ // Also pre-registers a queuing forwarder in receiveRegistry so callers can
25
+ // invoke receive immediately; calls are parked until bindReceive drains them.
26
+ let register = (~fieldName: string, ~externalInputSchema: S.t<unknown>, ~server: GraphQL_ServerInstance.t) => {
27
+ let sdlFields = switch GraphQL_FragmentGenerator.deriveMutationFieldFromObject(
28
+ ~fieldName,
29
+ ~collectedTypes=[],
30
+ ~seenTypes=Set.make(),
31
+ externalInputSchema,
32
+ ) {
33
+ | Some(field) => [field]
34
+ | None => [` ${fieldName}: String!`]
35
+ }
36
+
37
+ // Queue of pending calls when receive is not yet bound.
38
+ let pendingQueue: ref<array<pendingCall>> = ref([])
39
+ pendingQueueRegistry->Dict.set(fieldName, pendingQueue)
40
+
41
+ // Queuing forwarder: parks calls until bindReceive populates receiveRegistry.
42
+ let queuingReceive = (inputJson: JSON.t) =>
43
+ Promise.make((resolve, _reject) => {
44
+ pendingQueue.contents->Array.push({inputJson, resolve})
45
+ })
46
+ receiveRegistry->Dict.set(fieldName, queuingReceive)
47
+
48
+ let resolver: GraphQL_ServerInstance.resolverFn = async (_root, args, _ctx) => {
49
+ let inputJson: JSON.t = args->Obj.magic
50
+ let receive = receiveRegistry->Dict.getUnsafe(fieldName)
51
+ let result = await receive(inputJson)
52
+ switch result {
53
+ | Ok(targetIds) => targetIds->Array.map(JSON.Encode.string)->JSON.Encode.array
54
+ | Error(msg) => msg->JSON.Encode.string
55
+ }
56
+ }
57
+
58
+ let resolvers = Dict.make()
59
+ resolvers->Dict.set(fieldName, resolver)
60
+ server.registerMutations(~sdlFields, ~resolvers)
61
+ }
62
+
63
+ // Phase 2: Bind the real receive function once Output.apply resolves.
64
+ // Replaces the queuing forwarder in receiveRegistry and drains pending calls.
65
+ let bindReceive = (~fieldName: string, ~receive: JSON.t => promise<result<array<string>, string>>) => {
66
+ receiveRegistry->Dict.set(fieldName, receive)
67
+ switch pendingQueueRegistry->Dict.get(fieldName) {
68
+ | Some(pendingQueue) =>
69
+ let pending = pendingQueue.contents
70
+ pendingQueue.contents = []
71
+ pending->Array.forEach(({inputJson, resolve}) => {
72
+ let _ = receive(inputJson)->Promise.thenResolve(result => resolve(result))
73
+ })
74
+ | None => ()
75
+ }
76
+ }
@@ -0,0 +1,57 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as GraphQL_FragmentGenerator$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_FragmentGenerator.res.mjs";
4
+
5
+ let receiveRegistry = {};
6
+
7
+ let pendingQueueRegistry = {};
8
+
9
+ function register(fieldName, externalInputSchema, server) {
10
+ let field = GraphQL_FragmentGenerator$ReventlessCore.deriveMutationFieldFromObject(fieldName, [], new Set(), externalInputSchema);
11
+ let sdlFields = field !== undefined ? [field] : [` ` + fieldName + `: String!`];
12
+ let pendingQueue = {
13
+ contents: []
14
+ };
15
+ pendingQueueRegistry[fieldName] = pendingQueue;
16
+ let queuingReceive = inputJson => new Promise((resolve, _reject) => {
17
+ pendingQueue.contents.push({
18
+ inputJson: inputJson,
19
+ resolve: resolve
20
+ });
21
+ });
22
+ receiveRegistry[fieldName] = queuingReceive;
23
+ let resolver = async (_root, args, _ctx) => {
24
+ let receive = receiveRegistry[fieldName];
25
+ let result = await receive(args);
26
+ if (result.TAG === "Ok") {
27
+ return result._0.map(prim => prim);
28
+ } else {
29
+ return result._0;
30
+ }
31
+ };
32
+ let resolvers = {};
33
+ resolvers[fieldName] = resolver;
34
+ server.registerMutations(sdlFields, resolvers);
35
+ }
36
+
37
+ function bindReceive(fieldName, receive) {
38
+ receiveRegistry[fieldName] = receive;
39
+ let pendingQueue = pendingQueueRegistry[fieldName];
40
+ if (pendingQueue === undefined) {
41
+ return;
42
+ }
43
+ let pending = pendingQueue.contents;
44
+ pendingQueue.contents = [];
45
+ pending.forEach(param => {
46
+ let resolve = param.resolve;
47
+ receive(param.inputJson).then(result => resolve(result));
48
+ });
49
+ }
50
+
51
+ export {
52
+ receiveRegistry,
53
+ pendingQueueRegistry,
54
+ register,
55
+ bindReceive,
56
+ }
57
+ /* GraphQL_FragmentGenerator-ReventlessCore Not a pure module */
@@ -0,0 +1,19 @@
1
+ // No-op CommandGenerator resolvers for in-memory (no AppSync).
2
+
3
+ open ReventlessCore
4
+
5
+ type api = unit
6
+ type runtimeParts = LocalRuntimeEnvironment.parts
7
+
8
+ let handleResolversEvent = (generateCommand: CommandGenerator.commandGenerator) =>
9
+ Pulumi.Output.make((event, _context) => event->generateCommand)
10
+
11
+ let make: CommandGenerator_Adapter.resolversMaker<unit, runtimeParts> = (
12
+ ~name as _,
13
+ ~api as _,
14
+ ~fields as _,
15
+ ~commandSchema as _,
16
+ ~runtime as _,
17
+ ~resources as _,
18
+ ~opts as _,
19
+ ) => {resources: []}
@@ -0,0 +1,19 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Pulumi from "@pulumi/pulumi";
4
+
5
+ function handleResolversEvent(generateCommand) {
6
+ return Pulumi.output((event, _context) => generateCommand(event));
7
+ }
8
+
9
+ function make(param, param$1, param$2, param$3, param$4, param$5, param$6) {
10
+ return {
11
+ resources: []
12
+ };
13
+ }
14
+
15
+ export {
16
+ handleResolversEvent,
17
+ make,
18
+ }
19
+ /* @pulumi/pulumi Not a pure module */
@@ -0,0 +1,104 @@
1
+ // In-memory CommandTopic channel.
2
+ // publishJsons encodes each command as {id, meta, command} (full message body) and dispatches via Bus.
3
+ // connect wires the channel to the runtime handler via Bus.registerCommandHandler.
4
+ // The full body format matches what CommandTopic_Callback.handleJsonCommands expects to decode.
5
+
6
+ module Make = (Bus: LocalBus.T) => {
7
+ type callbackEvent = JSON.t
8
+ type runtimeParts = LocalRuntimeEnvironment.parts
9
+ type channelParts = {name: string}
10
+
11
+ // Extract aggregate id (used as reference) from the full message body
12
+ let decodeId = (body: JSON.t): string =>
13
+ switch body {
14
+ | JSON.Object(d) =>
15
+ d
16
+ ->Dict.get("id")
17
+ ->Option.flatMap(j =>
18
+ switch j {
19
+ | JSON.String(s) => Some(s)
20
+ | _ => None
21
+ }
22
+ )
23
+ ->Option.getOr("")
24
+ | _ => ""
25
+ }
26
+
27
+ let make: ReventlessCore.CommandTopic_Adapter.channelMaker<
28
+ callbackEvent,
29
+ 'context,
30
+ channelParts,
31
+ runtimeParts,
32
+ > = (~name, ~opts as _=?) => {
33
+ // Captured when handleChannelEvent is called; used by publishJsonsAndWait to
34
+ // run the handler inline and collect typed outcomes without going through the bus.
35
+ let handleCmdsRef: ref<
36
+ option<ReventlessCore.CommandTopic.jsonCommandsHandler>,
37
+ > = ref(None)
38
+
39
+ let publishJsons: ReventlessInfra.CommandTopic.publishJsons = async jsons => {
40
+ let _ =
41
+ await jsons
42
+ ->Array.map(async (cmdJson: Reventless.Message.commandJson) => {
43
+ await Bus.dispatchCommand(name, ReventlessCore.CommandTopic.encodeCommandJson(cmdJson))
44
+ })
45
+ ->Promise.all
46
+ }
47
+
48
+ let publishJsonsStream: ReventlessInfra.CommandTopic.publishJsonsStream = stream =>
49
+ stream
50
+ ->Stream.grouped(10)
51
+ ->Stream.runForEach(jsons => Effect.promise(() => publishJsons(jsons)))
52
+
53
+ let publishJsonsAndWait: ReventlessCore.CommandTopic.publishJsonsAndWait = async jsons => {
54
+ switch handleCmdsRef.contents {
55
+ | None =>
56
+ // Handler not yet registered — fall back to fire-and-forget, return Pending
57
+ let _ = await publishJsons(jsons)
58
+ jsons->Array.map(cmdJson =>
59
+ ReventlessCore.CommandTopic.Pending({msgId: cmdJson.meta.msgId})
60
+ )
61
+ | Some(handleCmds) =>
62
+ await ReventlessCore.CommandTopic.runInlineAndCollect(jsons, handleCmds)
63
+ }
64
+ }
65
+
66
+ let handleChannelEvent = (
67
+ handleCmds: ReventlessCore.CommandTopic.jsonCommandsHandler,
68
+ ): Pulumi.Output.t<ReventlessCore.Runtime.effectHandler<callbackEvent, 'context, unit, string>> => {
69
+ handleCmdsRef.contents = Some(handleCmds)
70
+ (
71
+ (fullBody: JSON.t, _ctx) => {
72
+ // Pass the full body as `command` — that's what handleJsonCommands decodes
73
+ let reference = decodeId(fullBody)
74
+ let item: ReventlessInfra.CommandTopic.topicItem<JSON.t> = {command: fullBody, reference}
75
+ handleCmds(Stream.fromIterable([item]))->Effect.map(_ => ())
76
+ }
77
+ )->Pulumi.Output.make
78
+ }
79
+
80
+ let connect: ReventlessCore.CommandTopic_Adapter.connect<
81
+ callbackEvent,
82
+ 'context,
83
+ channelParts,
84
+ runtimeParts,
85
+ > = (~name as _, ~channel, ~runtime, ~resources as _, ~opts as _) => {
86
+ Bus.registerCommandHandler(channel.parts.name, async (json, ctx) => {
87
+ let handler =
88
+ await runtime.parts.handlerDeferred->Deferred.await_->Effect.runPromise
89
+ await handler(json, ctx)
90
+ })
91
+ []
92
+ }
93
+
94
+ {
95
+ parts: {name: name},
96
+ resources: [],
97
+ publishJsons: publishJsons->Pulumi.Output.make,
98
+ publishJsonsStream: publishJsonsStream->Pulumi.Output.make,
99
+ publishJsonsAndWait: Some(publishJsonsAndWait)->Pulumi.Output.make,
100
+ handleChannelEvent,
101
+ connect,
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,82 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
4
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Stream$1 from "effect/Stream";
7
+ import * as Pulumi from "@pulumi/pulumi";
8
+ import * as Deferred from "effect/Deferred";
9
+ import * as CommandTopic$ReventlessCore from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic.res.mjs";
10
+
11
+ function Make(Bus) {
12
+ let decodeId = body => {
13
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
14
+ return Stdlib_Option.getOr(Stdlib_Option.flatMap(body["id"], j => {
15
+ if (typeof j === "string") {
16
+ return j;
17
+ }
18
+ }), "");
19
+ } else {
20
+ return "";
21
+ }
22
+ };
23
+ let make = (name, param) => {
24
+ let handleCmdsRef = {
25
+ contents: undefined
26
+ };
27
+ let publishJsons = async jsons => {
28
+ await Promise.all(jsons.map(async cmdJson => await Bus.dispatchCommand(name, CommandTopic$ReventlessCore.encodeCommandJson(cmdJson))));
29
+ };
30
+ let publishJsonsStream = stream => Stream$1.runForEach(Stream.grouped(stream, 10), jsons => Effect.promise(() => publishJsons(jsons)));
31
+ let publishJsonsAndWait = async jsons => {
32
+ let handleCmds = handleCmdsRef.contents;
33
+ if (handleCmds !== undefined) {
34
+ return await CommandTopic$ReventlessCore.runInlineAndCollect(jsons, handleCmds);
35
+ } else {
36
+ await publishJsons(jsons);
37
+ return jsons.map(cmdJson => ({
38
+ TAG: "Pending",
39
+ msgId: cmdJson.meta.msgId
40
+ }));
41
+ }
42
+ };
43
+ let handleChannelEvent = handleCmds => {
44
+ handleCmdsRef.contents = handleCmds;
45
+ return Pulumi.output((fullBody, _ctx) => {
46
+ let reference = decodeId(fullBody);
47
+ let item = {
48
+ command: fullBody,
49
+ reference: reference
50
+ };
51
+ return Effect.map(handleCmds(Stream$1.fromIterable([item])), param => {});
52
+ });
53
+ };
54
+ let connect = (param, channel, runtime, param$1, param$2) => {
55
+ Bus.registerCommandHandler(channel.parts.name, async (json, ctx) => {
56
+ let handler = await Effect.runPromise(Deferred.await(runtime.parts.handlerDeferred));
57
+ return await handler(json, ctx);
58
+ });
59
+ return [];
60
+ };
61
+ return {
62
+ parts: {
63
+ name: name
64
+ },
65
+ resources: [],
66
+ publishJsons: Pulumi.output(publishJsons),
67
+ publishJsonsStream: Pulumi.output(publishJsonsStream),
68
+ publishJsonsAndWait: Pulumi.output(publishJsonsAndWait),
69
+ handleChannelEvent: handleChannelEvent,
70
+ connect: connect
71
+ };
72
+ };
73
+ return {
74
+ decodeId: decodeId,
75
+ make: make
76
+ };
77
+ }
78
+
79
+ export {
80
+ Make,
81
+ }
82
+ /* Stream Not a pure module */
@@ -0,0 +1,32 @@
1
+ // In-memory CommandTopic remote channel — satisfies CommandTopic_Adapter.RemoteChannel.
2
+ // Dispatches "remote" commands directly to the in-memory Bus.
3
+
4
+ module Make = (Bus: LocalBus.T) => {
5
+ let make: ReventlessCore.CommandTopic_Adapter.remoteChannelMaker = resources => {
6
+ resources,
7
+ remotePublish: async jsons => {
8
+ let _ =
9
+ await jsons
10
+ ->Array.map(async (cmdJson: Reventless.Message.commandJson) => {
11
+ // Encode the same way LocalCommandTopicChannel does
12
+ let body = JSON.Encode.object(
13
+ Dict.fromArray([
14
+ ("id", JSON.Encode.string(cmdJson.id)),
15
+ (
16
+ "meta",
17
+ cmdJson.meta->S.reverseConvertToJsonOrThrow(Reventless.Message.metaSchema),
18
+ ),
19
+ ("command", cmdJson.commandJson),
20
+ ]),
21
+ )
22
+ // Dispatch to the first resource's name (the channel name)
23
+ let channelName = switch resources {
24
+ | [] => ""
25
+ | resources => (resources->Array.getUnsafe(0)).name
26
+ }
27
+ await Bus.dispatchCommand(channelName, body)
28
+ })
29
+ ->Promise.all
30
+ },
31
+ }
32
+ }
@@ -0,0 +1,38 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
5
+
6
+ function Make(Bus) {
7
+ let make = resources => ({
8
+ resources: resources,
9
+ remotePublish: async jsons => {
10
+ await Promise.all(jsons.map(async cmdJson => {
11
+ let body = Object.fromEntries([
12
+ [
13
+ "id",
14
+ cmdJson.id
15
+ ],
16
+ [
17
+ "meta",
18
+ S.reverseConvertToJsonOrThrow(cmdJson.meta, Message$Reventless.metaSchema)
19
+ ],
20
+ [
21
+ "command",
22
+ cmdJson.commandJson
23
+ ]
24
+ ]);
25
+ let channelName = resources.length !== 0 ? resources[0].name : "";
26
+ return await Bus.dispatchCommand(channelName, body);
27
+ }));
28
+ }
29
+ });
30
+ return {
31
+ make: make
32
+ };
33
+ }
34
+
35
+ export {
36
+ Make,
37
+ }
38
+ /* S Not a pure module */
@@ -0,0 +1,42 @@
1
+ // In-memory counter handler — tracks counter values in module-level dicts.
2
+ // Deduplicates: a given (counterId, targetRef) pair is only counted once.
3
+ //
4
+ // Call LocalCounterHandler.reset() in beforeEach to isolate tests.
5
+
6
+ open ReventlessCore
7
+
8
+ let counterStore: ref<dict<int>> = ref(Dict.make())
9
+ let targetRefStore: ref<dict<bool>> = ref(Dict.make())
10
+
11
+ let make: Counter_Adapter.handlerMaker = (
12
+ ~name as _,
13
+ ~referencesName as _,
14
+ ~referencesDb as _,
15
+ ~countsName as _,
16
+ ~countsDb as _,
17
+ ~counterHandler as _,
18
+ ~specModulePath as _,
19
+ ~mappingsModulePath as _,
20
+ ~publishChannelId as _,
21
+ ~opts as _,
22
+ ) => {
23
+ addToCounterTarget: async ({ReventlessInfra.Counter.counterId, target, targetRef}) => {
24
+ let refKey = counterId ++ ":" ++ targetRef
25
+ switch targetRefStore.contents->Dict.get(refKey) {
26
+ | Some(_) => () // Already counted this (counterId, targetRef) pair — skip
27
+ | None =>
28
+ targetRefStore.contents->Dict.set(refKey, true)
29
+ let current = counterStore.contents->Dict.get(counterId)->Option.getOr(0)
30
+ counterStore.contents->Dict.set(counterId, current + target)
31
+ }
32
+ },
33
+ }
34
+
35
+ // Returns the current count for a given counterId.
36
+ let getCount = counterId => counterStore.contents->Dict.get(counterId)->Option.getOr(0)
37
+
38
+ // Reset all counters — call in beforeEach for test isolation.
39
+ let reset = () => {
40
+ counterStore.contents = Dict.make()
41
+ targetRefStore.contents = Dict.make()
42
+ }
@@ -0,0 +1,45 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
+
5
+ let counterStore = {
6
+ contents: {}
7
+ };
8
+
9
+ let targetRefStore = {
10
+ contents: {}
11
+ };
12
+
13
+ function make(param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) {
14
+ return {
15
+ addToCounterTarget: async param => {
16
+ let counterId = param.counterId;
17
+ let refKey = counterId + ":" + param.targetRef;
18
+ let match = targetRefStore.contents[refKey];
19
+ if (match !== undefined) {
20
+ return;
21
+ }
22
+ targetRefStore.contents[refKey] = true;
23
+ let current = Stdlib_Option.getOr(counterStore.contents[counterId], 0);
24
+ counterStore.contents[counterId] = current + param.target | 0;
25
+ }
26
+ };
27
+ }
28
+
29
+ function getCount(counterId) {
30
+ return Stdlib_Option.getOr(counterStore.contents[counterId], 0);
31
+ }
32
+
33
+ function reset() {
34
+ counterStore.contents = {};
35
+ targetRefStore.contents = {};
36
+ }
37
+
38
+ export {
39
+ counterStore,
40
+ targetRefStore,
41
+ make,
42
+ getCount,
43
+ reset,
44
+ }
45
+ /* No side effect */
@@ -0,0 +1,131 @@
1
+ // In-memory DCB event log storage.
2
+ // Mirrors the mock storage in packages/reventless/tests/dcb/DcbFixtures.res
3
+
4
+ open ReventlessCore
5
+
6
+ let posToInt = (pos: string) => pos->Int.fromString->Option.getOr(0)
7
+
8
+ let matchesQuery = (event: DcbEventLog_Adapter.rawSequencedEvent, query: Reventless.DcbTag.query) =>
9
+ if query->Array.length == 0 {
10
+ true
11
+ } else {
12
+ query->Array.some(queryItem => {
13
+ let typeMatch = switch queryItem.eventTypes {
14
+ | Some(types) => types->Array.includes(event.eventType)
15
+ | None => true
16
+ }
17
+ let tagMatch = switch queryItem.tags {
18
+ | Some(tags) =>
19
+ tags->Array.every(tag =>
20
+ event.tags->Array.some(et => et.key == tag.key && et.value == tag.value)
21
+ )
22
+ | None => true
23
+ }
24
+ typeMatch && tagMatch
25
+ })
26
+ }
27
+
28
+ let makeStorage = (~name as _name, ~indexes as _, ~partitionTag as _, ~opts as _) => {
29
+ let events: ref<array<DcbEventLog_Adapter.rawSequencedEvent>> = ref([])
30
+ let position = ref(0)
31
+
32
+ let read = async (~query, ~after=?) => {
33
+ let filtered = events.contents->Array.filter(event => {
34
+ let afterMatch = switch after {
35
+ | Some(afterPos) => event.position->posToInt > afterPos->posToInt
36
+ | None => true
37
+ }
38
+ afterMatch && matchesQuery(event, query)
39
+ })
40
+ let headPosition =
41
+ events.contents
42
+ ->Array.get(events.contents->Array.length - 1)
43
+ ->Option.map(e => e.position)
44
+ {
45
+ DcbEventLog_Adapter.events: filtered,
46
+ ?headPosition,
47
+ }
48
+ }
49
+
50
+ let append = async (newEvents, ~condition=?) => {
51
+ let conflictDetected = switch condition {
52
+ | Some(cond: Reventless.DcbTag.appendCondition) =>
53
+ events.contents->Array.some(event => {
54
+ let afterMatch = switch cond.after {
55
+ | Some(pos) => event.position->posToInt > pos->posToInt
56
+ | None => true
57
+ }
58
+ afterMatch && matchesQuery(event, cond.query)
59
+ })
60
+ | None => false
61
+ }
62
+ if conflictDetected {
63
+ Error("conflict: condition check failed")
64
+ } else {
65
+ let storedEvents =
66
+ newEvents->Array.map((event: DcbEventLog_Adapter.rawStoredEvent) => {
67
+ position := position.contents + 1
68
+ let pos = position.contents->Int.toString
69
+ {
70
+ DcbEventLog_Adapter.position: pos,
71
+ eventType: event.eventType,
72
+ data: event.data,
73
+ tags: event.tags,
74
+ meta: event.meta,
75
+ recordedAt: Message.nowAsISOString(),
76
+ }
77
+ })
78
+ events := events.contents->Array.concat(storedEvents)
79
+ Ok(position.contents->Int.toString)
80
+ }
81
+ }
82
+
83
+ // ~strongConsistency is a DynamoDB read-replica concept; the in-memory backend
84
+ // is always consistent, so it is accepted (interface parity) and ignored.
85
+ let readStream = (~query, ~after=?, ~strongConsistency as _=?) =>
86
+ Effect.promise(() => read(~query, ~after?))
87
+ ->Effect.map(result => result.events)
88
+ ->Stream.fromEffect
89
+ ->Stream.flatMap(arr => Stream.fromIterable(arr))
90
+
91
+ (
92
+ _name,
93
+ read,
94
+ {
95
+ DcbEventLog_Adapter.resources: [],
96
+ operations: Pulumi.Output.make({DcbEventLog_Adapter.read, append, readStream}),
97
+ },
98
+ )
99
+ }
100
+
101
+ // Local backends evaluate the DCB condition literally against the event list
102
+ // (true DCB semantics), so a single-tag clause already matches every carrier of
103
+ // the tag regardless of partition — cross-partition reads work without special
104
+ // routing. The flag is accepted for interface parity and ignored.
105
+ let make: DcbEventLog_Adapter.storageMaker = (~name, ~indexes, ~partitionTag, ~crossPartitionTagKeys as _=?, ~opts) => {
106
+ let (_, _, storage) = makeStorage(~name, ~indexes, ~partitionTag, ~opts)
107
+ storage
108
+ }
109
+
110
+ module Make = (Bus: LocalBus.T) => {
111
+ let make: DcbEventLog_Adapter.storageMaker = (~name, ~indexes, ~partitionTag, ~crossPartitionTagKeys as _=?, ~opts) => {
112
+ switch BackendState.getDb() {
113
+ | Some(db) =>
114
+ let (storageName, read, storage) = DcbEventLogStorage_Sqlite.makeStorage(
115
+ ~db,
116
+ ~bus=(_, _) => (),
117
+ ~publishToTopic=(~topicName as _, ~json as _) => (),
118
+ ~name,
119
+ ~indexes,
120
+ ~partitionTag,
121
+ ~opts,
122
+ )
123
+ Bus.registerDcbEventLogRead(storageName, read)
124
+ storage
125
+ | None =>
126
+ let (storageName, read, storage) = makeStorage(~name, ~indexes, ~partitionTag, ~opts)
127
+ Bus.registerDcbEventLogRead(storageName, read)
128
+ storage
129
+ }
130
+ }
131
+ }