@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,126 @@
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 Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
7
+ import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
8
+ import * as QueryDbFixtures$ReventlessLocal from "./QueryDbFixtures.res.mjs";
9
+
10
+ globalThis.describe("QueryDb (in-memory)", () => {
11
+ globalThis.beforeAll(async () => {
12
+ await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
13
+ });
14
+ globalThis.test("loadStream returns empty for unknown id", async () => {
15
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
16
+ let result = await Effect.runPromise(Stream.runCollect(ops.loadStream("unknown-id")));
17
+ globalThis.expect(result).toEqual([]);
18
+ });
19
+ globalThis.test("save and loadStream round-trip", async () => {
20
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
21
+ await ops.save("item-1", {
22
+ name: "Widget",
23
+ count: 5
24
+ }, "Init", undefined);
25
+ let result = await Effect.runPromise(Stream.runCollect(ops.loadStream("item-1")));
26
+ if (result.length !== 1) {
27
+ globalThis.expect("Expected [state]").toEqual("but got different result");
28
+ return;
29
+ }
30
+ let s = result[0];
31
+ globalThis.expect([
32
+ s.name,
33
+ s.count
34
+ ]).toEqual([
35
+ "Widget",
36
+ 5
37
+ ]);
38
+ });
39
+ globalThis.test("save overwrites previous state", async () => {
40
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
41
+ await ops.save("item-2", {
42
+ name: "Old",
43
+ count: 1
44
+ }, "Init", undefined);
45
+ await ops.save("item-2", {
46
+ name: "New",
47
+ count: 2
48
+ }, "Overwrite", undefined);
49
+ let result = await Effect.runPromise(Stream.runCollect(ops.loadStream("item-2")));
50
+ if (result.length !== 1) {
51
+ globalThis.expect("Expected [state]").toEqual("but got different result");
52
+ return;
53
+ }
54
+ let s = result[0];
55
+ globalThis.expect(s.name).toBe("New");
56
+ });
57
+ globalThis.test("saveBatch saves multiple states", async () => {
58
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
59
+ let batch = [
60
+ [
61
+ "batch-1",
62
+ {
63
+ name: "Alpha",
64
+ count: 1
65
+ },
66
+ undefined
67
+ ],
68
+ [
69
+ "batch-2",
70
+ {
71
+ name: "Beta",
72
+ count: 2
73
+ },
74
+ undefined
75
+ ]
76
+ ];
77
+ await ops.saveBatch(batch);
78
+ let r1 = await Effect.runPromise(Stream.runCollect(ops.loadStream("batch-1")));
79
+ let r2 = await Effect.runPromise(Stream.runCollect(ops.loadStream("batch-2")));
80
+ globalThis.expect([
81
+ r1.length !== 0,
82
+ r2.length !== 0
83
+ ]).toEqual([
84
+ true,
85
+ true
86
+ ]);
87
+ });
88
+ globalThis.test("delete removes state", async () => {
89
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
90
+ await ops.save("item-del", {
91
+ name: "ToDelete",
92
+ count: 0
93
+ }, "Init", undefined);
94
+ await ops.delete("item-del", undefined);
95
+ let result = await Effect.runPromise(Stream.runCollect(ops.loadStream("item-del")));
96
+ globalThis.expect(result).toEqual([]);
97
+ });
98
+ globalThis.test("loadStream emits saved states", async () => {
99
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
100
+ await ops.save("stream-item", {
101
+ name: "Streamed",
102
+ count: 42
103
+ }, "Init", undefined);
104
+ let arr = await Effect.runPromise(Stream.runCollect(ops.loadStream("stream-item")));
105
+ globalThis.expect(arr.length).toBe(1);
106
+ let s = arr[0];
107
+ globalThis.expect([
108
+ s.name,
109
+ s.count
110
+ ]).toEqual([
111
+ "Streamed",
112
+ 42
113
+ ]);
114
+ });
115
+ globalThis.test("loadStream returns empty for unknown id", async () => {
116
+ let ops = await TestRunner$ReventlessLocal.resolve(Component$ReventlessCore.operations(QueryDbFixtures$ReventlessLocal.queryDb));
117
+ let arr = await Effect.runPromise(Stream.runCollect(ops.loadStream("no-such-id")));
118
+ globalThis.expect(arr.length).toBe(0);
119
+ });
120
+ globalThis.test("registered in bus by component name", async () => {
121
+ let db = QueryDbFixtures$ReventlessLocal.Bus.getQueryDb("TestItemQueryDb");
122
+ globalThis.expect(Stdlib_Option.isSome(db)).toBe(true);
123
+ });
124
+ });
125
+
126
+ /* Not a pure module */
@@ -0,0 +1,215 @@
1
+ // E2E test fixtures for DcbEventLog → ReadModel projection.
2
+ // Wires a real DcbEventLog + StateChangeSlice + ReadModel and verifies that
3
+ // events appended to the DCB log flow through the EventTopic and update the
4
+ // ReadModel's QueryDb. Exercises the Phase 1.5 fix that aligns
5
+ // `meta.service` with the `allEventTopics` dict key, plus the Phase 3
6
+ // `Reventless.Projection.DcbSource` helper.
7
+ //
8
+ // Plan 03: docs/plans/mixed-source-readmodel.md
9
+
10
+ open TestFixtures
11
+ open Reventless
12
+ open Reventless.Projection
13
+
14
+ // ─────────────────────────────────────────────────────────────
15
+ // DCB StateChangeSlice — emits events into a DCB EventLog
16
+ // ─────────────────────────────────────────────────────────────
17
+
18
+ module AddProductSpec = {
19
+ let name = "AddProduct"
20
+ module Id = Reventless.Id.String
21
+ let moduleUrl: string = %raw(`import.meta.url`)
22
+
23
+ @schema
24
+ type event =
25
+ ProductAdded({
26
+ productId: @s.matches(Reventless.DcbTag.string) string,
27
+ name: string,
28
+ })
29
+
30
+ @schema
31
+ type consumedEvent = ProductAdded
32
+
33
+ @schema
34
+ type command = AddProduct({
35
+ productId: @s.matches(Reventless.DcbTag.string) string,
36
+ name: string,
37
+ })
38
+
39
+ @schema
40
+ type error = ProductAlreadyExists
41
+
42
+ let commandSchema = commandSchema
43
+ }
44
+
45
+ module AddProductBehavior = {
46
+ module Spec = AddProductSpec
47
+ let moduleUrl: string = %raw(`import.meta.url`)
48
+
49
+ type state = bool
50
+ let initialState = false
51
+
52
+ let evolve = (_state: state, _event: Spec.consumedEvent) => true
53
+
54
+ let decide = (state: state, command: Spec.command): result<array<Spec.event>, Spec.error> =>
55
+ if state {
56
+ Error(ProductAlreadyExists)
57
+ } else {
58
+ switch command {
59
+ | AddProduct({productId, name}) => Ok([Spec.ProductAdded({productId, name})])
60
+ }
61
+ }
62
+ }
63
+
64
+ // ─────────────────────────────────────────────────────────────
65
+ // DCB Source — name MUST match `<dcbName>DcbEventLog`
66
+ // (= the dict key Plugin_Builder uses + the service stamped by
67
+ // DcbEventLog_Operations after Phase 1.5).
68
+ //
69
+ // Hand-rolled `Source`-shaped module: this is the canonical pattern. The
70
+ // `Reventless.Projection.DcbSource.Make` helper is also available but requires
71
+ // binding the inline definition to a name first (ReScript abstract-type
72
+ // limitation), and the hand-rolled form is shorter for most cases.
73
+ // ─────────────────────────────────────────────────────────────
74
+
75
+ module ProductCatalogDcbSource = {
76
+ module Id = Reventless.Id.String
77
+ let name = "ProductCatalogDcbEventLog"
78
+
79
+ @schema
80
+ type event = ProductAdded({productId: string, name: string})
81
+ }
82
+
83
+ // ─────────────────────────────────────────────────────────────
84
+ // ReadModel spec
85
+ // ─────────────────────────────────────────────────────────────
86
+
87
+ module ProductsReadModelSpec = {
88
+ module Id = Reventless.Id.String
89
+ let name = "TestProductsReadModel"
90
+ let moduleUrl: string = %raw(`import.meta.url`)
91
+
92
+ @schema
93
+ type state = {productId: string, name: string}
94
+
95
+ let config = ReadModel.config()
96
+ let subIdConfig = None
97
+ }
98
+
99
+ module ProductsFromDcb = Mapping.Make(
100
+ ProductCatalogDcbSource,
101
+ ProductsReadModelSpec,
102
+ {
103
+ let project = (msg: Message.event'<string, ProductCatalogDcbSource.event>) =>
104
+ switch msg.event {
105
+ | ProductAdded({productId, name}) =>
106
+ Set(productId, ({productId, name}: ProductsReadModelSpec.state))
107
+ }
108
+ },
109
+ )
110
+
111
+ module ProductsMappings: Mappings with module Target := ProductsReadModelSpec = {
112
+ module Mappings = Mappings.Make(ProductsReadModelSpec)
113
+ module type Mapping = Mappings.Mapping
114
+ let moduleUrl: string = %raw(`import.meta.url`)
115
+ let mappings: array<module(Mapping)> = [module(ProductsFromDcb)]
116
+ }
117
+
118
+ // ─────────────────────────────────────────────────────────────
119
+ // Bus + Pulumi mock setup
120
+ // ─────────────────────────────────────────────────────────────
121
+
122
+ module Bus = LocalBus.Make()
123
+ let _ = TestRunner.setup()
124
+
125
+ // ─────────────────────────────────────────────────────────────
126
+ // Build DcbEventLog (~name="ProductCatalog") and StateChangeSlice
127
+ // ─────────────────────────────────────────────────────────────
128
+
129
+ module DcbLogMaker = DcbEventLog_Builder.Make(Bus)
130
+ let dcbEventLog = DcbLogMaker.make(
131
+ ~name="ProductCatalog",
132
+ ~partitionTag=Reventless.DcbTag.Simple({key: "productId"}),
133
+ )
134
+
135
+ module AddProductMaker = StateChangeSlice_Builder.Make(AddProductSpec, AddProductBehavior)
136
+
137
+ let publishJsons: ReventlessInfra.CommandTopic.publishJsons = async cmdJsons => {
138
+ let _ = await cmdJsons
139
+ ->Array.map(async cmdJson => {
140
+ let typeName = switch cmdJson.commandJson {
141
+ | JSON.Object(dict) =>
142
+ dict
143
+ ->Dict.get("TAG")
144
+ ->Option.flatMap(j =>
145
+ switch j {
146
+ | JSON.String(s) => Some(s)
147
+ | _ => None
148
+ }
149
+ )
150
+ ->Option.getOr("")
151
+ | _ => ""
152
+ }
153
+ let fullBody = JSON.Encode.object(
154
+ Dict.fromArray([
155
+ ("id", JSON.Encode.string(cmdJson.id)),
156
+ ("meta", cmdJson.meta->S.reverseConvertToJsonOrThrow(Reventless.Message.metaSchema)),
157
+ ("command", cmdJson.commandJson),
158
+ ]),
159
+ )
160
+ let handlers = ReventlessCore.CommandTopic.getHandlers(typeName)
161
+ let _ = await handlers
162
+ ->Array.map(async entry => {
163
+ let item: ReventlessInfra.CommandTopic.topicItem<JSON.t> = {
164
+ reference: cmdJson.id,
165
+ command: fullBody,
166
+ }
167
+ let _ = await entry.handler(Stream.fromIterable([item]))->Effect.runPromise
168
+ })
169
+ ->Promise.all
170
+ })
171
+ ->Promise.all
172
+ }
173
+
174
+ let publishJsonsOutput = publishJsons->Pulumi.Output.make
175
+ let _addProductSlice = AddProductMaker.make(~dcbEventLog, ~publishJsons=publishJsonsOutput)
176
+
177
+ // ─────────────────────────────────────────────────────────────
178
+ // Build allEventTopics and the ReadModel.
179
+ // Mirrors how Plugin_Builder merges the DCB EventTopic into allEventTopics
180
+ // under the key `<name> ++ "DcbEventLog"`.
181
+ // ─────────────────────────────────────────────────────────────
182
+
183
+ let dcbTopicOutputs: ReventlessInfra.EventTopic.outputs = (dcbEventLog->ReventlessInfra.Component.outputs).eventTopic
184
+
185
+ let allEventTopics: ReventlessInfra.EventTopic.allOutputs = Dict.fromArray([
186
+ ("ProductCatalogDcbEventLog", dcbTopicOutputs),
187
+ ])
188
+
189
+ module ReadModelMaker = ReadModel_Builder.Make(Bus)
190
+ module ProductsReadModel = ReadModelMaker.Make(ProductsReadModelSpec, ProductsMappings)
191
+ let rm = ProductsReadModel.make(~api=(), ~apiRole=(), ~allEventTopics)
192
+
193
+ // ─────────────────────────────────────────────────────────────
194
+ // Test helpers
195
+ // ─────────────────────────────────────────────────────────────
196
+
197
+ let dispatch = async (commandJson, id) =>
198
+ await publishJsons([{Reventless.Message.id, meta: testMeta, commandJson}])
199
+
200
+ let addProductCmd = (productId, name) =>
201
+ AddProductSpec.AddProduct({productId, name})
202
+ ->S.reverseConvertToJsonOrThrow(AddProductSpec.commandSchema)
203
+
204
+ let loadState = async productId => {
205
+ switch Bus.getQueryDb("TestProductsReadModel") {
206
+ | None => []
207
+ | Some(ops) =>
208
+ let states =
209
+ await ops.loadStream(productId)
210
+ ->Stream.runCollect
211
+ ->Effect.catchAll(_ => Effect.succeed([]))
212
+ ->Effect.runPromise
213
+ states->Array.map(json => json->S.parseJsonOrThrow(ProductsReadModelSpec.stateSchema))
214
+ }
215
+ }
@@ -0,0 +1,308 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
5
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
6
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Stream$1 from "effect/Stream";
9
+ import * as Pulumi from "@pulumi/pulumi";
10
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
11
+ import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
12
+ import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
13
+ import * as Projection$Reventless from "@reventlessdev/reventless-spec/src/types/Projection.res.mjs";
14
+ import * as LocalBus$ReventlessLocal from "../../../src/adapter/LocalBus.res.mjs";
15
+ import * as Component$ReventlessInfra from "@reventlessdev/reventless-infra/src/components/Component.res.mjs";
16
+ import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
17
+ import * as CommandTopic$ReventlessCore from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic.res.mjs";
18
+ import * as TestFixtures$ReventlessLocal from "../../TestFixtures.res.mjs";
19
+ import * as ReadModel_Builder$ReventlessLocal from "../../../src/components/ReadModel_Builder.res.mjs";
20
+ import * as DcbEventLog_Builder$ReventlessLocal from "../../../src/components/DcbEventLog_Builder.res.mjs";
21
+ import * as StateChangeSlice_Builder$ReventlessLocal from "../../../src/components/StateChangeSlice_Builder.res.mjs";
22
+
23
+ let name = "AddProduct";
24
+
25
+ let moduleUrl = import.meta.url;
26
+
27
+ let eventSchema = S.schema(s => ({
28
+ TAG: "ProductAdded",
29
+ productId: s.m(DcbTag$Reventless.string),
30
+ name: s.m(S.string)
31
+ }));
32
+
33
+ let consumedEventSchema = S.literal("ProductAdded");
34
+
35
+ let commandSchema = S.schema(s => ({
36
+ TAG: "AddProduct",
37
+ productId: s.m(DcbTag$Reventless.string),
38
+ name: s.m(S.string)
39
+ }));
40
+
41
+ let errorSchema = S.literal("ProductAlreadyExists");
42
+
43
+ function commandAuthorization(param) {
44
+ return "AllowAuthenticated";
45
+ }
46
+
47
+ let AddProductSpec = {
48
+ name: name,
49
+ Id: undefined,
50
+ moduleUrl: moduleUrl,
51
+ eventSchema: eventSchema,
52
+ consumedEventSchema: consumedEventSchema,
53
+ errorSchema: errorSchema,
54
+ commandSchema: commandSchema,
55
+ commandAuthorization: commandAuthorization,
56
+ readConsistency: "EscalateOnRetry"
57
+ };
58
+
59
+ let moduleUrl$1 = import.meta.url;
60
+
61
+ function evolve(_state, _event) {
62
+ return true;
63
+ }
64
+
65
+ function decide(state, command) {
66
+ if (state) {
67
+ return {
68
+ TAG: "Error",
69
+ _0: "ProductAlreadyExists"
70
+ };
71
+ } else {
72
+ return {
73
+ TAG: "Ok",
74
+ _0: [{
75
+ TAG: "ProductAdded",
76
+ productId: command.productId,
77
+ name: command.name
78
+ }]
79
+ };
80
+ }
81
+ }
82
+
83
+ let AddProductBehavior = {
84
+ Spec: undefined,
85
+ moduleUrl: moduleUrl$1,
86
+ initialState: false,
87
+ evolve: evolve,
88
+ decide: decide
89
+ };
90
+
91
+ let name$1 = "ProductCatalogDcbEventLog";
92
+
93
+ let eventSchema$1 = S.schema(s => ({
94
+ TAG: "ProductAdded",
95
+ productId: s.m(S.string),
96
+ name: s.m(S.string)
97
+ }));
98
+
99
+ let ProductCatalogDcbSource = {
100
+ Id: undefined,
101
+ name: name$1,
102
+ eventSchema: eventSchema$1
103
+ };
104
+
105
+ let name$2 = "TestProductsReadModel";
106
+
107
+ let moduleUrl$2 = import.meta.url;
108
+
109
+ let stateSchema = S.schema(s => ({
110
+ productId: s.m(S.string),
111
+ name: s.m(S.string)
112
+ }));
113
+
114
+ let config = ReadModel$Reventless.config(undefined, undefined, undefined);
115
+
116
+ let ProductsReadModelSpec = {
117
+ Id: undefined,
118
+ name: name$2,
119
+ moduleUrl: moduleUrl$2,
120
+ stateSchema: stateSchema,
121
+ config: config,
122
+ subIdConfig: undefined,
123
+ authorization: "AllowAuthenticated",
124
+ visibility: "Public"
125
+ };
126
+
127
+ function project(msg) {
128
+ let match = msg.event;
129
+ let productId = match.productId;
130
+ return {
131
+ TAG: "Set",
132
+ _0: productId,
133
+ _1: {
134
+ productId: productId,
135
+ name: match.name
136
+ }
137
+ };
138
+ }
139
+
140
+ let ProductsFromDcb = Projection$Reventless.Mapping.Make({
141
+ Id: Id$Reventless.$$String,
142
+ name: name$1,
143
+ eventSchema: eventSchema$1
144
+ })({
145
+ Id: Id$Reventless.$$String,
146
+ name: name$2,
147
+ stateSchema: stateSchema,
148
+ subIdConfig: undefined
149
+ })({
150
+ project: project
151
+ });
152
+
153
+ Projection$Reventless.Mappings.Make({
154
+ Id: Id$Reventless.$$String,
155
+ name: name$2,
156
+ stateSchema: stateSchema,
157
+ subIdConfig: undefined
158
+ });
159
+
160
+ let moduleUrl$3 = import.meta.url;
161
+
162
+ let mappings = [ProductsFromDcb];
163
+
164
+ let ProductsMappings = {
165
+ moduleUrl: moduleUrl$3,
166
+ mappings: mappings
167
+ };
168
+
169
+ let Bus = LocalBus$ReventlessLocal.Make({});
170
+
171
+ TestRunner$ReventlessLocal.setup();
172
+
173
+ let DcbLogMaker = DcbEventLog_Builder$ReventlessLocal.Make(Bus);
174
+
175
+ let dcbEventLog = DcbLogMaker.make("ProductCatalog", undefined, {
176
+ TAG: "Simple",
177
+ _0: {
178
+ key: "productId"
179
+ }
180
+ }, undefined);
181
+
182
+ let AddProductMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
183
+ name: name,
184
+ moduleUrl: moduleUrl,
185
+ Id: Id$Reventless.$$String,
186
+ consumedEventSchema: consumedEventSchema,
187
+ errorSchema: errorSchema,
188
+ eventSchema: eventSchema,
189
+ commandSchema: commandSchema,
190
+ commandAuthorization: commandAuthorization,
191
+ readConsistency: "EscalateOnRetry"
192
+ })({
193
+ initialState: false,
194
+ evolve: evolve,
195
+ decide: decide,
196
+ moduleUrl: moduleUrl$1
197
+ });
198
+
199
+ async function publishJsons(cmdJsons) {
200
+ await Promise.all(cmdJsons.map(async cmdJson => {
201
+ let dict = cmdJson.commandJson;
202
+ let typeName;
203
+ typeName = typeof dict === "object" && dict !== null && !Array.isArray(dict) ? Stdlib_Option.getOr(Stdlib_Option.flatMap(dict["TAG"], j => {
204
+ if (typeof j === "string") {
205
+ return j;
206
+ }
207
+ }), "") : "";
208
+ let fullBody = Object.fromEntries([
209
+ [
210
+ "id",
211
+ cmdJson.id
212
+ ],
213
+ [
214
+ "meta",
215
+ S.reverseConvertToJsonOrThrow(cmdJson.meta, Message$Reventless.metaSchema)
216
+ ],
217
+ [
218
+ "command",
219
+ cmdJson.commandJson
220
+ ]
221
+ ]);
222
+ let handlers = CommandTopic$ReventlessCore.getHandlers(typeName);
223
+ await Promise.all(handlers.map(async entry => {
224
+ let item_reference = cmdJson.id;
225
+ let item = {
226
+ command: fullBody,
227
+ reference: item_reference
228
+ };
229
+ await Effect.runPromise(entry.handler(Stream$1.fromIterable([item])));
230
+ }));
231
+ }));
232
+ }
233
+
234
+ let publishJsonsOutput = Pulumi.output(publishJsons);
235
+
236
+ let _addProductSlice = AddProductMaker.make(dcbEventLog, publishJsonsOutput, undefined, undefined, undefined);
237
+
238
+ let dcbTopicOutputs = Component$ReventlessInfra.outputs(dcbEventLog).eventTopic;
239
+
240
+ let allEventTopics = Object.fromEntries([[
241
+ "ProductCatalogDcbEventLog",
242
+ dcbTopicOutputs
243
+ ]]);
244
+
245
+ let ReadModelMaker = ReadModel_Builder$ReventlessLocal.Make(Bus);
246
+
247
+ let ProductsReadModel = ReadModelMaker.Make({
248
+ Id: Id$Reventless.$$String,
249
+ name: name$2,
250
+ moduleUrl: moduleUrl$2,
251
+ stateSchema: stateSchema,
252
+ config: config,
253
+ subIdConfig: undefined,
254
+ authorization: "AllowAuthenticated",
255
+ visibility: "Public"
256
+ })(ProductsMappings);
257
+
258
+ let rm = ProductsReadModel.make(undefined, undefined, allEventTopics, undefined);
259
+
260
+ async function dispatch(commandJson, id) {
261
+ return await publishJsons([{
262
+ id: id,
263
+ meta: TestFixtures$ReventlessLocal.testMeta,
264
+ commandJson: commandJson
265
+ }]);
266
+ }
267
+
268
+ function addProductCmd(productId, name) {
269
+ return S.reverseConvertToJsonOrThrow({
270
+ TAG: "AddProduct",
271
+ productId: productId,
272
+ name: name
273
+ }, commandSchema);
274
+ }
275
+
276
+ async function loadState(productId) {
277
+ let ops = Bus.getQueryDb("TestProductsReadModel");
278
+ if (ops === undefined) {
279
+ return [];
280
+ }
281
+ let states = await Effect.runPromise(Effect.catchAll(Stream.runCollect(ops.loadStream(productId)), param => Effect.succeed([])));
282
+ return states.map(json => S.parseJsonOrThrow(json, stateSchema));
283
+ }
284
+
285
+ export {
286
+ AddProductSpec,
287
+ AddProductBehavior,
288
+ ProductCatalogDcbSource,
289
+ ProductsReadModelSpec,
290
+ ProductsFromDcb,
291
+ ProductsMappings,
292
+ Bus,
293
+ DcbLogMaker,
294
+ dcbEventLog,
295
+ AddProductMaker,
296
+ publishJsons,
297
+ publishJsonsOutput,
298
+ _addProductSlice,
299
+ dcbTopicOutputs,
300
+ allEventTopics,
301
+ ReadModelMaker,
302
+ ProductsReadModel,
303
+ rm,
304
+ dispatch,
305
+ addProductCmd,
306
+ loadState,
307
+ }
308
+ /* moduleUrl Not a pure module */
@@ -0,0 +1,45 @@
1
+ // E2E test: a DCB StateChangeSlice's events flow through the DcbEventLog's
2
+ // EventTopic and land in a ReadModel projection — the very pattern Plan 03
3
+ // is meant to enable.
4
+ //
5
+ // This test will silently pass-but-project-nothing if the Phase 1.5 fix
6
+ // (meta.service = `<name>DcbEventLog`) ever regresses, so it doubles as a
7
+ // regression vehicle for that fix.
8
+
9
+ open JestGlobals
10
+ open DcbReadModelE2EFixtures
11
+
12
+ describe("DCB → ReadModel E2E:", () => {
13
+ let _ = beforeAllAsync(async () => {
14
+ let _ = await dcbEventLog->DcbLogMaker.operations->TestRunner.resolve
15
+ let _ = await rm->ProductsReadModel.operations->TestRunner.resolve
16
+ // Wait for the ReadModel's EventCollector to register its bus subscription.
17
+ let resource = dcbTopicOutputs.resources->Array.getUnsafe(0)
18
+ let _ = await resource.name->TestRunner.resolve
19
+ })
20
+
21
+ testPromise("AddProduct command updates the ReadModel state", async () => {
22
+ await dispatch(addProductCmd("prod-1", "Laptop"), "prod-1")
23
+ let states = await loadState("prod-1")
24
+ expect(states->Array.length)->toBe(1)
25
+ let state = states->Array.getUnsafe(0)
26
+ expect(state.productId)->toBe("prod-1")
27
+ expect(state.name)->toBe("Laptop")
28
+ })
29
+
30
+ testPromise("second AddProduct for the same id is a no-op (decide returns Error)", async () => {
31
+ await dispatch(addProductCmd("prod-1", "Different name"), "prod-1")
32
+ let states = await loadState("prod-1")
33
+ expect(states->Array.length)->toBe(1)
34
+ let state = states->Array.getUnsafe(0)
35
+ expect(state.name)->toBe("Laptop")
36
+ })
37
+
38
+ testPromise("a different product id gets its own entry", async () => {
39
+ await dispatch(addProductCmd("prod-2", "Headphones"), "prod-2")
40
+ let states = await loadState("prod-2")
41
+ expect(states->Array.length)->toBe(1)
42
+ let state = states->Array.getUnsafe(0)
43
+ expect(state.name)->toBe("Headphones")
44
+ })
45
+ })