@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.
- package/CHANGELOG.md +1197 -0
- package/LICENSE +202 -0
- package/__mocks__/emptyModule.js +2 -0
- package/__mocks__/nodeSqlite.mjs +6 -0
- package/package.json +67 -0
- package/rescript.json +39 -0
- package/src/Platform.res +2162 -0
- package/src/Platform.res.mjs +3389 -0
- package/src/adapter/Api/LocalGraphQL_Adapter.res +29 -0
- package/src/adapter/Api/LocalGraphQL_Adapter.res.mjs +26 -0
- package/src/adapter/Api/LocalGraphQL_SubscriptionResolvers.res +146 -0
- package/src/adapter/Api/LocalGraphQL_SubscriptionResolvers.res.mjs +88 -0
- package/src/adapter/Auth/Auth_GraphqlContext.res +83 -0
- package/src/adapter/Auth/Auth_GraphqlContext.res.mjs +76 -0
- package/src/adapter/Auth/LocalAuth.res +239 -0
- package/src/adapter/Auth/LocalAuth.res.mjs +247 -0
- package/src/adapter/Auth/UserStore.res +134 -0
- package/src/adapter/Auth/UserStore.res.mjs +146 -0
- package/src/adapter/Backend.res +46 -0
- package/src/adapter/Backend.res.mjs +66 -0
- package/src/adapter/BackendState.res +34 -0
- package/src/adapter/BackendState.res.mjs +42 -0
- package/src/adapter/Cloner/LocalClonerRunner.res +13 -0
- package/src/adapter/Cloner/LocalClonerRunner.res.mjs +12 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +329 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res.mjs +301 -0
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +76 -0
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res.mjs +57 -0
- package/src/adapter/CommandGenerator/LocalCommandGeneratorResolvers.res +19 -0
- package/src/adapter/CommandGenerator/LocalCommandGeneratorResolvers.res.mjs +19 -0
- package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +104 -0
- package/src/adapter/CommandTopic/LocalCommandTopicChannel.res.mjs +82 -0
- package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +32 -0
- package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res.mjs +38 -0
- package/src/adapter/Counter/LocalCounterHandler.res +42 -0
- package/src/adapter/Counter/LocalCounterHandler.res.mjs +45 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +131 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res.mjs +140 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +334 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res.mjs +299 -0
- package/src/adapter/DomainGraphQL_Server.res +565 -0
- package/src/adapter/DomainGraphQL_Server.res.mjs +576 -0
- package/src/adapter/DomainMCP_Server.res +369 -0
- package/src/adapter/DomainMCP_Server.res.mjs +358 -0
- package/src/adapter/EventCollector/LocalEventCollectorChannel.res +87 -0
- package/src/adapter/EventCollector/LocalEventCollectorChannel.res.mjs +45 -0
- package/src/adapter/EventLog/EventLogStorage_InMemory.res +105 -0
- package/src/adapter/EventLog/EventLogStorage_InMemory.res.mjs +117 -0
- package/src/adapter/EventLog/EventLogStorage_Sqlite.res +145 -0
- package/src/adapter/EventLog/EventLogStorage_Sqlite.res.mjs +155 -0
- package/src/adapter/EventTopic/LocalEventTopicPublisher.res +36 -0
- package/src/adapter/EventTopic/LocalEventTopicPublisher.res.mjs +31 -0
- package/src/adapter/GraphQL_Server.res +6 -0
- package/src/adapter/GraphQL_Server.res.mjs +154 -0
- package/src/adapter/GraphQL_ServerInstance.res +310 -0
- package/src/adapter/GraphQL_ServerInstance.res.mjs +257 -0
- package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +57 -0
- package/src/adapter/Heartbeat/LocalHeartbeatRunner.res.mjs +34 -0
- package/src/adapter/LocalBus.res +498 -0
- package/src/adapter/LocalBus.res.mjs +1011 -0
- package/src/adapter/LocalPluginSpec.res +16 -0
- package/src/adapter/LocalPluginSpec.res.mjs +33 -0
- package/src/adapter/LocalSideEffectHandler.res +44 -0
- package/src/adapter/LocalSideEffectHandler.res.mjs +34 -0
- package/src/adapter/MCP_Server.res +4 -0
- package/src/adapter/MCP_Server.res.mjs +67 -0
- package/src/adapter/MCP_ServerInstance.res +362 -0
- package/src/adapter/MCP_ServerInstance.res.mjs +313 -0
- package/src/adapter/PlatformGraphQL_Server.res +75 -0
- package/src/adapter/PlatformGraphQL_Server.res.mjs +84 -0
- package/src/adapter/PlatformMCP_Server.res +23 -0
- package/src/adapter/PlatformMCP_Server.res.mjs +46 -0
- package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +793 -0
- package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res.mjs +569 -0
- package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +242 -0
- package/src/adapter/QueryDb/QueryDbStorage_InMemory.res.mjs +241 -0
- package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +339 -0
- package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res.mjs +318 -0
- package/src/adapter/QueryDb/SortKey_Filter.res +48 -0
- package/src/adapter/QueryDb/SortKey_Filter.res.mjs +46 -0
- package/src/adapter/QueryEngine/LocalQueryEngine.res +57 -0
- package/src/adapter/QueryEngine/LocalQueryEngine.res.mjs +56 -0
- package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +91 -0
- package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res.mjs +50 -0
- package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +47 -0
- package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res.mjs +37 -0
- package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +11 -0
- package/src/adapter/Runtime/LocalPluginRuntime_Builder.res.mjs +30 -0
- package/src/adapter/Runtime/LocalRuntimeEnvironment.res +54 -0
- package/src/adapter/Runtime/LocalRuntimeEnvironment.res.mjs +40 -0
- package/src/adapter/Scheduler/LocalScheduledPublisher.res +102 -0
- package/src/adapter/Scheduler/LocalScheduledPublisher.res.mjs +84 -0
- package/src/adapter/SqliteDriver.res +52 -0
- package/src/adapter/SqliteDriver.res.mjs +76 -0
- package/src/adapter/SqliteDriver.resi +31 -0
- package/src/adapter/Task/LocalTaskBucket.res +75 -0
- package/src/adapter/Task/LocalTaskBucket.res.mjs +48 -0
- package/src/adapter/Task/TaskBucket_Sqlite.res +47 -0
- package/src/adapter/Task/TaskBucket_Sqlite.res.mjs +40 -0
- package/src/components/Aggregate_Builder.res +55 -0
- package/src/components/Aggregate_Builder.res.mjs +140 -0
- package/src/components/AutomationSlice_Builder.res +41 -0
- package/src/components/AutomationSlice_Builder.res.mjs +57 -0
- package/src/components/Counter_Builder.res +14 -0
- package/src/components/Counter_Builder.res.mjs +32 -0
- package/src/components/DcbEventLog_Builder.res +18 -0
- package/src/components/DcbEventLog_Builder.res.mjs +24 -0
- package/src/components/ExtensionPoint_Builder.res +25 -0
- package/src/components/ExtensionPoint_Builder.res.mjs +44 -0
- package/src/components/InboundTranslationSlice_Builder.res +34 -0
- package/src/components/InboundTranslationSlice_Builder.res.mjs +45 -0
- package/src/components/OutboundTranslationSlice_Builder.res +43 -0
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +59 -0
- package/src/components/Plugin_Builder.res +37 -0
- package/src/components/Plugin_Builder.res.mjs +67 -0
- package/src/components/ReadModel_Builder.res +47 -0
- package/src/components/ReadModel_Builder.res.mjs +54 -0
- package/src/components/StateChangeSlice_Builder.res +19 -0
- package/src/components/StateChangeSlice_Builder.res.mjs +21 -0
- package/src/components/StateViewSlice_Builder.res +42 -0
- package/src/components/StateViewSlice_Builder.res.mjs +58 -0
- package/src/components/Task_Builder.res +28 -0
- package/src/components/Task_Builder.res.mjs +41 -0
- package/src/reexport/CommandTopic.res +3 -0
- package/src/reexport/CommandTopic.res.mjs +55 -0
- package/src/test/Mocks/MockDcbEventLogStorage.res +136 -0
- package/src/test/Mocks/MockDcbEventLogStorage.res.mjs +146 -0
- package/src/test/Mocks/MockEventLogStorage.res +57 -0
- package/src/test/Mocks/MockEventLogStorage.res.mjs +65 -0
- package/src/test/Mocks/MockPublisher.res +29 -0
- package/src/test/Mocks/MockPublisher.res.mjs +28 -0
- package/src/test/Mocks/MockQueryDbStorage.res +104 -0
- package/src/test/Mocks/MockQueryDbStorage.res.mjs +136 -0
- package/src/test/TestRunner.res +96 -0
- package/src/test/TestRunner.res.mjs +71 -0
- package/tests/SplitApiFixtures.res +84 -0
- package/tests/SplitApiFixtures.res.mjs +88 -0
- package/tests/SplitApiTest.res +102 -0
- package/tests/SplitApiTest.res.mjs +82 -0
- package/tests/TestFixtures.res +54 -0
- package/tests/TestFixtures.res.mjs +65 -0
- package/tests/adapter/BackendParityTest.res +94 -0
- package/tests/adapter/BackendParityTest.res.mjs +96 -0
- package/tests/adapter/CollectNEventsTest.res +82 -0
- package/tests/adapter/CollectNEventsTest.res.mjs +83 -0
- package/tests/adapter/CommandAuthorizationTest.res +200 -0
- package/tests/adapter/CommandAuthorizationTest.res.mjs +190 -0
- package/tests/adapter/CommandTopicChannelTest.res +174 -0
- package/tests/adapter/CommandTopicChannelTest.res.mjs +170 -0
- package/tests/adapter/CounterHandlerTest.res +113 -0
- package/tests/adapter/CounterHandlerTest.res.mjs +96 -0
- package/tests/adapter/DcbEventLogStorageSqliteTest.res +157 -0
- package/tests/adapter/DcbEventLogStorageSqliteTest.res.mjs +165 -0
- package/tests/adapter/DcbEventLogStorageTest.res +187 -0
- package/tests/adapter/DcbEventLogStorageTest.res.mjs +195 -0
- package/tests/adapter/EventCollectorChannelTest.res +166 -0
- package/tests/adapter/EventCollectorChannelTest.res.mjs +178 -0
- package/tests/adapter/EventLogStorageSqliteTest.res +105 -0
- package/tests/adapter/EventLogStorageSqliteTest.res.mjs +116 -0
- package/tests/adapter/EventTapTest.res +102 -0
- package/tests/adapter/EventTapTest.res.mjs +94 -0
- package/tests/adapter/EventTopicPublisherTest.res +76 -0
- package/tests/adapter/EventTopicPublisherTest.res.mjs +86 -0
- package/tests/adapter/GraphQL_SchemaInspectorTest.res +763 -0
- package/tests/adapter/GraphQL_SchemaInspectorTest.res.mjs +578 -0
- package/tests/adapter/GraphQL_SubscriptionResolversTest.res +161 -0
- package/tests/adapter/GraphQL_SubscriptionResolversTest.res.mjs +134 -0
- package/tests/adapter/HeartbeatRunnerTest.res +136 -0
- package/tests/adapter/HeartbeatRunnerTest.res.mjs +96 -0
- package/tests/adapter/LocalAuthHttpTest.res +224 -0
- package/tests/adapter/LocalAuthHttpTest.res.mjs +237 -0
- package/tests/adapter/LocalAuthLoginTest.res +180 -0
- package/tests/adapter/LocalAuthLoginTest.res.mjs +207 -0
- package/tests/adapter/LocalAuthTest.res +106 -0
- package/tests/adapter/LocalAuthTest.res.mjs +145 -0
- package/tests/adapter/LocalAuthUserStoreTest.res +172 -0
- package/tests/adapter/LocalAuthUserStoreTest.res.mjs +208 -0
- package/tests/adapter/LocalBusBoundedTest.res +157 -0
- package/tests/adapter/LocalBusBoundedTest.res.mjs +168 -0
- package/tests/adapter/LocalBusPubSubTest.res +81 -0
- package/tests/adapter/LocalBusPubSubTest.res.mjs +81 -0
- package/tests/adapter/QueryDbGsiTtlTest.res +268 -0
- package/tests/adapter/QueryDbGsiTtlTest.res.mjs +209 -0
- package/tests/adapter/QueryDbListResolverTest.res +361 -0
- package/tests/adapter/QueryDbListResolverTest.res.mjs +426 -0
- package/tests/adapter/QueryDbStorageSqliteTest.res +159 -0
- package/tests/adapter/QueryDbStorageSqliteTest.res.mjs +126 -0
- package/tests/adapter/QueryDbStorageTest.res +171 -0
- package/tests/adapter/QueryDbStorageTest.res.mjs +170 -0
- package/tests/adapter/QueryEngineTest.res +152 -0
- package/tests/adapter/QueryEngineTest.res.mjs +148 -0
- package/tests/adapter/ScheduledPublisherTest.res +199 -0
- package/tests/adapter/ScheduledPublisherTest.res.mjs +203 -0
- package/tests/adapter/SortKey_FilterTest.res +103 -0
- package/tests/adapter/SortKey_FilterTest.res.mjs +135 -0
- package/tests/adapter/SqliteDriverTest.res +86 -0
- package/tests/adapter/SqliteDriverTest.res.mjs +101 -0
- package/tests/adapter/TaskBucketSqliteTest.res +44 -0
- package/tests/adapter/TaskBucketSqliteTest.res.mjs +40 -0
- package/tests/adapter/TaskBucketTest.res +106 -0
- package/tests/adapter/TaskBucketTest.res.mjs +118 -0
- package/tests/components/aggregate/AggregateFixtures.res +78 -0
- package/tests/components/aggregate/AggregateFixtures.res.mjs +109 -0
- package/tests/components/aggregate/AggregateTest.res +129 -0
- package/tests/components/aggregate/AggregateTest.res.mjs +129 -0
- package/tests/components/automationslice/AutomationSliceCallbackTest.res +212 -0
- package/tests/components/automationslice/AutomationSliceCallbackTest.res.mjs +233 -0
- package/tests/components/automationslice/AutomationSliceFixtures.res +189 -0
- package/tests/components/automationslice/AutomationSliceFixtures.res.mjs +276 -0
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +289 -0
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res.mjs +453 -0
- package/tests/components/automationslice/AutomationSliceSelfDeadlockTest.res +47 -0
- package/tests/components/automationslice/AutomationSliceSelfDeadlockTest.res.mjs +31 -0
- package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +213 -0
- package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res.mjs +268 -0
- package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +118 -0
- package/tests/components/automationslice/MixedSourceAutomationSliceTest.res.mjs +99 -0
- package/tests/components/commandgenerator/CommandGeneratorFixtures.res +73 -0
- package/tests/components/commandgenerator/CommandGeneratorFixtures.res.mjs +109 -0
- package/tests/components/commandgenerator/CommandGeneratorTest.res +43 -0
- package/tests/components/commandgenerator/CommandGeneratorTest.res.mjs +46 -0
- package/tests/components/commandtopic/CommandTopicFixtures.res +37 -0
- package/tests/components/commandtopic/CommandTopicFixtures.res.mjs +68 -0
- package/tests/components/commandtopic/CommandTopicStreamFixtures.res +43 -0
- package/tests/components/commandtopic/CommandTopicStreamFixtures.res.mjs +91 -0
- package/tests/components/commandtopic/CommandTopicStreamTest.res +30 -0
- package/tests/components/commandtopic/CommandTopicStreamTest.res.mjs +35 -0
- package/tests/components/commandtopic/CommandTopicTest.res +55 -0
- package/tests/components/commandtopic/CommandTopicTest.res.mjs +62 -0
- package/tests/components/counter/CounterFixtures.res +42 -0
- package/tests/components/counter/CounterFixtures.res.mjs +34 -0
- package/tests/components/counter/CounterTest.res +46 -0
- package/tests/components/counter/CounterTest.res.mjs +61 -0
- package/tests/components/dcb/DcbCrossPartitionFixtures.res +170 -0
- package/tests/components/dcb/DcbCrossPartitionFixtures.res.mjs +276 -0
- package/tests/components/dcb/DcbCrossPartitionReadTest.res +68 -0
- package/tests/components/dcb/DcbCrossPartitionReadTest.res.mjs +78 -0
- package/tests/components/dcb/DcbEventLogAppendStreamTest.res +72 -0
- package/tests/components/dcb/DcbEventLogAppendStreamTest.res.mjs +82 -0
- package/tests/components/dcb/DcbEventLogStreamTest.res +103 -0
- package/tests/components/dcb/DcbEventLogStreamTest.res.mjs +91 -0
- package/tests/components/dcb/DcbFixtures.res +145 -0
- package/tests/components/dcb/DcbFixtures.res.mjs +221 -0
- package/tests/components/dcb/DcbTest.res +55 -0
- package/tests/components/dcb/DcbTest.res.mjs +55 -0
- package/tests/components/eventcollector/EventCollectorFixtures.res +42 -0
- package/tests/components/eventcollector/EventCollectorFixtures.res.mjs +49 -0
- package/tests/components/eventcollector/EventCollectorTest.res +37 -0
- package/tests/components/eventcollector/EventCollectorTest.res.mjs +36 -0
- package/tests/components/eventlog/EventLogAppendStreamTest.res +93 -0
- package/tests/components/eventlog/EventLogAppendStreamTest.res.mjs +113 -0
- package/tests/components/eventlog/EventLogConflictTest.res +86 -0
- package/tests/components/eventlog/EventLogConflictTest.res.mjs +81 -0
- package/tests/components/eventlog/EventLogFixtures.res +52 -0
- package/tests/components/eventlog/EventLogFixtures.res.mjs +80 -0
- package/tests/components/eventlog/EventLogStreamTest.res +98 -0
- package/tests/components/eventlog/EventLogStreamTest.res.mjs +142 -0
- package/tests/components/eventlog/EventLogTest.res +53 -0
- package/tests/components/eventlog/EventLogTest.res.mjs +74 -0
- package/tests/components/eventtopic/EventTopicFixtures.res +47 -0
- package/tests/components/eventtopic/EventTopicFixtures.res.mjs +77 -0
- package/tests/components/eventtopic/EventTopicStreamFixtures.res +27 -0
- package/tests/components/eventtopic/EventTopicStreamFixtures.res.mjs +62 -0
- package/tests/components/eventtopic/EventTopicStreamTest.res +35 -0
- package/tests/components/eventtopic/EventTopicStreamTest.res.mjs +44 -0
- package/tests/components/eventtopic/EventTopicTest.res +35 -0
- package/tests/components/eventtopic/EventTopicTest.res.mjs +43 -0
- package/tests/components/extensionpoint/ExtensionPointFixtures.res +145 -0
- package/tests/components/extensionpoint/ExtensionPointFixtures.res.mjs +188 -0
- package/tests/components/extensionpoint/ExtensionPointTest.res +62 -0
- package/tests/components/extensionpoint/ExtensionPointTest.res.mjs +55 -0
- package/tests/components/heartbeat/HeartbeatFixtures.res +48 -0
- package/tests/components/heartbeat/HeartbeatFixtures.res.mjs +46 -0
- package/tests/components/heartbeat/HeartbeatTest.res +67 -0
- package/tests/components/heartbeat/HeartbeatTest.res.mjs +65 -0
- package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +241 -0
- package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res.mjs +239 -0
- package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +36 -0
- package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res.mjs +73 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +191 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res.mjs +297 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +78 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res.mjs +137 -0
- package/tests/components/querydb/QueryDbFixtures.res +39 -0
- package/tests/components/querydb/QueryDbFixtures.res.mjs +73 -0
- package/tests/components/querydb/QueryDbSubIdFixtures.res +44 -0
- package/tests/components/querydb/QueryDbSubIdFixtures.res.mjs +80 -0
- package/tests/components/querydb/QueryDbSubIdTest.res +104 -0
- package/tests/components/querydb/QueryDbSubIdTest.res.mjs +104 -0
- package/tests/components/querydb/QueryDbTest.res +81 -0
- package/tests/components/querydb/QueryDbTest.res.mjs +126 -0
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res +215 -0
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res.mjs +308 -0
- package/tests/components/readmodel/DcbReadModelE2ETest.res +45 -0
- package/tests/components/readmodel/DcbReadModelE2ETest.res.mjs +37 -0
- package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res +88 -0
- package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res.mjs +152 -0
- package/tests/components/readmodel/MixedSourceReadModelFixtures.res +181 -0
- package/tests/components/readmodel/MixedSourceReadModelFixtures.res.mjs +277 -0
- package/tests/components/readmodel/MixedSourceReadModelTest.res +61 -0
- package/tests/components/readmodel/MixedSourceReadModelTest.res.mjs +68 -0
- package/tests/components/readmodel/ReadModelFixtures.res +138 -0
- package/tests/components/readmodel/ReadModelFixtures.res.mjs +169 -0
- package/tests/components/readmodel/ReadModelTest.res +46 -0
- package/tests/components/readmodel/ReadModelTest.res.mjs +36 -0
- package/tests/components/scheduler/SchedulerFixtures.res +59 -0
- package/tests/components/scheduler/SchedulerFixtures.res.mjs +63 -0
- package/tests/components/scheduler/SchedulerTest.res +76 -0
- package/tests/components/scheduler/SchedulerTest.res.mjs +86 -0
- package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +133 -0
- package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res.mjs +149 -0
- package/tests/components/sideeffecthandler/SideEffectHandlerTest.res +39 -0
- package/tests/components/sideeffecthandler/SideEffectHandlerTest.res.mjs +28 -0
- package/tests/components/stateviewslice/StateViewSliceFixtures.res +117 -0
- package/tests/components/stateviewslice/StateViewSliceFixtures.res.mjs +188 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +117 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res.mjs +183 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +78 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdTest.res.mjs +107 -0
- package/tests/components/stateviewslice/StateViewSliceTest.res +59 -0
- package/tests/components/stateviewslice/StateViewSliceTest.res.mjs +72 -0
- package/tests/components/task/TaskFixtures.res +87 -0
- package/tests/components/task/TaskFixtures.res.mjs +82 -0
- package/tests/components/task/TaskTest.res +98 -0
- package/tests/components/task/TaskTest.res.mjs +46 -0
- package/tests/plugin/PluginBehavior_GWT.res +146 -0
- package/tests/plugin/PluginBehavior_GWT.res.mjs +281 -0
- package/tests/plugin/Plugin_Fixtures.res +61 -0
- package/tests/plugin/Plugin_Fixtures.res.mjs +105 -0
- package/tests/plugin/PluginsProjection_GWT.res +95 -0
- package/tests/plugin/PluginsProjection_GWT.res.mjs +120 -0
- package/tests/plugin/UIFragmentRegistryProjection_GWT.res +72 -0
- package/tests/plugin/UIFragmentRegistryProjection_GWT.res.mjs +117 -0
- package/tests/setup/sqliteGlobal.cjs +12 -0
|
@@ -0,0 +1,183 @@
|
|
|
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 Effect from "effect/Effect";
|
|
6
|
+
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
7
|
+
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
8
|
+
import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
|
|
9
|
+
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
10
|
+
import * as LocalBus$ReventlessLocal from "../../../src/adapter/LocalBus.res.mjs";
|
|
11
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
12
|
+
import * as DcbEventLog_Builder$ReventlessLocal from "../../../src/components/DcbEventLog_Builder.res.mjs";
|
|
13
|
+
import * as StateViewSlice_Builder$ReventlessLocal from "../../../src/components/StateViewSlice_Builder.res.mjs";
|
|
14
|
+
|
|
15
|
+
let eventSchema = S.union([
|
|
16
|
+
S.schema(s => ({
|
|
17
|
+
TAG: "ScoreRecorded",
|
|
18
|
+
id: s.m(DcbTag$Reventless.string),
|
|
19
|
+
category: s.m(S.string),
|
|
20
|
+
date: s.m(S.string),
|
|
21
|
+
score: s.m(S.int)
|
|
22
|
+
})),
|
|
23
|
+
S.schema(s => ({
|
|
24
|
+
TAG: "ScoreRemoved",
|
|
25
|
+
id: s.m(DcbTag$Reventless.string),
|
|
26
|
+
category: s.m(S.string),
|
|
27
|
+
date: s.m(S.string)
|
|
28
|
+
}))
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
let ScoreEventLog = {
|
|
32
|
+
eventSchema: eventSchema
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let name = "ScoresView";
|
|
36
|
+
|
|
37
|
+
let moduleUrl = import.meta.url;
|
|
38
|
+
|
|
39
|
+
let consumedEventSchema = S.union([
|
|
40
|
+
S.schema(s => ({
|
|
41
|
+
TAG: "ScoreRecorded",
|
|
42
|
+
id: s.m(S.string),
|
|
43
|
+
category: s.m(S.string),
|
|
44
|
+
date: s.m(S.string),
|
|
45
|
+
score: s.m(S.int)
|
|
46
|
+
})),
|
|
47
|
+
S.schema(s => ({
|
|
48
|
+
TAG: "ScoreRemoved",
|
|
49
|
+
id: s.m(S.string),
|
|
50
|
+
category: s.m(S.string),
|
|
51
|
+
date: s.m(S.string)
|
|
52
|
+
}))
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
let stateSchema = S.schema(s => ({
|
|
56
|
+
id: s.m(S.string),
|
|
57
|
+
category: s.m(S.string),
|
|
58
|
+
date: s.m(S.string),
|
|
59
|
+
score: s.m(S.int)
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
let config = ReadModel$Reventless.config(undefined, undefined, undefined);
|
|
63
|
+
|
|
64
|
+
let subIdConfig = {
|
|
65
|
+
subIdField: "_subId",
|
|
66
|
+
getSubId: state => state.category + "/" + state.date
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
let ScoresViewSpec = {
|
|
70
|
+
name: name,
|
|
71
|
+
moduleUrl: moduleUrl,
|
|
72
|
+
consumedEventSchema: consumedEventSchema,
|
|
73
|
+
stateSchema: stateSchema,
|
|
74
|
+
config: config,
|
|
75
|
+
subIdConfig: subIdConfig,
|
|
76
|
+
authorization: "AllowAuthenticated",
|
|
77
|
+
visibility: "Public"
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
let moduleUrl$1 = import.meta.url;
|
|
81
|
+
|
|
82
|
+
function project(event) {
|
|
83
|
+
if (event.TAG !== "ScoreRecorded") {
|
|
84
|
+
return [{
|
|
85
|
+
TAG: "Delete",
|
|
86
|
+
_0: event.id
|
|
87
|
+
}];
|
|
88
|
+
}
|
|
89
|
+
let id = event.id;
|
|
90
|
+
return [{
|
|
91
|
+
TAG: "Set",
|
|
92
|
+
_0: id,
|
|
93
|
+
_1: {
|
|
94
|
+
id: id,
|
|
95
|
+
category: event.category,
|
|
96
|
+
date: event.date,
|
|
97
|
+
score: event.score
|
|
98
|
+
}
|
|
99
|
+
}];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let ScoresViewProjection = {
|
|
103
|
+
Spec: undefined,
|
|
104
|
+
moduleUrl: moduleUrl$1,
|
|
105
|
+
project: project
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
let Bus = LocalBus$ReventlessLocal.Make({});
|
|
109
|
+
|
|
110
|
+
TestRunner$ReventlessLocal.setup();
|
|
111
|
+
|
|
112
|
+
let ScoreEventLogMaker = DcbEventLog_Builder$ReventlessLocal.Make(Bus);
|
|
113
|
+
|
|
114
|
+
let eventLog = ScoreEventLogMaker.make("ScoreEventLog", undefined, {
|
|
115
|
+
TAG: "Simple",
|
|
116
|
+
_0: {
|
|
117
|
+
key: "id"
|
|
118
|
+
}
|
|
119
|
+
}, undefined);
|
|
120
|
+
|
|
121
|
+
let SVMaker = StateViewSlice_Builder$ReventlessLocal.Make(Bus);
|
|
122
|
+
|
|
123
|
+
let ScoresViewMaker = SVMaker.Make({
|
|
124
|
+
name: name,
|
|
125
|
+
moduleUrl: moduleUrl,
|
|
126
|
+
stateSchema: stateSchema,
|
|
127
|
+
consumedEventSchema: consumedEventSchema,
|
|
128
|
+
config: config,
|
|
129
|
+
subIdConfig: subIdConfig,
|
|
130
|
+
authorization: "AllowAuthenticated",
|
|
131
|
+
visibility: "Public"
|
|
132
|
+
})({
|
|
133
|
+
project: project,
|
|
134
|
+
moduleUrl: moduleUrl$1
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
let sv = ScoresViewMaker.make(eventLog, undefined);
|
|
138
|
+
|
|
139
|
+
let dcbEventTopicResource = Component$ReventlessCore.outputs(eventLog).eventTopic.resources[0];
|
|
140
|
+
|
|
141
|
+
function encodeEvent(event) {
|
|
142
|
+
let json = S.reverseConvertToJsonOrThrow(event, eventSchema);
|
|
143
|
+
let match = Message$ReventlessCore.splitMessage(json);
|
|
144
|
+
let tags = DcbTag$Reventless.extractTags(eventSchema, event);
|
|
145
|
+
let meta = Message$ReventlessCore.generateMeta("test", undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
146
|
+
return {
|
|
147
|
+
eventType: match[0],
|
|
148
|
+
data: match[1],
|
|
149
|
+
tags: tags,
|
|
150
|
+
meta: meta
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function appendEvent(event) {
|
|
155
|
+
let ops = await TestRunner$ReventlessLocal.resolve(ScoreEventLogMaker.operations(eventLog));
|
|
156
|
+
await ops.append([encodeEvent(event)], undefined);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function loadScores(id) {
|
|
160
|
+
let ops = Bus.getQueryDb("ScoresView");
|
|
161
|
+
if (ops === undefined) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
let states = await Effect.runPromise(Effect.catchAll(Stream.runCollect(ops.loadStream(id)), param => Effect.succeed([])));
|
|
165
|
+
return states.map(json => S.parseJsonOrThrow(json, stateSchema));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export {
|
|
169
|
+
ScoreEventLog,
|
|
170
|
+
ScoresViewSpec,
|
|
171
|
+
ScoresViewProjection,
|
|
172
|
+
Bus,
|
|
173
|
+
ScoreEventLogMaker,
|
|
174
|
+
eventLog,
|
|
175
|
+
SVMaker,
|
|
176
|
+
ScoresViewMaker,
|
|
177
|
+
sv,
|
|
178
|
+
dcbEventTopicResource,
|
|
179
|
+
encodeEvent,
|
|
180
|
+
appendEvent,
|
|
181
|
+
loadScores,
|
|
182
|
+
}
|
|
183
|
+
/* eventSchema Not a pure module */
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// E2E tests for StateViewSlice with sub-ID (composite sort key).
|
|
2
|
+
// Verifies that:
|
|
3
|
+
// - projected items are stored with the correct composite sub-key (_subId = category/date)
|
|
4
|
+
// - loadStream returns items sorted by sub-key
|
|
5
|
+
// - multiple sub-key items for the same partition key are all returned
|
|
6
|
+
|
|
7
|
+
open JestGlobals
|
|
8
|
+
open StateViewSliceSubIdFixtures
|
|
9
|
+
|
|
10
|
+
describe("StateViewSlice sub-ID E2E", () => {
|
|
11
|
+
let _ = beforeAllAsync(async () => {
|
|
12
|
+
let _ = await sv->ScoresViewMaker.operations->TestRunner.resolve
|
|
13
|
+
let _ = await dcbEventTopicResource.name->TestRunner.resolve
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
testPromise("ScoreRecorded stores item with composite sub-key", async () => {
|
|
17
|
+
let _ = await appendEvent(
|
|
18
|
+
ScoreEventLog.ScoreRecorded({id: "player-1", category: "math", date: "2026-01", score: 90}),
|
|
19
|
+
)
|
|
20
|
+
let scores = await loadScores("player-1")
|
|
21
|
+
expect(scores->Array.length)->toBe(1)
|
|
22
|
+
let s = scores->Array.getUnsafe(0)
|
|
23
|
+
expect(s.category)->toBe("math")
|
|
24
|
+
expect(s.score)->toBe(90)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
testPromise("multiple ScoreRecorded events for same id are all kept", async () => {
|
|
28
|
+
let _ = await appendEvent(
|
|
29
|
+
ScoreEventLog.ScoreRecorded({id: "player-2", category: "math", date: "2026-01", score: 80}),
|
|
30
|
+
)
|
|
31
|
+
let _ = await appendEvent(
|
|
32
|
+
ScoreEventLog.ScoreRecorded({id: "player-2", category: "science", date: "2026-01", score: 95}),
|
|
33
|
+
)
|
|
34
|
+
let _ = await appendEvent(
|
|
35
|
+
ScoreEventLog.ScoreRecorded({id: "player-2", category: "math", date: "2026-02", score: 85}),
|
|
36
|
+
)
|
|
37
|
+
let scores = await loadScores("player-2")
|
|
38
|
+
expect(scores->Array.length)->toBe(3)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
testPromise("loadStream returns sub-key items in alphabetical order", async () => {
|
|
42
|
+
let _ = await appendEvent(
|
|
43
|
+
ScoreEventLog.ScoreRecorded({id: "player-3", category: "science", date: "2026-03", score: 70}),
|
|
44
|
+
)
|
|
45
|
+
let _ = await appendEvent(
|
|
46
|
+
ScoreEventLog.ScoreRecorded({id: "player-3", category: "math", date: "2026-01", score: 88}),
|
|
47
|
+
)
|
|
48
|
+
let _ = await appendEvent(
|
|
49
|
+
ScoreEventLog.ScoreRecorded({id: "player-3", category: "art", date: "2026-02", score: 77}),
|
|
50
|
+
)
|
|
51
|
+
let scores = await loadScores("player-3")
|
|
52
|
+
expect(scores->Array.length)->toBe(3)
|
|
53
|
+
// Sub-keys: "art/2026-02", "math/2026-01", "science/2026-03" — alphabetical order
|
|
54
|
+
let s0 = scores->Array.getUnsafe(0)
|
|
55
|
+
let s1 = scores->Array.getUnsafe(1)
|
|
56
|
+
let s2 = scores->Array.getUnsafe(2)
|
|
57
|
+
expect(s0.category)->toBe("art")
|
|
58
|
+
expect(s1.category)->toBe("math")
|
|
59
|
+
expect(s2.category)->toBe("science")
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
testPromise("items for different players are independent", async () => {
|
|
63
|
+
let _ = await appendEvent(
|
|
64
|
+
ScoreEventLog.ScoreRecorded({id: "player-4", category: "math", date: "2026-01", score: 60}),
|
|
65
|
+
)
|
|
66
|
+
let _ = await appendEvent(
|
|
67
|
+
ScoreEventLog.ScoreRecorded({id: "player-5", category: "math", date: "2026-01", score: 100}),
|
|
68
|
+
)
|
|
69
|
+
let scores4 = await loadScores("player-4")
|
|
70
|
+
let scores5 = await loadScores("player-5")
|
|
71
|
+
expect(scores4->Array.length)->toBe(1)
|
|
72
|
+
expect(scores5->Array.length)->toBe(1)
|
|
73
|
+
let s4 = scores4->Array.getUnsafe(0)
|
|
74
|
+
let s5 = scores5->Array.getUnsafe(0)
|
|
75
|
+
expect(s4.score)->toBe(60)
|
|
76
|
+
expect(s5.score)->toBe(100)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
4
|
+
import * as StateViewSliceSubIdFixtures$ReventlessLocal from "./StateViewSliceSubIdFixtures.res.mjs";
|
|
5
|
+
|
|
6
|
+
globalThis.describe("StateViewSlice sub-ID E2E", () => {
|
|
7
|
+
globalThis.beforeAll(async () => {
|
|
8
|
+
await TestRunner$ReventlessLocal.resolve(StateViewSliceSubIdFixtures$ReventlessLocal.ScoresViewMaker.operations(StateViewSliceSubIdFixtures$ReventlessLocal.sv));
|
|
9
|
+
await TestRunner$ReventlessLocal.resolve(StateViewSliceSubIdFixtures$ReventlessLocal.dcbEventTopicResource.name);
|
|
10
|
+
});
|
|
11
|
+
globalThis.test("ScoreRecorded stores item with composite sub-key", async () => {
|
|
12
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
13
|
+
TAG: "ScoreRecorded",
|
|
14
|
+
id: "player-1",
|
|
15
|
+
category: "math",
|
|
16
|
+
date: "2026-01",
|
|
17
|
+
score: 90
|
|
18
|
+
});
|
|
19
|
+
let scores = await StateViewSliceSubIdFixtures$ReventlessLocal.loadScores("player-1");
|
|
20
|
+
globalThis.expect(scores.length).toBe(1);
|
|
21
|
+
let s = scores[0];
|
|
22
|
+
globalThis.expect(s.category).toBe("math");
|
|
23
|
+
globalThis.expect(s.score).toBe(90);
|
|
24
|
+
});
|
|
25
|
+
globalThis.test("multiple ScoreRecorded events for same id are all kept", async () => {
|
|
26
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
27
|
+
TAG: "ScoreRecorded",
|
|
28
|
+
id: "player-2",
|
|
29
|
+
category: "math",
|
|
30
|
+
date: "2026-01",
|
|
31
|
+
score: 80
|
|
32
|
+
});
|
|
33
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
34
|
+
TAG: "ScoreRecorded",
|
|
35
|
+
id: "player-2",
|
|
36
|
+
category: "science",
|
|
37
|
+
date: "2026-01",
|
|
38
|
+
score: 95
|
|
39
|
+
});
|
|
40
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
41
|
+
TAG: "ScoreRecorded",
|
|
42
|
+
id: "player-2",
|
|
43
|
+
category: "math",
|
|
44
|
+
date: "2026-02",
|
|
45
|
+
score: 85
|
|
46
|
+
});
|
|
47
|
+
let scores = await StateViewSliceSubIdFixtures$ReventlessLocal.loadScores("player-2");
|
|
48
|
+
globalThis.expect(scores.length).toBe(3);
|
|
49
|
+
});
|
|
50
|
+
globalThis.test("loadStream returns sub-key items in alphabetical order", async () => {
|
|
51
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
52
|
+
TAG: "ScoreRecorded",
|
|
53
|
+
id: "player-3",
|
|
54
|
+
category: "science",
|
|
55
|
+
date: "2026-03",
|
|
56
|
+
score: 70
|
|
57
|
+
});
|
|
58
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
59
|
+
TAG: "ScoreRecorded",
|
|
60
|
+
id: "player-3",
|
|
61
|
+
category: "math",
|
|
62
|
+
date: "2026-01",
|
|
63
|
+
score: 88
|
|
64
|
+
});
|
|
65
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
66
|
+
TAG: "ScoreRecorded",
|
|
67
|
+
id: "player-3",
|
|
68
|
+
category: "art",
|
|
69
|
+
date: "2026-02",
|
|
70
|
+
score: 77
|
|
71
|
+
});
|
|
72
|
+
let scores = await StateViewSliceSubIdFixtures$ReventlessLocal.loadScores("player-3");
|
|
73
|
+
globalThis.expect(scores.length).toBe(3);
|
|
74
|
+
let s0 = scores[0];
|
|
75
|
+
let s1 = scores[1];
|
|
76
|
+
let s2 = scores[2];
|
|
77
|
+
globalThis.expect(s0.category).toBe("art");
|
|
78
|
+
globalThis.expect(s1.category).toBe("math");
|
|
79
|
+
globalThis.expect(s2.category).toBe("science");
|
|
80
|
+
});
|
|
81
|
+
globalThis.test("items for different players are independent", async () => {
|
|
82
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
83
|
+
TAG: "ScoreRecorded",
|
|
84
|
+
id: "player-4",
|
|
85
|
+
category: "math",
|
|
86
|
+
date: "2026-01",
|
|
87
|
+
score: 60
|
|
88
|
+
});
|
|
89
|
+
await StateViewSliceSubIdFixtures$ReventlessLocal.appendEvent({
|
|
90
|
+
TAG: "ScoreRecorded",
|
|
91
|
+
id: "player-5",
|
|
92
|
+
category: "math",
|
|
93
|
+
date: "2026-01",
|
|
94
|
+
score: 100
|
|
95
|
+
});
|
|
96
|
+
let scores4 = await StateViewSliceSubIdFixtures$ReventlessLocal.loadScores("player-4");
|
|
97
|
+
let scores5 = await StateViewSliceSubIdFixtures$ReventlessLocal.loadScores("player-5");
|
|
98
|
+
globalThis.expect(scores4.length).toBe(1);
|
|
99
|
+
globalThis.expect(scores5.length).toBe(1);
|
|
100
|
+
let s4 = scores4[0];
|
|
101
|
+
let s5 = scores5[0];
|
|
102
|
+
globalThis.expect(s4.score).toBe(60);
|
|
103
|
+
globalThis.expect(s5.score).toBe(100);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// E2E tests for StateViewSlice_Builder.
|
|
2
|
+
// Verifies the full DcbEventLog.append → event topic → EventCollector → projection → QueryDb pipeline.
|
|
3
|
+
|
|
4
|
+
open JestGlobals
|
|
5
|
+
open StateViewSliceFixtures
|
|
6
|
+
|
|
7
|
+
describe("StateViewSlice E2E", () => {
|
|
8
|
+
// TWO resolves needed (same pattern as ReadModel E2E):
|
|
9
|
+
// 1. sv.operations chain — triggers queryDb.operations.apply which creates EventCollector
|
|
10
|
+
// and calls EventCollectorRuntimeBuilder.forEventCollector as a side effect.
|
|
11
|
+
// 2. dcbEventTopicResource.name — triggers EventCollectorChannel.connect inner
|
|
12
|
+
// resource.name.apply, which registers the Bus.subscribeToEvents handler.
|
|
13
|
+
let _ = beforeAllAsync(async () => {
|
|
14
|
+
let _ = await sv->ItemsViewMaker.operations->TestRunner.resolve
|
|
15
|
+
let _ = await dcbEventTopicResource.name->TestRunner.resolve
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
testPromise("ItemAdded event projects to QueryDb state", async () => {
|
|
19
|
+
let _ = await appendEvent(ItemEventLog.ItemAdded({id: "item-1", name: "Widget"}))
|
|
20
|
+
let states = await loadState("item-1")
|
|
21
|
+
expect(states->Array.length)->toBe(1)
|
|
22
|
+
let s = states->Array.getUnsafe(0)
|
|
23
|
+
expect(s.name)->toBe("Widget")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
testPromise("ItemRenamed event updates existing state", async () => {
|
|
27
|
+
// item-1 already exists from previous test (shared state across tests in this describe)
|
|
28
|
+
let _ = await appendEvent(ItemEventLog.ItemRenamed({id: "item-1", name: "SuperWidget"}))
|
|
29
|
+
let states = await loadState("item-1")
|
|
30
|
+
expect(states->Array.length)->toBe(1)
|
|
31
|
+
let s = states->Array.getUnsafe(0)
|
|
32
|
+
expect(s.name)->toBe("SuperWidget")
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
testPromise("multiple items projected independently", async () => {
|
|
36
|
+
let _ = await appendEvent(ItemEventLog.ItemAdded({id: "item-2", name: "Gadget"}))
|
|
37
|
+
let _ = await appendEvent(ItemEventLog.ItemAdded({id: "item-3", name: "Doohickey"}))
|
|
38
|
+
let states2 = await loadState("item-2")
|
|
39
|
+
let states3 = await loadState("item-3")
|
|
40
|
+
expect(states2->Array.length)->toBe(1)
|
|
41
|
+
expect(states3->Array.length)->toBe(1)
|
|
42
|
+
let s2 = states2->Array.getUnsafe(0)
|
|
43
|
+
let s3 = states3->Array.getUnsafe(0)
|
|
44
|
+
expect(s2.name)->toBe("Gadget")
|
|
45
|
+
expect(s3.name)->toBe("Doohickey")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
testPromise("ItemRemoved event deletes state from QueryDb", async () => {
|
|
49
|
+
let _ = await appendEvent(ItemEventLog.ItemAdded({id: "item-4", name: "Temp"}))
|
|
50
|
+
let _ = await appendEvent(ItemEventLog.ItemRemoved({id: "item-4"}))
|
|
51
|
+
let states = await loadState("item-4")
|
|
52
|
+
expect(states->Array.length)->toBe(0)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
testPromise("query for unknown ID returns empty", async () => {
|
|
56
|
+
let states = await loadState("no-such-item")
|
|
57
|
+
expect(states->Array.length)->toBe(0)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
4
|
+
import * as StateViewSliceFixtures$ReventlessLocal from "./StateViewSliceFixtures.res.mjs";
|
|
5
|
+
|
|
6
|
+
globalThis.describe("StateViewSlice E2E", () => {
|
|
7
|
+
globalThis.beforeAll(async () => {
|
|
8
|
+
await TestRunner$ReventlessLocal.resolve(StateViewSliceFixtures$ReventlessLocal.ItemsViewMaker.operations(StateViewSliceFixtures$ReventlessLocal.sv));
|
|
9
|
+
await TestRunner$ReventlessLocal.resolve(StateViewSliceFixtures$ReventlessLocal.dcbEventTopicResource.name);
|
|
10
|
+
});
|
|
11
|
+
globalThis.test("ItemAdded event projects to QueryDb state", async () => {
|
|
12
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
13
|
+
TAG: "ItemAdded",
|
|
14
|
+
id: "item-1",
|
|
15
|
+
name: "Widget"
|
|
16
|
+
});
|
|
17
|
+
let states = await StateViewSliceFixtures$ReventlessLocal.loadState("item-1");
|
|
18
|
+
globalThis.expect(states.length).toBe(1);
|
|
19
|
+
let s = states[0];
|
|
20
|
+
globalThis.expect(s.name).toBe("Widget");
|
|
21
|
+
});
|
|
22
|
+
globalThis.test("ItemRenamed event updates existing state", async () => {
|
|
23
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
24
|
+
TAG: "ItemRenamed",
|
|
25
|
+
id: "item-1",
|
|
26
|
+
name: "SuperWidget"
|
|
27
|
+
});
|
|
28
|
+
let states = await StateViewSliceFixtures$ReventlessLocal.loadState("item-1");
|
|
29
|
+
globalThis.expect(states.length).toBe(1);
|
|
30
|
+
let s = states[0];
|
|
31
|
+
globalThis.expect(s.name).toBe("SuperWidget");
|
|
32
|
+
});
|
|
33
|
+
globalThis.test("multiple items projected independently", async () => {
|
|
34
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
35
|
+
TAG: "ItemAdded",
|
|
36
|
+
id: "item-2",
|
|
37
|
+
name: "Gadget"
|
|
38
|
+
});
|
|
39
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
40
|
+
TAG: "ItemAdded",
|
|
41
|
+
id: "item-3",
|
|
42
|
+
name: "Doohickey"
|
|
43
|
+
});
|
|
44
|
+
let states2 = await StateViewSliceFixtures$ReventlessLocal.loadState("item-2");
|
|
45
|
+
let states3 = await StateViewSliceFixtures$ReventlessLocal.loadState("item-3");
|
|
46
|
+
globalThis.expect(states2.length).toBe(1);
|
|
47
|
+
globalThis.expect(states3.length).toBe(1);
|
|
48
|
+
let s2 = states2[0];
|
|
49
|
+
let s3 = states3[0];
|
|
50
|
+
globalThis.expect(s2.name).toBe("Gadget");
|
|
51
|
+
globalThis.expect(s3.name).toBe("Doohickey");
|
|
52
|
+
});
|
|
53
|
+
globalThis.test("ItemRemoved event deletes state from QueryDb", async () => {
|
|
54
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
55
|
+
TAG: "ItemAdded",
|
|
56
|
+
id: "item-4",
|
|
57
|
+
name: "Temp"
|
|
58
|
+
});
|
|
59
|
+
await StateViewSliceFixtures$ReventlessLocal.appendEvent({
|
|
60
|
+
TAG: "ItemRemoved",
|
|
61
|
+
id: "item-4"
|
|
62
|
+
});
|
|
63
|
+
let states = await StateViewSliceFixtures$ReventlessLocal.loadState("item-4");
|
|
64
|
+
globalThis.expect(states.length).toBe(0);
|
|
65
|
+
});
|
|
66
|
+
globalThis.test("query for unknown ID returns empty", async () => {
|
|
67
|
+
let states = await StateViewSliceFixtures$ReventlessLocal.loadState("no-such-item");
|
|
68
|
+
globalThis.expect(states.length).toBe(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Fixtures for Task integration tests.
|
|
2
|
+
// Tests Task_Builder.Make wiring with in-memory adapters.
|
|
3
|
+
|
|
4
|
+
S.enableJson()
|
|
5
|
+
|
|
6
|
+
// Activate Pulumi mock mode (must be called before any Component.make)
|
|
7
|
+
let _ = TestRunner.setup()
|
|
8
|
+
|
|
9
|
+
// ─────────────────────────────────────────────────────────────
|
|
10
|
+
// Isolated bus
|
|
11
|
+
// ─────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
module Bus = LocalBus.Make()
|
|
14
|
+
|
|
15
|
+
// ─────────────────────────────────────────────────────────────
|
|
16
|
+
// In-memory Task builder (parametrised by Bus)
|
|
17
|
+
// ─────────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
module TaskBuilderWithBus = Task_Builder.Make(Bus)
|
|
20
|
+
|
|
21
|
+
// ─────────────────────────────────────────────────────────────
|
|
22
|
+
// Task spec — no buckets (smoke test for minimal setup)
|
|
23
|
+
// ─────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
module NoBucketsSpec = {
|
|
26
|
+
let name = "NoBucketsTask"
|
|
27
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
28
|
+
|
|
29
|
+
let setup = (
|
|
30
|
+
_queryEngine: Reventless.QueryEngine.operations,
|
|
31
|
+
_queryBucketName: ReventlessInfra.Task.queryBucketName,
|
|
32
|
+
_opts: Pulumi.ComponentResource.options,
|
|
33
|
+
): Reventless.Task.config => {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─────────────────────────────────────────────────────────────
|
|
37
|
+
// Task spec — one named bucket with a callback
|
|
38
|
+
// ─────────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
let capturedEvents: ref<array<(string, string)>> = ref([])
|
|
41
|
+
|
|
42
|
+
module OneBucketSpec = {
|
|
43
|
+
let name = "OneBucketTask"
|
|
44
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
45
|
+
|
|
46
|
+
let setup = (
|
|
47
|
+
_queryEngine: Reventless.QueryEngine.operations,
|
|
48
|
+
_queryBucketName: ReventlessInfra.Task.queryBucketName,
|
|
49
|
+
_opts: Pulumi.ComponentResource.options,
|
|
50
|
+
): Reventless.Task.config => {
|
|
51
|
+
buckets: [
|
|
52
|
+
{
|
|
53
|
+
bucketName: "Reports",
|
|
54
|
+
bucketMode: Reventless.Task.Read,
|
|
55
|
+
callback: async (~eventName, ~key) => {
|
|
56
|
+
capturedEvents :=
|
|
57
|
+
capturedEvents.contents->Array.concat([(eventName, key)])
|
|
58
|
+
[]
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ─────────────────────────────────────────────────────────────
|
|
66
|
+
// Mock infrastructure (shared across tests)
|
|
67
|
+
// ─────────────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
let mockPublishToAggregates: dict<ReventlessInfra.CommandTopic.publishJsons> = Dict.make()
|
|
70
|
+
|
|
71
|
+
let mockQueryBucketName: ReventlessInfra.Task.queryBucketName = (~taskName as _, ~bucketName as _=?) =>
|
|
72
|
+
"in-memory-bucket"
|
|
73
|
+
|
|
74
|
+
// ─────────────────────────────────────────────────────────────
|
|
75
|
+
// Pre-built task makers
|
|
76
|
+
// ─────────────────────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
module NoBucketsMaker = TaskBuilderWithBus.Make(NoBucketsSpec)
|
|
79
|
+
module OneBucketMaker = TaskBuilderWithBus.Make(OneBucketSpec)
|
|
80
|
+
|
|
81
|
+
// ─────────────────────────────────────────────────────────────
|
|
82
|
+
// Helper to reset captured state between tests
|
|
83
|
+
// ─────────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
let resetCaptures = () => {
|
|
86
|
+
capturedEvents := []
|
|
87
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
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 Task_Builder$ReventlessLocal from "../../../src/components/Task_Builder.res.mjs";
|
|
7
|
+
|
|
8
|
+
S.enableJson();
|
|
9
|
+
|
|
10
|
+
TestRunner$ReventlessLocal.setup();
|
|
11
|
+
|
|
12
|
+
let Bus = LocalBus$ReventlessLocal.Make({});
|
|
13
|
+
|
|
14
|
+
let TaskBuilderWithBus = Task_Builder$ReventlessLocal.Make(Bus);
|
|
15
|
+
|
|
16
|
+
let moduleUrl = import.meta.url;
|
|
17
|
+
|
|
18
|
+
function setup(_queryEngine, _queryBucketName, _opts) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let NoBucketsSpec = {
|
|
23
|
+
name: "NoBucketsTask",
|
|
24
|
+
moduleUrl: moduleUrl,
|
|
25
|
+
setup: setup
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
let capturedEvents = {
|
|
29
|
+
contents: []
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
let moduleUrl$1 = import.meta.url;
|
|
33
|
+
|
|
34
|
+
function setup$1(_queryEngine, _queryBucketName, _opts) {
|
|
35
|
+
return {
|
|
36
|
+
buckets: [{
|
|
37
|
+
bucketName: "Reports",
|
|
38
|
+
bucketMode: "Read",
|
|
39
|
+
callback: async (eventName, key) => {
|
|
40
|
+
capturedEvents.contents = capturedEvents.contents.concat([[
|
|
41
|
+
eventName,
|
|
42
|
+
key
|
|
43
|
+
]]);
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let OneBucketSpec = {
|
|
51
|
+
name: "OneBucketTask",
|
|
52
|
+
moduleUrl: moduleUrl$1,
|
|
53
|
+
setup: setup$1
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
let mockPublishToAggregates = {};
|
|
57
|
+
|
|
58
|
+
function mockQueryBucketName(param, param$1) {
|
|
59
|
+
return "in-memory-bucket";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let NoBucketsMaker = TaskBuilderWithBus.Make(NoBucketsSpec);
|
|
63
|
+
|
|
64
|
+
let OneBucketMaker = TaskBuilderWithBus.Make(OneBucketSpec);
|
|
65
|
+
|
|
66
|
+
function resetCaptures() {
|
|
67
|
+
capturedEvents.contents = [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
Bus,
|
|
72
|
+
TaskBuilderWithBus,
|
|
73
|
+
NoBucketsSpec,
|
|
74
|
+
capturedEvents,
|
|
75
|
+
OneBucketSpec,
|
|
76
|
+
mockPublishToAggregates,
|
|
77
|
+
mockQueryBucketName,
|
|
78
|
+
NoBucketsMaker,
|
|
79
|
+
OneBucketMaker,
|
|
80
|
+
resetCaptures,
|
|
81
|
+
}
|
|
82
|
+
/* Not a pure module */
|