@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,148 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as LocalBus$ReventlessLocal from "../../src/adapter/LocalBus.res.mjs";
4
+ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
5
+ import * as LocalQueryEngine$ReventlessLocal from "../../src/adapter/QueryEngine/LocalQueryEngine.res.mjs";
6
+ import * as QueryDbStorage_InMemory$ReventlessLocal from "../../src/adapter/QueryDb/QueryDbStorage_InMemory.res.mjs";
7
+
8
+ TestRunner$ReventlessLocal.setup();
9
+
10
+ let opts = {};
11
+
12
+ globalThis.describe("LocalQueryEngine", () => {
13
+ globalThis.describe("query", () => {
14
+ globalThis.test("query by id returns items saved in the matching QueryDbStorage", async () => {
15
+ let TestBus = LocalBus$ReventlessLocal.Make({});
16
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
17
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
18
+ let s = Storage.make("users", [], undefined, undefined, undefined, undefined, opts);
19
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
20
+ await ops.save("user-1", "Alice", "Any", undefined);
21
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
22
+ let items = await engine.query("users", undefined, {
23
+ TAG: "String",
24
+ _0: "user-1"
25
+ }, undefined, undefined, undefined, undefined);
26
+ globalThis.expect(items.length).toBe(1);
27
+ globalThis.expect(items[0]).toEqual("Alice");
28
+ });
29
+ globalThis.test("query with explicit key overrides the id parameter", async () => {
30
+ let TestBus = LocalBus$ReventlessLocal.Make({});
31
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
32
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
33
+ let s = Storage.make("products", [], undefined, undefined, undefined, undefined, opts);
34
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
35
+ await ops.save("prod-key", "Widget", "Any", undefined);
36
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
37
+ let items = await engine.query("products", "prod-key", {
38
+ TAG: "String",
39
+ _0: "ignored"
40
+ }, undefined, undefined, undefined, undefined);
41
+ globalThis.expect(items.length).toBe(1);
42
+ globalThis.expect(items[0]).toEqual("Widget");
43
+ });
44
+ globalThis.test("query for unknown readModelName returns empty array", async () => {
45
+ let TestBus = LocalBus$ReventlessLocal.Make({});
46
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
47
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
48
+ let items = await engine.query("no-such-model", undefined, {
49
+ TAG: "String",
50
+ _0: "any"
51
+ }, undefined, undefined, undefined, undefined);
52
+ globalThis.expect(items.length).toBe(0);
53
+ });
54
+ globalThis.test("query with Int id converts to string key for lookup", async () => {
55
+ let TestBus = LocalBus$ReventlessLocal.Make({});
56
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
57
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
58
+ let s = Storage.make("counters", [], undefined, undefined, undefined, undefined, opts);
59
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
60
+ await ops.save("42", 100, "Any", undefined);
61
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
62
+ let items = await engine.query("counters", undefined, {
63
+ TAG: "Int",
64
+ _0: 42
65
+ }, undefined, undefined, undefined, undefined);
66
+ globalThis.expect(items.length).toBe(1);
67
+ });
68
+ });
69
+ globalThis.describe("scan", () => {
70
+ globalThis.test("scan returns all items from the matching QueryDbStorage", async () => {
71
+ let TestBus = LocalBus$ReventlessLocal.Make({});
72
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
73
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
74
+ let s = Storage.make("orders", [], undefined, undefined, undefined, undefined, opts);
75
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
76
+ await ops.save("o1", "order1", "Any", undefined);
77
+ await ops.save("o2", "order2", "Any", undefined);
78
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
79
+ let items = await engine.scan("orders", [], 100);
80
+ globalThis.expect(items.length).toBe(2);
81
+ });
82
+ globalThis.test("scan for unknown readModelName returns empty array", async () => {
83
+ let TestBus = LocalBus$ReventlessLocal.Make({});
84
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
85
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
86
+ let items = await engine.scan("no-such-model", [], 100);
87
+ globalThis.expect(items.length).toBe(0);
88
+ });
89
+ });
90
+ globalThis.describe("scan with ~limit", () => {
91
+ globalThis.test("~limit=2 on a 5-item QueryDb returns exactly 2 items", async () => {
92
+ let TestBus = LocalBus$ReventlessLocal.Make({});
93
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
94
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
95
+ let s = Storage.make("items", [], undefined, undefined, undefined, undefined, opts);
96
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
97
+ await ops.save("k1", "a", "Any", undefined);
98
+ await ops.save("k2", "b", "Any", undefined);
99
+ await ops.save("k3", "c", "Any", undefined);
100
+ await ops.save("k4", "d", "Any", undefined);
101
+ await ops.save("k5", "e", "Any", undefined);
102
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
103
+ let result = await engine.scan("items", [], 2);
104
+ globalThis.expect(result.length).toBe(2);
105
+ });
106
+ globalThis.test("~limit larger than total returns all items (no padding)", async () => {
107
+ let TestBus = LocalBus$ReventlessLocal.Make({});
108
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
109
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
110
+ let s = Storage.make("things", [], undefined, undefined, undefined, undefined, opts);
111
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
112
+ await ops.save("t1", "x", "Any", undefined);
113
+ await ops.save("t2", "y", "Any", undefined);
114
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
115
+ let result = await engine.scan("things", [], 100);
116
+ globalThis.expect(result.length).toBe(2);
117
+ });
118
+ globalThis.test("~limit=0 returns empty array", async () => {
119
+ let TestBus = LocalBus$ReventlessLocal.Make({});
120
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
121
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
122
+ let s = Storage.make("stuff", [], undefined, undefined, undefined, undefined, opts);
123
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
124
+ await ops.save("s1", "z", "Any", undefined);
125
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
126
+ let result = await engine.scan("stuff", [], 0);
127
+ globalThis.expect(result.length).toBe(0);
128
+ });
129
+ globalThis.test("~limit=3 on a 3-item QueryDb returns all 3 items", async () => {
130
+ let TestBus = LocalBus$ReventlessLocal.Make({});
131
+ let Storage = QueryDbStorage_InMemory$ReventlessLocal.Make(TestBus);
132
+ let QE = LocalQueryEngine$ReventlessLocal.Make(TestBus);
133
+ let s = Storage.make("widgets", [], undefined, undefined, undefined, undefined, opts);
134
+ let ops = await TestRunner$ReventlessLocal.resolve(s.operations);
135
+ await ops.save("w1", "p", "Any", undefined);
136
+ await ops.save("w2", "q", "Any", undefined);
137
+ await ops.save("w3", "r", "Any", undefined);
138
+ let engine = await TestRunner$ReventlessLocal.resolve(QE.make({}));
139
+ let result = await engine.scan("widgets", [], 3);
140
+ globalThis.expect(result.length).toBe(3);
141
+ });
142
+ });
143
+ });
144
+
145
+ export {
146
+ opts,
147
+ }
148
+ /* Not a pure module */
@@ -0,0 +1,199 @@
1
+ // Unit tests for LocalScheduledPublisher.
2
+ // Uses fake timers to verify createSchedule, deleteSchedule, and reset.
3
+
4
+ open JestGlobals
5
+
6
+ // ─────────────────────────────────────────────────────────────
7
+ // Fake timer bindings
8
+ // ─────────────────────────────────────────────────────────────
9
+
10
+ type jestObj
11
+ @module("@jest/globals") external jest: jestObj = "jest"
12
+ @send external useFakeTimers: jestObj => unit = "useFakeTimers"
13
+ @send external useRealTimers: jestObj => unit = "useRealTimers"
14
+ @send external runAllTimers: jestObj => unit = "runAllTimers"
15
+ @send external advanceTimersByTime: (jestObj, int) => unit = "advanceTimersByTime"
16
+
17
+ let _ = beforeAll(() => {
18
+ jest->useFakeTimers
19
+ })
20
+
21
+ // ─────────────────────────────────────────────────────────────
22
+ // Pulumi mock (needed for Pulumi.Output.make in ScheduledPublisher)
23
+ // ─────────────────────────────────────────────────────────────
24
+
25
+ let _ = TestRunner.setup()
26
+
27
+ // ─────────────────────────────────────────────────────────────
28
+ // Restore real timers after all tests in this file
29
+ // ─────────────────────────────────────────────────────────────
30
+
31
+ let _ = afterAll(() => {
32
+ jest->useRealTimers
33
+ })
34
+
35
+ // ─────────────────────────────────────────────────────────────
36
+ // Helper: create a topic resource with a known name
37
+ // ─────────────────────────────────────────────────────────────
38
+
39
+ let makeTopicResource = (topicName: string): ReventlessInfra.Adapter.resolvedResource => {
40
+ name: topicName,
41
+ id: topicName,
42
+ urn: topicName,
43
+ resourceInfo: NoInfo,
44
+ service: "memory:InMemory",
45
+ role: "",
46
+ region: "",
47
+ resourceType: "",
48
+ configuration: Dict.make(),
49
+ tags: Dict.make(),
50
+ }
51
+
52
+ describe("LocalScheduledPublisher", () => {
53
+ describe("createSchedule", () => {
54
+ testPromise("single-shot schedule fires event after runAllTimers", async () => {
55
+ module TestBus = LocalBus.Make()
56
+ module SP = LocalScheduledPublisher.Make(TestBus)
57
+ let count: ref<int> = ref(0)
58
+ TestBus.subscribeToEvents("sched-topic", async (_, _, _) => {
59
+ count := count.contents + 1
60
+ })
61
+ let pub = SP.make(~name="scheduler", ~opts={})
62
+ let ops = await pub.operations->TestRunner.resolve
63
+ let schedule: Reventless.Schedule.schedule = {
64
+ name: "one-shot",
65
+ rate: Reventless.Schedule.Single(2024, 1, 1, 0, 0),
66
+ payload: "{}",
67
+ }
68
+ await ops.createSchedule([makeTopicResource("sched-topic")], schedule)
69
+ jest->runAllTimers
70
+ // Two microtask ticks: publishEvent uses Effect.all(concurrency=unbounded) which forks
71
+ // child fibers via startFork — one tick for the child fiber to offer to the Queue,
72
+ // a second tick for the drain fiber to run the callback.
73
+ let _ = await Promise.resolve(())
74
+ let _ = await Promise.resolve(())
75
+ expect(count.contents)->toBe(1)
76
+ SP.reset()
77
+ })
78
+
79
+ testPromise("recurring schedule fires on each interval advance", async () => {
80
+ module TestBus = LocalBus.Make()
81
+ module SP = LocalScheduledPublisher.Make(TestBus)
82
+ let count: ref<int> = ref(0)
83
+ TestBus.subscribeToEvents("repeat-topic", async (_, _, _) => {
84
+ count := count.contents + 1
85
+ })
86
+ let pub = SP.make(~name="scheduler2", ~opts={})
87
+ let ops = await pub.operations->TestRunner.resolve
88
+ let schedule: Reventless.Schedule.schedule = {
89
+ name: "every-minute",
90
+ rate: Reventless.Schedule.Minutes(1),
91
+ payload: "{}",
92
+ }
93
+ await ops.createSchedule([makeTopicResource("repeat-topic")], schedule)
94
+ jest->advanceTimersByTime(60 * 1000)
95
+ let _ = await Promise.resolve(())
96
+ let _ = await Promise.resolve(())
97
+ jest->advanceTimersByTime(60 * 1000)
98
+ let _ = await Promise.resolve(())
99
+ let _ = await Promise.resolve(())
100
+ expect(count.contents)->toBe(2)
101
+ SP.reset()
102
+ })
103
+ })
104
+
105
+ describe("deleteSchedule", () => {
106
+ testPromise("clears a named schedule; advancing timers does not fire it", async () => {
107
+ module TestBus = LocalBus.Make()
108
+ module SP = LocalScheduledPublisher.Make(TestBus)
109
+ let count: ref<int> = ref(0)
110
+ TestBus.subscribeToEvents("del-topic", async (_, _, _) => {
111
+ count := count.contents + 1
112
+ })
113
+ let pub = SP.make(~name="scheduler3", ~opts={})
114
+ let ops = await pub.operations->TestRunner.resolve
115
+ let schedule: Reventless.Schedule.schedule = {
116
+ name: "to-delete",
117
+ rate: Reventless.Schedule.Minutes(1),
118
+ payload: "{}",
119
+ }
120
+ await ops.createSchedule([makeTopicResource("del-topic")], schedule)
121
+ await ops.deleteSchedule([], "to-delete")
122
+ jest->advanceTimersByTime(60 * 1000)
123
+ expect(count.contents)->toBe(0)
124
+ SP.reset()
125
+ })
126
+ })
127
+
128
+ describe("reset", () => {
129
+ testPromise("clears all active timers; subsequent advance does not fire", async () => {
130
+ module TestBus = LocalBus.Make()
131
+ module SP = LocalScheduledPublisher.Make(TestBus)
132
+ let count: ref<int> = ref(0)
133
+ TestBus.subscribeToEvents("reset-topic", async (_, _, _) => {
134
+ count := count.contents + 1
135
+ })
136
+ let pub = SP.make(~name="scheduler4", ~opts={})
137
+ let ops = await pub.operations->TestRunner.resolve
138
+ let schedule: Reventless.Schedule.schedule = {
139
+ name: "reset-sched",
140
+ rate: Reventless.Schedule.Minutes(5),
141
+ payload: "{}",
142
+ }
143
+ await ops.createSchedule([makeTopicResource("reset-topic")], schedule)
144
+ SP.reset()
145
+ jest->advanceTimersByTime(5 * 60 * 1000)
146
+ expect(count.contents)->toBe(0)
147
+ })
148
+ })
149
+
150
+ describe("rateToMs", () => {
151
+ testPromise("Minutes(n) fires after n minutes", async () => {
152
+ module TestBus = LocalBus.Make()
153
+ module SP = LocalScheduledPublisher.Make(TestBus)
154
+ let count: ref<int> = ref(0)
155
+ TestBus.subscribeToEvents("rate-topic", async (_, _, _) => {
156
+ count := count.contents + 1
157
+ })
158
+ let pub = SP.make(~name="rate-scheduler", ~opts={})
159
+ let ops = await pub.operations->TestRunner.resolve
160
+ let schedule: Reventless.Schedule.schedule = {
161
+ name: "rate-sched",
162
+ rate: Reventless.Schedule.Minutes(3),
163
+ payload: "{}",
164
+ }
165
+ await ops.createSchedule([makeTopicResource("rate-topic")], schedule)
166
+ // Advance by slightly less than 3 minutes — should not fire
167
+ jest->advanceTimersByTime(3 * 60 * 1000 - 1)
168
+ expect(count.contents)->toBe(0)
169
+ // Advance the remaining millisecond — now fires; two ticks for Effect.all drain
170
+ jest->advanceTimersByTime(1)
171
+ let _ = await Promise.resolve(())
172
+ let _ = await Promise.resolve(())
173
+ expect(count.contents)->toBe(1)
174
+ SP.reset()
175
+ })
176
+
177
+ testPromise("Hours(n) fires after n hours", async () => {
178
+ module TestBus = LocalBus.Make()
179
+ module SP = LocalScheduledPublisher.Make(TestBus)
180
+ let count: ref<int> = ref(0)
181
+ TestBus.subscribeToEvents("hours-topic", async (_, _, _) => {
182
+ count := count.contents + 1
183
+ })
184
+ let pub = SP.make(~name="hours-scheduler", ~opts={})
185
+ let ops = await pub.operations->TestRunner.resolve
186
+ let schedule: Reventless.Schedule.schedule = {
187
+ name: "hours-sched",
188
+ rate: Reventless.Schedule.Hours(2),
189
+ payload: "{}",
190
+ }
191
+ await ops.createSchedule([makeTopicResource("hours-topic")], schedule)
192
+ jest->advanceTimersByTime(2 * 60 * 60 * 1000)
193
+ let _ = await Promise.resolve(())
194
+ let _ = await Promise.resolve(())
195
+ expect(count.contents)->toBe(1)
196
+ SP.reset()
197
+ })
198
+ })
199
+ })
@@ -0,0 +1,203 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Globals from "@jest/globals";
4
+ import * as LocalBus$ReventlessLocal from "../../src/adapter/LocalBus.res.mjs";
5
+ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
6
+ import * as LocalScheduledPublisher$ReventlessLocal from "../../src/adapter/Scheduler/LocalScheduledPublisher.res.mjs";
7
+
8
+ globalThis.beforeAll(() => {
9
+ Globals.jest.useFakeTimers();
10
+ });
11
+
12
+ TestRunner$ReventlessLocal.setup();
13
+
14
+ globalThis.afterAll(() => {
15
+ Globals.jest.useRealTimers();
16
+ });
17
+
18
+ function makeTopicResource(topicName) {
19
+ return {
20
+ name: topicName,
21
+ id: topicName,
22
+ urn: topicName,
23
+ resourceInfo: "NoInfo",
24
+ service: "memory:InMemory",
25
+ role: "",
26
+ region: "",
27
+ resourceType: "",
28
+ configuration: {},
29
+ tags: {}
30
+ };
31
+ }
32
+
33
+ globalThis.describe("LocalScheduledPublisher", () => {
34
+ globalThis.describe("createSchedule", () => {
35
+ globalThis.test("single-shot schedule fires event after runAllTimers", async () => {
36
+ let TestBus = LocalBus$ReventlessLocal.Make({});
37
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
38
+ let count = {
39
+ contents: 0
40
+ };
41
+ TestBus.subscribeToEvents("sched-topic", async (param, param$1, param$2) => {
42
+ count.contents = count.contents + 1 | 0;
43
+ });
44
+ let pub = SP.make("scheduler", {});
45
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
46
+ await ops.createSchedule([makeTopicResource("sched-topic")], {
47
+ name: "one-shot",
48
+ rate: {
49
+ TAG: "Single",
50
+ _0: 2024,
51
+ _1: 1,
52
+ _2: 1,
53
+ _3: 0,
54
+ _4: 0
55
+ },
56
+ payload: "{}"
57
+ });
58
+ Globals.jest.runAllTimers();
59
+ await Promise.resolve();
60
+ await Promise.resolve();
61
+ globalThis.expect(count.contents).toBe(1);
62
+ return SP.reset();
63
+ });
64
+ globalThis.test("recurring schedule fires on each interval advance", async () => {
65
+ let TestBus = LocalBus$ReventlessLocal.Make({});
66
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
67
+ let count = {
68
+ contents: 0
69
+ };
70
+ TestBus.subscribeToEvents("repeat-topic", async (param, param$1, param$2) => {
71
+ count.contents = count.contents + 1 | 0;
72
+ });
73
+ let pub = SP.make("scheduler2", {});
74
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
75
+ await ops.createSchedule([makeTopicResource("repeat-topic")], {
76
+ name: "every-minute",
77
+ rate: {
78
+ TAG: "Minutes",
79
+ _0: 1
80
+ },
81
+ payload: "{}"
82
+ });
83
+ Globals.jest.advanceTimersByTime(60000);
84
+ await Promise.resolve();
85
+ await Promise.resolve();
86
+ Globals.jest.advanceTimersByTime(60000);
87
+ await Promise.resolve();
88
+ await Promise.resolve();
89
+ globalThis.expect(count.contents).toBe(2);
90
+ return SP.reset();
91
+ });
92
+ });
93
+ globalThis.describe("deleteSchedule", () => {
94
+ globalThis.test("clears a named schedule; advancing timers does not fire it", async () => {
95
+ let TestBus = LocalBus$ReventlessLocal.Make({});
96
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
97
+ let count = {
98
+ contents: 0
99
+ };
100
+ TestBus.subscribeToEvents("del-topic", async (param, param$1, param$2) => {
101
+ count.contents = count.contents + 1 | 0;
102
+ });
103
+ let pub = SP.make("scheduler3", {});
104
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
105
+ await ops.createSchedule([makeTopicResource("del-topic")], {
106
+ name: "to-delete",
107
+ rate: {
108
+ TAG: "Minutes",
109
+ _0: 1
110
+ },
111
+ payload: "{}"
112
+ });
113
+ await ops.deleteSchedule([], "to-delete");
114
+ Globals.jest.advanceTimersByTime(60000);
115
+ globalThis.expect(count.contents).toBe(0);
116
+ return SP.reset();
117
+ });
118
+ });
119
+ globalThis.describe("reset", () => {
120
+ globalThis.test("clears all active timers; subsequent advance does not fire", async () => {
121
+ let TestBus = LocalBus$ReventlessLocal.Make({});
122
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
123
+ let count = {
124
+ contents: 0
125
+ };
126
+ TestBus.subscribeToEvents("reset-topic", async (param, param$1, param$2) => {
127
+ count.contents = count.contents + 1 | 0;
128
+ });
129
+ let pub = SP.make("scheduler4", {});
130
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
131
+ await ops.createSchedule([makeTopicResource("reset-topic")], {
132
+ name: "reset-sched",
133
+ rate: {
134
+ TAG: "Minutes",
135
+ _0: 5
136
+ },
137
+ payload: "{}"
138
+ });
139
+ SP.reset();
140
+ Globals.jest.advanceTimersByTime(300000);
141
+ globalThis.expect(count.contents).toBe(0);
142
+ });
143
+ });
144
+ globalThis.describe("rateToMs", () => {
145
+ globalThis.test("Minutes(n) fires after n minutes", async () => {
146
+ let TestBus = LocalBus$ReventlessLocal.Make({});
147
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
148
+ let count = {
149
+ contents: 0
150
+ };
151
+ TestBus.subscribeToEvents("rate-topic", async (param, param$1, param$2) => {
152
+ count.contents = count.contents + 1 | 0;
153
+ });
154
+ let pub = SP.make("rate-scheduler", {});
155
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
156
+ await ops.createSchedule([makeTopicResource("rate-topic")], {
157
+ name: "rate-sched",
158
+ rate: {
159
+ TAG: "Minutes",
160
+ _0: 3
161
+ },
162
+ payload: "{}"
163
+ });
164
+ Globals.jest.advanceTimersByTime(179999);
165
+ globalThis.expect(count.contents).toBe(0);
166
+ Globals.jest.advanceTimersByTime(1);
167
+ await Promise.resolve();
168
+ await Promise.resolve();
169
+ globalThis.expect(count.contents).toBe(1);
170
+ return SP.reset();
171
+ });
172
+ globalThis.test("Hours(n) fires after n hours", async () => {
173
+ let TestBus = LocalBus$ReventlessLocal.Make({});
174
+ let SP = LocalScheduledPublisher$ReventlessLocal.Make(TestBus);
175
+ let count = {
176
+ contents: 0
177
+ };
178
+ TestBus.subscribeToEvents("hours-topic", async (param, param$1, param$2) => {
179
+ count.contents = count.contents + 1 | 0;
180
+ });
181
+ let pub = SP.make("hours-scheduler", {});
182
+ let ops = await TestRunner$ReventlessLocal.resolve(pub.operations);
183
+ await ops.createSchedule([makeTopicResource("hours-topic")], {
184
+ name: "hours-sched",
185
+ rate: {
186
+ TAG: "Hours",
187
+ _0: 2
188
+ },
189
+ payload: "{}"
190
+ });
191
+ Globals.jest.advanceTimersByTime(7200000);
192
+ await Promise.resolve();
193
+ await Promise.resolve();
194
+ globalThis.expect(count.contents).toBe(1);
195
+ return SP.reset();
196
+ });
197
+ });
198
+ });
199
+
200
+ export {
201
+ makeTopicResource,
202
+ }
203
+ /* Not a pure module */
@@ -0,0 +1,103 @@
1
+ // Unit tests for SortKey_Filter — the pure sort key filtering utility.
2
+
3
+ open JestGlobals
4
+
5
+ let makeItem = (sk: string) => {
6
+ let d = Dict.make()
7
+ d->Dict.set("_subId", JSON.Encode.string(sk))
8
+ JSON.Encode.object(d)
9
+ }
10
+
11
+ let items = [
12
+ makeItem("art/2026-01"),
13
+ makeItem("art/2026-02"),
14
+ makeItem("math/2026-01"),
15
+ makeItem("math/2026-02"),
16
+ makeItem("science/2026-01"),
17
+ ]
18
+
19
+ let skField = "_subId"
20
+
21
+ let getSks = result =>
22
+ result.SortKey_Filter.items->Array.map(item =>
23
+ item->JSON.Decode.object->Option.flatMap(d => d->Dict.get(skField))->Option.flatMap(JSON.Decode.string)->Option.getOr("")
24
+ )
25
+
26
+ describe("SortKey_Filter.apply:", () => {
27
+ testPromise("no filters returns all items in order", async () => {
28
+ let r = SortKey_Filter.apply(~items, ~skField)
29
+ expect(r.items->Array.length)->toBe(5)
30
+ expect(getSks(r))->toEqual(["art/2026-01", "art/2026-02", "math/2026-01", "math/2026-02", "science/2026-01"])
31
+ expect(r.nextToken)->toBe(None)
32
+ })
33
+
34
+ testPromise("prefix filters to matching sort keys", async () => {
35
+ let r = SortKey_Filter.apply(~items, ~skField, ~prefix="math")
36
+ expect(getSks(r))->toEqual(["math/2026-01", "math/2026-02"])
37
+ expect(r.nextToken)->toBe(None)
38
+ })
39
+
40
+ testPromise("from filters to sort keys >= from", async () => {
41
+ let r = SortKey_Filter.apply(~items, ~skField, ~from="math/2026-01")
42
+ expect(getSks(r))->toEqual(["math/2026-01", "math/2026-02", "science/2026-01"])
43
+ })
44
+
45
+ testPromise("to filters to sort keys <= to", async () => {
46
+ let r = SortKey_Filter.apply(~items, ~skField, ~to_="art/2026-02")
47
+ expect(getSks(r))->toEqual(["art/2026-01", "art/2026-02"])
48
+ })
49
+
50
+ testPromise("from+to gives BETWEEN range", async () => {
51
+ let r = SortKey_Filter.apply(~items, ~skField, ~from="art/2026-02", ~to_="math/2026-01")
52
+ expect(getSks(r))->toEqual(["art/2026-02", "math/2026-01"])
53
+ })
54
+
55
+ testPromise("eq filters to exact match only", async () => {
56
+ let r = SortKey_Filter.apply(~items, ~skField, ~eq="math/2026-02")
57
+ expect(getSks(r))->toEqual(["math/2026-02"])
58
+ })
59
+
60
+ testPromise("reverse returns items in descending order", async () => {
61
+ let r = SortKey_Filter.apply(~items, ~skField, ~reverse=true)
62
+ expect(getSks(r))->toEqual(["science/2026-01", "math/2026-02", "math/2026-01", "art/2026-02", "art/2026-01"])
63
+ })
64
+
65
+ testPromise("limit returns first N items", async () => {
66
+ let r = SortKey_Filter.apply(~items, ~skField, ~limit=2)
67
+ expect(getSks(r))->toEqual(["art/2026-01", "art/2026-02"])
68
+ expect(r.nextToken)->toBe(Some("2"))
69
+ })
70
+
71
+ testPromise("nextToken resumes from offset", async () => {
72
+ let r = SortKey_Filter.apply(~items, ~skField, ~limit=2, ~offset=2)
73
+ expect(getSks(r))->toEqual(["math/2026-01", "math/2026-02"])
74
+ expect(r.nextToken)->toBe(Some("4"))
75
+ })
76
+
77
+ testPromise("last page has no nextToken", async () => {
78
+ let r = SortKey_Filter.apply(~items, ~skField, ~limit=2, ~offset=4)
79
+ expect(getSks(r))->toEqual(["science/2026-01"])
80
+ expect(r.nextToken)->toBe(None)
81
+ })
82
+
83
+ testPromise("prefix + limit + nextToken paginates correctly", async () => {
84
+ let r1 = SortKey_Filter.apply(~items, ~skField, ~prefix="art", ~limit=1)
85
+ expect(getSks(r1))->toEqual(["art/2026-01"])
86
+ expect(r1.nextToken)->toBe(Some("1"))
87
+ let r2 = SortKey_Filter.apply(~items, ~skField, ~prefix="art", ~limit=1, ~offset=1)
88
+ expect(getSks(r2))->toEqual(["art/2026-02"])
89
+ expect(r2.nextToken)->toBe(None)
90
+ })
91
+
92
+ testPromise("reverse + limit returns last N items", async () => {
93
+ let r = SortKey_Filter.apply(~items, ~skField, ~reverse=true, ~limit=3)
94
+ expect(getSks(r))->toEqual(["science/2026-01", "math/2026-02", "math/2026-01"])
95
+ expect(r.nextToken)->toBe(Some("3"))
96
+ })
97
+
98
+ testPromise("eq with no match returns empty", async () => {
99
+ let r = SortKey_Filter.apply(~items, ~skField, ~eq="nonexistent")
100
+ expect(r.items->Array.length)->toBe(0)
101
+ expect(r.nextToken)->toBe(None)
102
+ })
103
+ })