@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,277 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
|
|
5
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Pulumi from "@pulumi/pulumi";
|
|
8
|
+
import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
|
|
9
|
+
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
10
|
+
import * as Projection$Reventless from "@reventlessdev/reventless-spec/src/types/Projection.res.mjs";
|
|
11
|
+
import * as Adapter$ReventlessInfra from "@reventlessdev/reventless-infra/src/adapter/Adapter.res.mjs";
|
|
12
|
+
import * as LocalBus$ReventlessLocal from "../../../src/adapter/LocalBus.res.mjs";
|
|
13
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
14
|
+
import * as TestFixtures$ReventlessLocal from "../../TestFixtures.res.mjs";
|
|
15
|
+
import * as ReadModel_Builder$ReventlessLocal from "../../../src/components/ReadModel_Builder.res.mjs";
|
|
16
|
+
|
|
17
|
+
let name = "TestMixedReadModel";
|
|
18
|
+
|
|
19
|
+
let moduleUrl = import.meta.url;
|
|
20
|
+
|
|
21
|
+
let stateSchema = S.schema(s => ({
|
|
22
|
+
name: s.m(S.string),
|
|
23
|
+
source: s.m(S.string)
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
let config = ReadModel$Reventless.config(undefined, undefined, undefined);
|
|
27
|
+
|
|
28
|
+
let MixedReadModelSpec = {
|
|
29
|
+
Id: undefined,
|
|
30
|
+
name: name,
|
|
31
|
+
moduleUrl: moduleUrl,
|
|
32
|
+
stateSchema: stateSchema,
|
|
33
|
+
config: config,
|
|
34
|
+
subIdConfig: undefined,
|
|
35
|
+
authorization: "AllowAuthenticated",
|
|
36
|
+
visibility: "Public"
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
let name$1 = "TestAggregateEventTopic";
|
|
40
|
+
|
|
41
|
+
let eventSchema = S.union([
|
|
42
|
+
S.schema(s => ({
|
|
43
|
+
TAG: "AggregateItemCreated",
|
|
44
|
+
name: s.m(S.string)
|
|
45
|
+
})),
|
|
46
|
+
S.schema(s => ({
|
|
47
|
+
TAG: "AggregateItemRenamed",
|
|
48
|
+
name: s.m(S.string)
|
|
49
|
+
}))
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
let AggregateSource = {
|
|
53
|
+
Id: undefined,
|
|
54
|
+
name: name$1,
|
|
55
|
+
eventSchema: eventSchema
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let name$2 = "TestDcbEventTopic";
|
|
59
|
+
|
|
60
|
+
let eventSchema$1 = S.union([
|
|
61
|
+
S.schema(s => ({
|
|
62
|
+
TAG: "DcbItemAdded",
|
|
63
|
+
name: s.m(S.string)
|
|
64
|
+
})),
|
|
65
|
+
S.schema(s => ({
|
|
66
|
+
TAG: "DcbItemNameChanged",
|
|
67
|
+
name: s.m(S.string)
|
|
68
|
+
}))
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
let DcbSource = {
|
|
72
|
+
Id: undefined,
|
|
73
|
+
name: name$2,
|
|
74
|
+
eventSchema: eventSchema$1
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function project(msg) {
|
|
78
|
+
let match = msg.event;
|
|
79
|
+
if (match.TAG === "AggregateItemCreated") {
|
|
80
|
+
return {
|
|
81
|
+
TAG: "Create",
|
|
82
|
+
_0: msg.id,
|
|
83
|
+
_1: {
|
|
84
|
+
name: match.name,
|
|
85
|
+
source: "aggregate"
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
let name = match.name;
|
|
90
|
+
return {
|
|
91
|
+
TAG: "Update",
|
|
92
|
+
_0: msg.id,
|
|
93
|
+
_1: state => ({
|
|
94
|
+
name: name,
|
|
95
|
+
source: state.source
|
|
96
|
+
})
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let AggregateMapping = Projection$Reventless.Mapping.Make({
|
|
101
|
+
Id: Id$Reventless.$$String,
|
|
102
|
+
name: name$1,
|
|
103
|
+
eventSchema: eventSchema
|
|
104
|
+
})({
|
|
105
|
+
Id: Id$Reventless.$$String,
|
|
106
|
+
name: name,
|
|
107
|
+
stateSchema: stateSchema,
|
|
108
|
+
subIdConfig: undefined
|
|
109
|
+
})({
|
|
110
|
+
project: project
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
function project$1(msg) {
|
|
114
|
+
let match = msg.event;
|
|
115
|
+
if (match.TAG === "DcbItemAdded") {
|
|
116
|
+
return {
|
|
117
|
+
TAG: "Create",
|
|
118
|
+
_0: msg.id,
|
|
119
|
+
_1: {
|
|
120
|
+
name: match.name,
|
|
121
|
+
source: "dcb"
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
let name = match.name;
|
|
126
|
+
return {
|
|
127
|
+
TAG: "Update",
|
|
128
|
+
_0: msg.id,
|
|
129
|
+
_1: state => ({
|
|
130
|
+
name: name,
|
|
131
|
+
source: state.source
|
|
132
|
+
})
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let DcbMapping = Projection$Reventless.Mapping.Make({
|
|
137
|
+
Id: Id$Reventless.$$String,
|
|
138
|
+
name: name$2,
|
|
139
|
+
eventSchema: eventSchema$1
|
|
140
|
+
})({
|
|
141
|
+
Id: Id$Reventless.$$String,
|
|
142
|
+
name: name,
|
|
143
|
+
stateSchema: stateSchema,
|
|
144
|
+
subIdConfig: undefined
|
|
145
|
+
})({
|
|
146
|
+
project: project$1
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
Projection$Reventless.Mappings.Make({
|
|
150
|
+
Id: Id$Reventless.$$String,
|
|
151
|
+
name: name,
|
|
152
|
+
stateSchema: stateSchema,
|
|
153
|
+
subIdConfig: undefined
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
let moduleUrl$1 = import.meta.url;
|
|
157
|
+
|
|
158
|
+
let mappings = [
|
|
159
|
+
AggregateMapping,
|
|
160
|
+
DcbMapping
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
let MixedMappings = {
|
|
164
|
+
moduleUrl: moduleUrl$1,
|
|
165
|
+
mappings: mappings
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
let aggregateTopicName = "TestAggregateEventTopic";
|
|
169
|
+
|
|
170
|
+
let dcbTopicName = "TestDcbEventTopic";
|
|
171
|
+
|
|
172
|
+
let aggregateResource = Adapter$ReventlessInfra.make(Pulumi.output(aggregateTopicName), Pulumi.output(aggregateTopicName), Pulumi.output(aggregateTopicName), Pulumi.output("memory:InMemory"), undefined, undefined, undefined, undefined, undefined, undefined);
|
|
173
|
+
|
|
174
|
+
let dcbResource = Adapter$ReventlessInfra.make(Pulumi.output(dcbTopicName), Pulumi.output(dcbTopicName), Pulumi.output(dcbTopicName), Pulumi.output("memory:InMemory"), undefined, undefined, undefined, undefined, undefined, undefined);
|
|
175
|
+
|
|
176
|
+
let allEventTopics = Object.fromEntries([
|
|
177
|
+
[
|
|
178
|
+
aggregateTopicName,
|
|
179
|
+
{
|
|
180
|
+
resources: [aggregateResource]
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
dcbTopicName,
|
|
185
|
+
{
|
|
186
|
+
resources: [dcbResource]
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
]);
|
|
190
|
+
|
|
191
|
+
let Bus = LocalBus$ReventlessLocal.Make({});
|
|
192
|
+
|
|
193
|
+
TestRunner$ReventlessLocal.setup();
|
|
194
|
+
|
|
195
|
+
let ReadModelMaker = ReadModel_Builder$ReventlessLocal.Make(Bus);
|
|
196
|
+
|
|
197
|
+
let MixedRM = ReadModelMaker.Make({
|
|
198
|
+
Id: Id$Reventless.$$String,
|
|
199
|
+
name: name,
|
|
200
|
+
moduleUrl: moduleUrl,
|
|
201
|
+
stateSchema: stateSchema,
|
|
202
|
+
config: config,
|
|
203
|
+
subIdConfig: undefined,
|
|
204
|
+
authorization: "AllowAuthenticated",
|
|
205
|
+
visibility: "Public"
|
|
206
|
+
})(MixedMappings);
|
|
207
|
+
|
|
208
|
+
let rm = MixedRM.make(undefined, undefined, allEventTopics, undefined);
|
|
209
|
+
|
|
210
|
+
async function publishAggregateEvent(id, event) {
|
|
211
|
+
let meta = TestFixtures$ReventlessLocal.makeTestMeta("TestAggregateEventTopic");
|
|
212
|
+
let eventJson = Object.fromEntries([
|
|
213
|
+
[
|
|
214
|
+
"id",
|
|
215
|
+
id
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
"meta",
|
|
219
|
+
S.reverseConvertToJsonOrThrow(meta, Message$Reventless.metaSchema)
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"event",
|
|
223
|
+
S.reverseConvertToJsonOrThrow(event, eventSchema)
|
|
224
|
+
]
|
|
225
|
+
]);
|
|
226
|
+
return await Bus.publishEvent(aggregateTopicName, "test", meta, eventJson);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function publishDcbEvent(id, event) {
|
|
230
|
+
let meta = TestFixtures$ReventlessLocal.makeTestMeta("TestDcbEventTopic");
|
|
231
|
+
let eventJson = Object.fromEntries([
|
|
232
|
+
[
|
|
233
|
+
"id",
|
|
234
|
+
id
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
"meta",
|
|
238
|
+
S.reverseConvertToJsonOrThrow(meta, Message$Reventless.metaSchema)
|
|
239
|
+
],
|
|
240
|
+
[
|
|
241
|
+
"event",
|
|
242
|
+
S.reverseConvertToJsonOrThrow(event, eventSchema$1)
|
|
243
|
+
]
|
|
244
|
+
]);
|
|
245
|
+
return await Bus.publishEvent(dcbTopicName, "test", meta, eventJson);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function loadState(id) {
|
|
249
|
+
let ops = Bus.getQueryDb("TestMixedReadModel");
|
|
250
|
+
if (ops === undefined) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
let states = await Effect.runPromise(Effect.catchAll(Stream.runCollect(ops.loadStream(id)), param => Effect.succeed([])));
|
|
254
|
+
return states.map(json => S.parseJsonOrThrow(json, stateSchema));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export {
|
|
258
|
+
MixedReadModelSpec,
|
|
259
|
+
AggregateSource,
|
|
260
|
+
DcbSource,
|
|
261
|
+
AggregateMapping,
|
|
262
|
+
DcbMapping,
|
|
263
|
+
MixedMappings,
|
|
264
|
+
aggregateTopicName,
|
|
265
|
+
dcbTopicName,
|
|
266
|
+
aggregateResource,
|
|
267
|
+
dcbResource,
|
|
268
|
+
allEventTopics,
|
|
269
|
+
Bus,
|
|
270
|
+
ReadModelMaker,
|
|
271
|
+
MixedRM,
|
|
272
|
+
rm,
|
|
273
|
+
publishAggregateEvent,
|
|
274
|
+
publishDcbEvent,
|
|
275
|
+
loadState,
|
|
276
|
+
}
|
|
277
|
+
/* moduleUrl Not a pure module */
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Integration test: ReadModel with mixed event sources.
|
|
2
|
+
// Verifies that a single ReadModel can project events from two independent
|
|
3
|
+
// EventTopics (simulating aggregate + DCB sources merged by Plugin_Builder).
|
|
4
|
+
|
|
5
|
+
open JestGlobals
|
|
6
|
+
open MixedSourceReadModelFixtures
|
|
7
|
+
|
|
8
|
+
describe("MixedSource ReadModel", () => {
|
|
9
|
+
let _ = beforeAllAsync(async () => {
|
|
10
|
+
let _ = await rm->MixedRM.operations->TestRunner.resolve
|
|
11
|
+
let _ = await aggregateResource.name->TestRunner.resolve
|
|
12
|
+
let _ = await dcbResource.name->TestRunner.resolve
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
testPromise("aggregate event projects with source 'aggregate'", async () => {
|
|
16
|
+
let _ = await publishAggregateEvent("agg-1", AggregateItemCreated({name: "Widget"}))
|
|
17
|
+
let states = await loadState("agg-1")
|
|
18
|
+
expect(states->Array.length)->toBe(1)
|
|
19
|
+
let state = states->Array.getUnsafe(0)
|
|
20
|
+
expect(state.name)->toBe("Widget")
|
|
21
|
+
expect(state.source)->toBe("aggregate")
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
testPromise("DCB event projects with source 'dcb'", async () => {
|
|
25
|
+
let _ = await publishDcbEvent("dcb-1", DcbItemAdded({name: "Gadget"}))
|
|
26
|
+
let states = await loadState("dcb-1")
|
|
27
|
+
expect(states->Array.length)->toBe(1)
|
|
28
|
+
let state = states->Array.getUnsafe(0)
|
|
29
|
+
expect(state.name)->toBe("Gadget")
|
|
30
|
+
expect(state.source)->toBe("dcb")
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
testPromise("both sources coexist independently", async () => {
|
|
34
|
+
let aggStates = await loadState("agg-1")
|
|
35
|
+
let dcbStates = await loadState("dcb-1")
|
|
36
|
+
expect(aggStates->Array.length)->toBe(1)
|
|
37
|
+
expect(dcbStates->Array.length)->toBe(1)
|
|
38
|
+
let agg = aggStates->Array.getUnsafe(0)
|
|
39
|
+
let dcb = dcbStates->Array.getUnsafe(0)
|
|
40
|
+
expect(agg.source)->toBe("aggregate")
|
|
41
|
+
expect(dcb.source)->toBe("dcb")
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
testPromise("aggregate update modifies existing entry", async () => {
|
|
45
|
+
let _ = await publishAggregateEvent("agg-1", AggregateItemRenamed({name: "Super Widget"}))
|
|
46
|
+
let states = await loadState("agg-1")
|
|
47
|
+
expect(states->Array.length)->toBe(1)
|
|
48
|
+
let state = states->Array.getUnsafe(0)
|
|
49
|
+
expect(state.name)->toBe("Super Widget")
|
|
50
|
+
expect(state.source)->toBe("aggregate")
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
testPromise("DCB update modifies existing entry", async () => {
|
|
54
|
+
let _ = await publishDcbEvent("dcb-1", DcbItemNameChanged({name: "Super Gadget"}))
|
|
55
|
+
let states = await loadState("dcb-1")
|
|
56
|
+
expect(states->Array.length)->toBe(1)
|
|
57
|
+
let state = states->Array.getUnsafe(0)
|
|
58
|
+
expect(state.name)->toBe("Super Gadget")
|
|
59
|
+
expect(state.source)->toBe("dcb")
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
4
|
+
import * as MixedSourceReadModelFixtures$ReventlessLocal from "./MixedSourceReadModelFixtures.res.mjs";
|
|
5
|
+
|
|
6
|
+
globalThis.describe("MixedSource ReadModel", () => {
|
|
7
|
+
globalThis.beforeAll(async () => {
|
|
8
|
+
await TestRunner$ReventlessLocal.resolve(MixedSourceReadModelFixtures$ReventlessLocal.MixedRM.operations(MixedSourceReadModelFixtures$ReventlessLocal.rm));
|
|
9
|
+
await TestRunner$ReventlessLocal.resolve(MixedSourceReadModelFixtures$ReventlessLocal.aggregateResource.name);
|
|
10
|
+
await TestRunner$ReventlessLocal.resolve(MixedSourceReadModelFixtures$ReventlessLocal.dcbResource.name);
|
|
11
|
+
});
|
|
12
|
+
globalThis.test("aggregate event projects with source 'aggregate'", async () => {
|
|
13
|
+
await MixedSourceReadModelFixtures$ReventlessLocal.publishAggregateEvent("agg-1", {
|
|
14
|
+
TAG: "AggregateItemCreated",
|
|
15
|
+
name: "Widget"
|
|
16
|
+
});
|
|
17
|
+
let states = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("agg-1");
|
|
18
|
+
globalThis.expect(states.length).toBe(1);
|
|
19
|
+
let state = states[0];
|
|
20
|
+
globalThis.expect(state.name).toBe("Widget");
|
|
21
|
+
globalThis.expect(state.source).toBe("aggregate");
|
|
22
|
+
});
|
|
23
|
+
globalThis.test("DCB event projects with source 'dcb'", async () => {
|
|
24
|
+
await MixedSourceReadModelFixtures$ReventlessLocal.publishDcbEvent("dcb-1", {
|
|
25
|
+
TAG: "DcbItemAdded",
|
|
26
|
+
name: "Gadget"
|
|
27
|
+
});
|
|
28
|
+
let states = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("dcb-1");
|
|
29
|
+
globalThis.expect(states.length).toBe(1);
|
|
30
|
+
let state = states[0];
|
|
31
|
+
globalThis.expect(state.name).toBe("Gadget");
|
|
32
|
+
globalThis.expect(state.source).toBe("dcb");
|
|
33
|
+
});
|
|
34
|
+
globalThis.test("both sources coexist independently", async () => {
|
|
35
|
+
let aggStates = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("agg-1");
|
|
36
|
+
let dcbStates = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("dcb-1");
|
|
37
|
+
globalThis.expect(aggStates.length).toBe(1);
|
|
38
|
+
globalThis.expect(dcbStates.length).toBe(1);
|
|
39
|
+
let agg = aggStates[0];
|
|
40
|
+
let dcb = dcbStates[0];
|
|
41
|
+
globalThis.expect(agg.source).toBe("aggregate");
|
|
42
|
+
globalThis.expect(dcb.source).toBe("dcb");
|
|
43
|
+
});
|
|
44
|
+
globalThis.test("aggregate update modifies existing entry", async () => {
|
|
45
|
+
await MixedSourceReadModelFixtures$ReventlessLocal.publishAggregateEvent("agg-1", {
|
|
46
|
+
TAG: "AggregateItemRenamed",
|
|
47
|
+
name: "Super Widget"
|
|
48
|
+
});
|
|
49
|
+
let states = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("agg-1");
|
|
50
|
+
globalThis.expect(states.length).toBe(1);
|
|
51
|
+
let state = states[0];
|
|
52
|
+
globalThis.expect(state.name).toBe("Super Widget");
|
|
53
|
+
globalThis.expect(state.source).toBe("aggregate");
|
|
54
|
+
});
|
|
55
|
+
globalThis.test("DCB update modifies existing entry", async () => {
|
|
56
|
+
await MixedSourceReadModelFixtures$ReventlessLocal.publishDcbEvent("dcb-1", {
|
|
57
|
+
TAG: "DcbItemNameChanged",
|
|
58
|
+
name: "Super Gadget"
|
|
59
|
+
});
|
|
60
|
+
let states = await MixedSourceReadModelFixtures$ReventlessLocal.loadState("dcb-1");
|
|
61
|
+
globalThis.expect(states.length).toBe(1);
|
|
62
|
+
let state = states[0];
|
|
63
|
+
globalThis.expect(state.name).toBe("Super Gadget");
|
|
64
|
+
globalThis.expect(state.source).toBe("dcb");
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// E2E test fixtures for ReadModel builder.
|
|
2
|
+
// Builds a ReadModel from a manually constructed allEventTopics and publishes
|
|
3
|
+
// events directly via the bus to verify projection into the QueryDb.
|
|
4
|
+
|
|
5
|
+
open TestFixtures
|
|
6
|
+
open Reventless
|
|
7
|
+
open Reventless.Projection
|
|
8
|
+
|
|
9
|
+
// ─────────────────────────────────────────────────────────────
|
|
10
|
+
// Minimal ReadModel spec
|
|
11
|
+
// ─────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
module ItemReadModelSpec = {
|
|
14
|
+
module Id = Reventless.Id.String
|
|
15
|
+
let name = "TestItemReadModel"
|
|
16
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
17
|
+
|
|
18
|
+
@schema
|
|
19
|
+
type state = {name: string}
|
|
20
|
+
|
|
21
|
+
let config = ReadModel.config()
|
|
22
|
+
let subIdConfig = None
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ─────────────────────────────────────────────────────────────
|
|
26
|
+
// Minimal source event
|
|
27
|
+
// Used as the projection source — topic name doubles as mapping.sourceName
|
|
28
|
+
// ─────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
module ItemEventSource = {
|
|
31
|
+
module Id = Reventless.Id.String
|
|
32
|
+
let name = "TestItemEventTopic" // must match allEventTopics key AND meta.service in published events
|
|
33
|
+
|
|
34
|
+
@schema
|
|
35
|
+
type event = | ItemCreated({name: string})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ─────────────────────────────────────────────────────────────
|
|
39
|
+
// Mapping: ItemCreated → Create ReadModel state
|
|
40
|
+
// ─────────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
module ItemMapping = Mapping.Make(
|
|
43
|
+
ItemEventSource,
|
|
44
|
+
ItemReadModelSpec,
|
|
45
|
+
{
|
|
46
|
+
let project = (msg: Message.event'<string, ItemEventSource.event>) =>
|
|
47
|
+
switch msg.event {
|
|
48
|
+
| ItemCreated({name}) => Create(msg.id, ({name: name}: ItemReadModelSpec.state))
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// ─────────────────────────────────────────────────────────────
|
|
54
|
+
// Mappings module required by ReadModel_Builder.Make
|
|
55
|
+
// ─────────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
module ItemMappings: Mappings with module Target := ItemReadModelSpec = {
|
|
58
|
+
module Mappings = Mappings.Make(ItemReadModelSpec)
|
|
59
|
+
module type Mapping = Mappings.Mapping
|
|
60
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
61
|
+
let mappings: array<module(Mapping)> = [module(ItemMapping)]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ─────────────────────────────────────────────────────────────
|
|
65
|
+
// allEventTopics — constructed manually (no aggregate needed)
|
|
66
|
+
// resource.name is the bus topic key that EventCollectorChannel subscribes to.
|
|
67
|
+
// ─────────────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
let topicName = "TestItemEventTopic"
|
|
70
|
+
let topicResource: ReventlessInfra.Adapter.resource = ReventlessInfra.Adapter.make(
|
|
71
|
+
~name=topicName->Pulumi.Output.make,
|
|
72
|
+
~id=topicName->Pulumi.Output.make,
|
|
73
|
+
~urn=topicName->Pulumi.Output.make,
|
|
74
|
+
~service="memory:InMemory"->Pulumi.Output.make,
|
|
75
|
+
)
|
|
76
|
+
let allEventTopics: ReventlessInfra.EventTopic.allOutputs = Dict.fromArray([
|
|
77
|
+
(topicName, {ReventlessInfra.EventTopic.resources: [topicResource]}),
|
|
78
|
+
])
|
|
79
|
+
|
|
80
|
+
// ─────────────────────────────────────────────────────────────
|
|
81
|
+
// Isolated bus for this test suite
|
|
82
|
+
// ─────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
module Bus = LocalBus.Make()
|
|
85
|
+
|
|
86
|
+
// ─────────────────────────────────────────────────────────────
|
|
87
|
+
// Activate Pulumi mock mode (must be before any Component.make)
|
|
88
|
+
// ─────────────────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
let _ = TestRunner.setup()
|
|
91
|
+
|
|
92
|
+
// ─────────────────────────────────────────────────────────────
|
|
93
|
+
// Build ReadModel
|
|
94
|
+
// ─────────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
module ReadModelMaker = ReadModel_Builder.Make(Bus)
|
|
97
|
+
module ItemReadModel = ReadModelMaker.Make(ItemReadModelSpec, ItemMappings)
|
|
98
|
+
let rm = ItemReadModel.make(~api=(), ~apiRole=(), ~allEventTopics)
|
|
99
|
+
|
|
100
|
+
// ─────────────────────────────────────────────────────────────
|
|
101
|
+
// Test helpers
|
|
102
|
+
// ─────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
// meta.service MUST match Mapping.sourceName ("TestItemEventTopic") for
|
|
105
|
+
// ReadModel_Callback to route the event to the correct mapping.
|
|
106
|
+
let testMeta = makeTestMeta(~service="TestItemEventTopic")
|
|
107
|
+
|
|
108
|
+
// Publish a typed event to the bus topic.
|
|
109
|
+
// The event JSON must be {id, meta, event} format for Message.decodeEvent' to parse.
|
|
110
|
+
let publishItemCreated = async (id, name) => {
|
|
111
|
+
let eventJson = JSON.Encode.object(
|
|
112
|
+
Dict.fromArray([
|
|
113
|
+
("id", id->JSON.Encode.string),
|
|
114
|
+
("meta", testMeta->S.reverseConvertToJsonOrThrow(Message.metaSchema)),
|
|
115
|
+
(
|
|
116
|
+
"event",
|
|
117
|
+
ItemEventSource.ItemCreated({name: name})
|
|
118
|
+
->S.reverseConvertToJsonOrThrow(ItemEventSource.eventSchema),
|
|
119
|
+
),
|
|
120
|
+
]),
|
|
121
|
+
)
|
|
122
|
+
await Bus.publishEvent(topicName, "test", testMeta, eventJson)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Query projected state from the in-memory QueryDb.
|
|
126
|
+
// QueryDb is registered with the ReadModel Spec.name = "TestItemReadModel".
|
|
127
|
+
let loadState = async id => {
|
|
128
|
+
switch Bus.getQueryDb("TestItemReadModel") {
|
|
129
|
+
| None => []
|
|
130
|
+
| Some(ops) =>
|
|
131
|
+
let states =
|
|
132
|
+
await ops.loadStream(id)
|
|
133
|
+
->Stream.runCollect
|
|
134
|
+
->Effect.catchAll(_ => Effect.succeed([]))
|
|
135
|
+
->Effect.runPromise
|
|
136
|
+
states->Array.map(json => json->S.parseJsonOrThrow(ItemReadModelSpec.stateSchema))
|
|
137
|
+
}
|
|
138
|
+
}
|