@reventlessdev/reventless-local 3.0.0-alpha.249 → 3.0.0-alpha.251

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/package.json +13 -13
  3. package/src/BakedManifest.res +5 -6
  4. package/src/EmitCapabilities.res +3 -1
  5. package/src/LocalPlatformRegistry.res +3 -1
  6. package/src/LocalPlatformStart.res +7 -6
  7. package/src/LocalSeedTarget.res +3 -1
  8. package/src/Platform.res +291 -215
  9. package/src/ShellConfig.res +10 -17
  10. package/src/UiHints.res +8 -14
  11. package/src/UiSlots.res +10 -17
  12. package/src/adapter/Api/LocalEvents_Server.res +5 -3
  13. package/src/adapter/Api/LocalGraphQL_Adapter.res +4 -4
  14. package/src/adapter/Auth/LocalAuth.res +12 -16
  15. package/src/adapter/Auth/LocalAuth.res.mjs +2 -1
  16. package/src/adapter/Auth/UserStore.res +13 -40
  17. package/src/adapter/Auth/UserStore.res.mjs +11 -67
  18. package/src/adapter/Backend.res +1 -2
  19. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +42 -26
  20. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +13 -3
  21. package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +15 -17
  22. package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +18 -22
  23. package/src/adapter/Counter/LocalCounterHandler.res +1 -1
  24. package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +33 -22
  25. package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +57 -57
  26. package/src/adapter/DomainGraphQL_Server.res +35 -34
  27. package/src/adapter/DomainMCP_Server.res +45 -41
  28. package/src/adapter/EventCollector/LocalEventCollectorChannel.res +47 -36
  29. package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res +15 -12
  30. package/src/adapter/EventLog/EventLogStorage_InMemory.res +9 -4
  31. package/src/adapter/EventLog/EventLogStorage_Sqlite.res +36 -24
  32. package/src/adapter/EventTopic/LocalEventTopicPublisher.res +9 -3
  33. package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +9 -14
  34. package/src/adapter/LocalBus.res +12 -12
  35. package/src/adapter/LocalCapabilities.res +6 -0
  36. package/src/adapter/LocalCapabilities.res.mjs +5 -2
  37. package/src/adapter/LocalGeocodeResolvers.res +1 -4
  38. package/src/adapter/LocalSideEffectHandler.res +1 -1
  39. package/src/adapter/LocalStateChangeDescriptor.res +2 -1
  40. package/src/adapter/MCP_ServerInstance.res +51 -39
  41. package/src/adapter/ObjectStore/LocalObjectStore.res +5 -2
  42. package/src/adapter/ObjectStore/ObjectStoreStorage_FileSystem.res +1 -2
  43. package/src/adapter/PlatformGraphQL_Server.res +10 -6
  44. package/src/adapter/PlatformGraphQL_Server.res.mjs +2 -1
  45. package/src/adapter/ProjectionCheckpoint.res +8 -1
  46. package/src/adapter/ProjectionPending.res +1 -3
  47. package/src/adapter/QueryDb/LocalQueryDbStorage.res +2 -1
  48. package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +367 -269
  49. package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +5 -3
  50. package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +63 -40
  51. package/src/adapter/QueryDb/SortKey_Filter.res +14 -6
  52. package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +12 -10
  53. package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +8 -2
  54. package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +1 -4
  55. package/src/adapter/Scheduler/LocalScheduledPublisher.res +12 -12
  56. package/src/adapter/SqliteDriver.res +16 -4
  57. package/src/adapter/Task/TaskBucket_Sqlite.res +5 -6
  58. package/src/components/Aggregate_Builder.res +6 -1
  59. package/src/components/Counter_Builder.res +1 -5
  60. package/src/components/DcbEventLog_Builder.res +5 -3
  61. package/src/components/ExtensionPoint_Builder.res +13 -15
  62. package/src/components/InboundTranslationSlice_Builder.res +3 -2
  63. package/src/components/OutboundTranslationSlice_Builder.res +3 -2
  64. package/src/components/ReadModel_Builder.res +18 -20
  65. package/src/components/StateViewSlice_Builder.res +3 -2
  66. package/src/components/Task_Builder.res +12 -13
  67. package/src/reset/LocalSeedReset.res +2 -5
  68. package/src/test/Mocks/MockDcbEventLogStorage.res +5 -1
  69. package/src/test/Mocks/MockEventLogStorage.res +8 -3
  70. package/src/test/Mocks/MockQueryDbStorage.res +3 -2
  71. package/src/test/TestRunner.res +1 -1
  72. package/tests/BakedManifestFilesTest.res +7 -10
  73. package/tests/LocalEventTapTest.res +26 -21
  74. package/tests/LocalPlatformStartTest.res +33 -28
  75. package/tests/PluginEventDecodeTest.res +3 -3
  76. package/tests/ShellConfigTest.res +30 -21
  77. package/tests/SplitApiFixtures.res +34 -10
  78. package/tests/SplitApiTest.res +92 -62
  79. package/tests/adapter/BackendParityTest.res +180 -130
  80. package/tests/adapter/CollectNEventsTest.res +6 -4
  81. package/tests/adapter/CommandAuthorizationTest.res +47 -41
  82. package/tests/adapter/CommandTopicChannelTest.res +163 -139
  83. package/tests/adapter/CounterHandlerTest.res +95 -77
  84. package/tests/adapter/DcbEventLogStorageSqliteTest.res +171 -168
  85. package/tests/adapter/DcbEventLogStorageTest.res +264 -207
  86. package/tests/adapter/DomainGraphQL_ServerTest.res +53 -43
  87. package/tests/adapter/EventCollectorChannelTest.res +153 -124
  88. package/tests/adapter/EventHistoryResolverTest.res +46 -18
  89. package/tests/adapter/EventLogSnapshotParityTest.res +57 -45
  90. package/tests/adapter/EventLogStorageSqliteTest.res +9 -10
  91. package/tests/adapter/EventTapTest.res +37 -20
  92. package/tests/adapter/EventTopicPublisherTest.res +74 -50
  93. package/tests/adapter/GraphQLSubscriptionBridgeTest.res +4 -3
  94. package/tests/adapter/GraphQL_SchemaInspectorTest.res +666 -568
  95. package/tests/adapter/GraphQL_SubscriptionResolversTest.res +105 -96
  96. package/tests/adapter/HeartbeatRunnerTest.res +99 -81
  97. package/tests/adapter/InboundTranslationMutationTest.res +4 -1
  98. package/tests/adapter/LocalAuthHttpTest.res +79 -85
  99. package/tests/adapter/LocalAuthLoginTest.res +42 -50
  100. package/tests/adapter/LocalAuthTest.res +8 -16
  101. package/tests/adapter/LocalAuthUserStoreTest.res +2 -7
  102. package/tests/adapter/LocalBusBoundedTest.res +187 -117
  103. package/tests/adapter/LocalBusPubSubTest.res +118 -76
  104. package/tests/adapter/LocalDispatchContextTest.res +1 -2
  105. package/tests/adapter/LocalEvents_ServerTest.res +242 -187
  106. package/tests/adapter/PgProjectionCatchupTest.res +44 -10
  107. package/tests/adapter/ProjectionCheckpointTest.res +261 -206
  108. package/tests/adapter/QueryDbGsiTtlTest.res +123 -83
  109. package/tests/adapter/QueryDbListPushdownParityTest.res +107 -67
  110. package/tests/adapter/QueryDbListResolverTest.res +225 -208
  111. package/tests/adapter/QueryDbResolvedFieldsTest.res +17 -14
  112. package/tests/adapter/QueryDbStorageSqliteTest.res +33 -49
  113. package/tests/adapter/QueryDbStorageTest.res +163 -117
  114. package/tests/adapter/QueryDbUnionRoundTripTest.res +8 -10
  115. package/tests/adapter/QueryEngineTest.res +179 -126
  116. package/tests/adapter/ScheduledPublisherTest.res +171 -135
  117. package/tests/adapter/ServedBucketHttpTest.res +65 -59
  118. package/tests/adapter/SortKey_FilterTest.res +19 -3
  119. package/tests/adapter/SqliteDriverTest.res +13 -10
  120. package/tests/adapter/TaskBucketTest.res +94 -80
  121. package/tests/components/aggregate/AggregateTest.res +31 -18
  122. package/tests/components/automationslice/AutomationSliceCallbackTest.res +259 -222
  123. package/tests/components/automationslice/AutomationSliceFixtures.res +4 -2
  124. package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +38 -38
  125. package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +12 -14
  126. package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +8 -32
  127. package/tests/components/commandgenerator/CommandGeneratorFixtures.res +7 -5
  128. package/tests/components/commandgenerator/CommandGeneratorTest.res +40 -31
  129. package/tests/components/commandtopic/CommandTopicFixtures.res +3 -4
  130. package/tests/components/commandtopic/CommandTopicStreamFixtures.res +7 -5
  131. package/tests/components/commandtopic/CommandTopicTest.res +24 -15
  132. package/tests/components/counter/CounterFixtures.res +6 -8
  133. package/tests/components/dcb/DcbCrossPartitionFixtures.res +8 -2
  134. package/tests/components/dcb/DcbCrossPartitionReadTest.res +20 -13
  135. package/tests/components/dcb/DcbEventLogAppendStreamTest.res +12 -8
  136. package/tests/components/dcb/DcbEventLogStreamTest.res +88 -61
  137. package/tests/components/dcb/DcbFixtures.res +4 -1
  138. package/tests/components/dcb/DcbTest.res +9 -6
  139. package/tests/components/eventcollector/EventCollectorFixtures.res +0 -1
  140. package/tests/components/eventcollector/EventCollectorTest.res +6 -3
  141. package/tests/components/eventlog/EventLogAppendStreamTest.res +88 -68
  142. package/tests/components/eventlog/EventLogConflictTest.res +8 -4
  143. package/tests/components/eventlog/EventLogFixtures.res +3 -3
  144. package/tests/components/eventlog/EventLogProvisioningSeamTest.res +26 -13
  145. package/tests/components/eventlog/EventLogStreamTest.res +119 -56
  146. package/tests/components/eventlog/EventLogTest.res +20 -4
  147. package/tests/components/eventtopic/EventTopicFixtures.res +3 -3
  148. package/tests/components/eventtopic/EventTopicStreamFixtures.res +1 -2
  149. package/tests/components/eventtopic/EventTopicStreamTest.res +7 -1
  150. package/tests/components/extensionpoint/ExtensionPointFixtures.res +14 -9
  151. package/tests/components/extensionpoint/ExtensionPointTest.res +3 -2
  152. package/tests/components/heartbeat/HeartbeatFixtures.res +5 -6
  153. package/tests/components/heartbeat/HeartbeatTest.res +56 -47
  154. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +271 -249
  155. package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +3 -2
  156. package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +361 -276
  157. package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +8 -10
  158. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +37 -43
  159. package/tests/components/querydb/QueryDbFixtures.res +1 -5
  160. package/tests/components/querydb/QueryDbTest.res +2 -4
  161. package/tests/components/readmodel/DcbReadModelE2EFixtures.res +15 -18
  162. package/tests/components/readmodel/MixedSourceReadModelFixtures.res +5 -7
  163. package/tests/components/readmodel/ReadModelFixtures.res +8 -8
  164. package/tests/components/scheduler/SchedulerTest.res +76 -58
  165. package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +4 -4
  166. package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res +5 -7
  167. package/tests/components/stateviewslice/StateViewSliceFixtures.res +8 -6
  168. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +17 -11
  169. package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +12 -2
  170. package/tests/components/task/TaskFixtures.res +5 -5
  171. package/tests/components/task/TaskTest.res +95 -80
  172. package/tests/plugin/PluginsProjection_GWT.res +3 -1
  173. package/tests/plugin/UiFragments_GWT.res +6 -1
  174. package/tests/reset/LocalSeedResetTest.res +1 -0
@@ -13,86 +13,149 @@ describe("EventLog.replayStream (in-memory adapter)", () => {
13
13
  let _ = beforeEach(() => reset())
14
14
 
15
15
  describe("basic streaming", () => {
16
- testPromise("replayStream returns all appended events", async () => {
17
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
18
- let _ = await ops.append(0, "stream-1", [makeEvent'("stream-1", ItemEventLogSpec.ItemCreated({name: "Widget"}))])
19
- let _ = await ops.append(1, "stream-1", [makeEvent'("stream-1", ItemEventLogSpec.ItemDeleted({id: "stream-1"}))])
20
- let count = await ops.replayStream("stream-1")
16
+ testPromise(
17
+ "replayStream returns all appended events",
18
+ async () => {
19
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
20
+ let _ = await ops.append(
21
+ 0,
22
+ "stream-1",
23
+ [makeEvent'("stream-1", ItemEventLogSpec.ItemCreated({name: "Widget"}))],
24
+ )
25
+ let _ = await ops.append(
26
+ 1,
27
+ "stream-1",
28
+ [makeEvent'("stream-1", ItemEventLogSpec.ItemDeleted({id: "stream-1"}))],
29
+ )
30
+ let count = await ops.replayStream("stream-1")
21
31
  ->Stream.runFold(0, (n, _) => n + 1)
22
32
  ->Effect.runPromise
23
- expect(count)->toBe(2)
24
- })
33
+ expect(count)->toBe(2)
34
+ },
35
+ )
25
36
 
26
- testPromise("replayStream for unknown id returns empty stream", async () => {
27
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
28
- let count = await ops.replayStream("no-such-id")
37
+ testPromise(
38
+ "replayStream for unknown id returns empty stream",
39
+ async () => {
40
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
41
+ let count = await ops.replayStream("no-such-id")
29
42
  ->Stream.runFold(0, (n, _) => n + 1)
30
43
  ->Effect.runPromise
31
- expect(count)->toBe(0)
32
- })
44
+ expect(count)->toBe(0)
45
+ },
46
+ )
33
47
 
34
- testPromise("replayStream emits events in append order", async () => {
35
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
36
- let _ = await ops.append(0, "stream-2", [makeEvent'("stream-2", ItemEventLogSpec.ItemCreated({name: "First"}))])
37
- let _ = await ops.append(1, "stream-2", [makeEvent'("stream-2", ItemEventLogSpec.ItemDeleted({id: "stream-2"}))])
38
- let events = await ops.replayStream("stream-2")
48
+ testPromise(
49
+ "replayStream emits events in append order",
50
+ async () => {
51
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
52
+ let _ = await ops.append(
53
+ 0,
54
+ "stream-2",
55
+ [makeEvent'("stream-2", ItemEventLogSpec.ItemCreated({name: "First"}))],
56
+ )
57
+ let _ = await ops.append(
58
+ 1,
59
+ "stream-2",
60
+ [makeEvent'("stream-2", ItemEventLogSpec.ItemDeleted({id: "stream-2"}))],
61
+ )
62
+ let events = await ops.replayStream("stream-2")
39
63
  ->Stream.runCollect
40
64
  ->Effect.runPromise
41
- expect(events->Array.length)->toBe(2)
42
- // First emitted is the Created event
43
- let first = events->Array.getUnsafe(0)
44
- expect(first)->toEqual(ItemEventLogSpec.ItemCreated({name: "First"}))
45
- })
65
+ expect(events->Array.length)->toBe(2)
66
+ // First emitted is the Created event
67
+ let first = events->Array.getUnsafe(0)
68
+ expect(first)->toEqual(ItemEventLogSpec.ItemCreated({name: "First"}))
69
+ },
70
+ )
46
71
 
47
- testPromise("separate aggregate IDs have independent streams", async () => {
48
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
49
- let _ = await ops.append(0, "agg-X", [makeEvent'("agg-X", ItemEventLogSpec.ItemCreated({name: "X"}))])
50
- let _ = await ops.append(0, "agg-Y", [makeEvent'("agg-Y", ItemEventLogSpec.ItemCreated({name: "Y1"})), makeEvent'("agg-Y", ItemEventLogSpec.ItemDeleted({id: "agg-Y"}))])
51
- let countX = await ops.replayStream("agg-X")
72
+ testPromise(
73
+ "separate aggregate IDs have independent streams",
74
+ async () => {
75
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
76
+ let _ = await ops.append(
77
+ 0,
78
+ "agg-X",
79
+ [makeEvent'("agg-X", ItemEventLogSpec.ItemCreated({name: "X"}))],
80
+ )
81
+ let _ = await ops.append(
82
+ 0,
83
+ "agg-Y",
84
+ [
85
+ makeEvent'("agg-Y", ItemEventLogSpec.ItemCreated({name: "Y1"})),
86
+ makeEvent'("agg-Y", ItemEventLogSpec.ItemDeleted({id: "agg-Y"})),
87
+ ],
88
+ )
89
+ let countX = await ops.replayStream("agg-X")
52
90
  ->Stream.runFold(0, (n, _) => n + 1)
53
91
  ->Effect.runPromise
54
- let countY = await ops.replayStream("agg-Y")
92
+ let countY = await ops.replayStream("agg-Y")
55
93
  ->Stream.runFold(0, (n, _) => n + 1)
56
94
  ->Effect.runPromise
57
- expect(countX)->toBe(1)
58
- expect(countY)->toBe(2)
59
- })
95
+ expect(countX)->toBe(1)
96
+ expect(countY)->toBe(2)
97
+ },
98
+ )
60
99
 
61
- testPromise("take(2) on a 5-event log returns only 2 events", async () => {
62
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
63
- let _ = await ops.append(0, "stream-3", [
64
- makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e1"})),
65
- makeEvent'("stream-3", ItemEventLogSpec.ItemDeleted({id: "e2"})),
66
- makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e3"})),
67
- makeEvent'("stream-3", ItemEventLogSpec.ItemDeleted({id: "e4"})),
68
- makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e5"})),
69
- ])
70
- let first2 = await ops.replayStream("stream-3")
100
+ testPromise(
101
+ "take(2) on a 5-event log returns only 2 events",
102
+ async () => {
103
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
104
+ let _ = await ops.append(
105
+ 0,
106
+ "stream-3",
107
+ [
108
+ makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e1"})),
109
+ makeEvent'("stream-3", ItemEventLogSpec.ItemDeleted({id: "e2"})),
110
+ makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e3"})),
111
+ makeEvent'("stream-3", ItemEventLogSpec.ItemDeleted({id: "e4"})),
112
+ makeEvent'("stream-3", ItemEventLogSpec.ItemCreated({name: "e5"})),
113
+ ],
114
+ )
115
+ let first2 = await ops.replayStream("stream-3")
71
116
  ->Stream.take(2)
72
117
  ->Stream.runCollect
73
118
  ->Effect.runPromise
74
- expect(first2->Array.length)->toBe(2)
75
- })
119
+ expect(first2->Array.length)->toBe(2)
120
+ },
121
+ )
76
122
  })
77
123
 
78
124
  describe("tuple fold — (state, count) pattern used in Aggregate_Callback", () => {
79
- testPromise("runFold produces correct count for sequenceNr", async () => {
80
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
81
- let _ = await ops.append(0, "fold-1", [makeEvent'("fold-1", ItemEventLogSpec.ItemCreated({name: "e1"})), makeEvent'("fold-1", ItemEventLogSpec.ItemDeleted({id: "e2"}))])
82
- let _ = await ops.append(2, "fold-1", [makeEvent'("fold-1", ItemEventLogSpec.ItemCreated({name: "e3"}))])
83
- let (_state, count) = await ops.replayStream("fold-1")
125
+ testPromise(
126
+ "runFold produces correct count for sequenceNr",
127
+ async () => {
128
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
129
+ let _ = await ops.append(
130
+ 0,
131
+ "fold-1",
132
+ [
133
+ makeEvent'("fold-1", ItemEventLogSpec.ItemCreated({name: "e1"})),
134
+ makeEvent'("fold-1", ItemEventLogSpec.ItemDeleted({id: "e2"})),
135
+ ],
136
+ )
137
+ let _ = await ops.append(
138
+ 2,
139
+ "fold-1",
140
+ [makeEvent'("fold-1", ItemEventLogSpec.ItemCreated({name: "e3"}))],
141
+ )
142
+ let (_state, count) = await ops.replayStream("fold-1")
84
143
  ->Stream.runFold((None, 0), ((st, n), _ev) => (st, n + 1))
85
144
  ->Effect.runPromise
86
- expect(count)->toBe(3)
87
- })
145
+ expect(count)->toBe(3)
146
+ },
147
+ )
88
148
 
89
- testPromise("runFold on empty stream returns initial accumulator", async () => {
90
- let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
91
- let (state, count) = await ops.replayStream("unknown-fold")
149
+ testPromise(
150
+ "runFold on empty stream returns initial accumulator",
151
+ async () => {
152
+ let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
153
+ let (state, count) = await ops.replayStream("unknown-fold")
92
154
  ->Stream.runFold((None, 0), ((st, n), _ev) => (st, n + 1))
93
155
  ->Effect.runPromise
94
- expect(state)->toEqual(None)
95
- expect(count)->toBe(0)
96
- })
156
+ expect(state)->toEqual(None)
157
+ expect(count)->toBe(0)
158
+ },
159
+ )
97
160
  })
98
161
  })
@@ -36,16 +36,32 @@ describe("EventLog (in-memory)", () => {
36
36
 
37
37
  testPromise("multiple appends accumulate events", async () => {
38
38
  let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
39
- let _ = await ops.append(0, "agg-1", [makeEvent'("agg-1", ItemEventLogSpec.ItemCreated({name: "First"}))])
40
- let _ = await ops.append(1, "agg-1", [makeEvent'("agg-1", ItemEventLogSpec.ItemDeleted({id: "agg-1"}))])
39
+ let _ = await ops.append(
40
+ 0,
41
+ "agg-1",
42
+ [makeEvent'("agg-1", ItemEventLogSpec.ItemCreated({name: "First"}))],
43
+ )
44
+ let _ = await ops.append(
45
+ 1,
46
+ "agg-1",
47
+ [makeEvent'("agg-1", ItemEventLogSpec.ItemDeleted({id: "agg-1"}))],
48
+ )
41
49
  let replayed = await ops.replay("agg-1")
42
50
  expect(replayed->Array.length)->toBe(2)
43
51
  })
44
52
 
45
53
  testPromise("separate aggregates have independent event logs", async () => {
46
54
  let ops = await eventLog->ReventlessCore.Component.operations->TestRunner.resolve
47
- let _ = await ops.append(0, "agg-A", [makeEvent'("agg-A", ItemEventLogSpec.ItemCreated({name: "A"}))])
48
- let _ = await ops.append(0, "agg-B", [makeEvent'("agg-B", ItemEventLogSpec.ItemDeleted({id: "B"}))])
55
+ let _ = await ops.append(
56
+ 0,
57
+ "agg-A",
58
+ [makeEvent'("agg-A", ItemEventLogSpec.ItemCreated({name: "A"}))],
59
+ )
60
+ let _ = await ops.append(
61
+ 0,
62
+ "agg-B",
63
+ [makeEvent'("agg-B", ItemEventLogSpec.ItemDeleted({id: "B"}))],
64
+ )
49
65
  let eventsA = await ops.replay("agg-A")
50
66
  let eventsB = await ops.replay("agg-B")
51
67
  expect((eventsA->Array.length, eventsB->Array.length))->toEqual((1, 1))
@@ -7,7 +7,7 @@ module ItemEventTopicSpec = {
7
7
  let name = "TestItemEventTopic"
8
8
 
9
9
  @schema
10
- type event = | ItemPublished({name: string}) | ItemRemoved({id: string})
10
+ type event = ItemPublished({name: string}) | ItemRemoved({id: string})
11
11
  }
12
12
 
13
13
  // ─────────────────────────────────────────────────────────────
@@ -36,11 +36,11 @@ module EventTopicMaker = ReventlessCore.EventTopic_Builder.Make(
36
36
 
37
37
  let eventTopic = EventTopicMaker.make(~name="TestItemEventTopic", ~storageResources=[])
38
38
 
39
- let makeEvent' = (id, event) => ({
39
+ let makeEvent' = (id, event): Reventless.Message.event'<string, ItemEventTopicSpec.event> => {
40
40
  Reventless.Message.id,
41
41
  meta: testMeta,
42
42
  event,
43
- }: Reventless.Message.event'<string, ItemEventTopicSpec.event>)
43
+ }
44
44
 
45
45
  let reset = () => {
46
46
  capturedEventCount := 0
@@ -5,7 +5,7 @@ module ItemStreamSpec = {
5
5
  let name = "StreamEvtItem"
6
6
 
7
7
  @schema
8
- type event = | ItemPublished({name: string}) | ItemRemoved({id: string})
8
+ type event = ItemPublished({name: string}) | ItemRemoved({id: string})
9
9
  }
10
10
 
11
11
  module StreamEvtBus = LocalBus.Make()
@@ -24,4 +24,3 @@ module StreamEvtTopicMaker = ReventlessCore.EventTopic_Builder.Make(
24
24
  )
25
25
 
26
26
  let evtTopic = StreamEvtTopicMaker.make(~name="StreamEvtTopic", ~storageResources=[])
27
-
@@ -17,7 +17,13 @@ describe("EventTopic.publishJsonStream", () => {
17
17
  testPromise("streams 2 events to all subscribers", async () => {
18
18
  let ops = await evtTopic->ReventlessCore.Component.operations->TestRunner.resolve
19
19
  let stream = [
20
- ({service: "svc", meta: testMeta, json: JSON.parseOrThrow("{\"ev\":1}")}: ReventlessInfra.EventTopic.publishJsonStreamItem),
20
+ (
21
+ {
22
+ service: "svc",
23
+ meta: testMeta,
24
+ json: JSON.parseOrThrow("{\"ev\":1}"),
25
+ }: ReventlessInfra.EventTopic.publishJsonStreamItem
26
+ ),
21
27
  {service: "svc", meta: testMeta, json: JSON.parseOrThrow("{\"ev\":2}")},
22
28
  ]->Stream.fromIterable
23
29
  let _ = await ops.publishJsonStream(stream)->Effect.runPromise
@@ -3,7 +3,6 @@
3
3
 
4
4
  open TestFixtures
5
5
 
6
-
7
6
  // ─────────────────────────────────────────────────────────────
8
7
  // Isolated bus + Pulumi mock mode
9
8
  // ─────────────────────────────────────────────────────────────
@@ -20,13 +19,13 @@ module TestEPSpec = {
20
19
  let name = "TestEP"
21
20
 
22
21
  @schema
23
- type command = | Forward({targetId: string})
22
+ type command = Forward({targetId: string})
24
23
 
25
24
  @schema
26
- type event = | TEPNoEvent // unused — mapOutgoingEvent = None
25
+ type event = TEPNoEvent // unused — mapOutgoingEvent = None
27
26
 
28
27
  @schema
29
- type directive = | TEPNoDirective // unused — mapIncomingCommand only uses PublishCommand
28
+ type directive = TEPNoDirective // unused — mapIncomingCommand only uses PublishCommand
30
29
 
31
30
  let moduleUrl: string = %raw(`import.meta.url`)
32
31
  }
@@ -40,13 +39,13 @@ module DelegateAggSpec = {
40
39
  let name = "TargetAgg"
41
40
 
42
41
  @schema
43
- type command = | Execute({targetId: string})
42
+ type command = Execute({targetId: string})
44
43
 
45
44
  @schema
46
- type event = | Executed({targetId: string}) // unused but required by Aggregate.Spec
45
+ type event = Executed({targetId: string}) // unused but required by Aggregate.Spec
47
46
 
48
47
  @schema
49
- type error = | TEAggNoError // unused but required by Aggregate.Spec
48
+ type error = TEAggNoError // unused but required by Aggregate.Spec
50
49
 
51
50
  let moduleUrl: string = %raw(`import.meta.url`)
52
51
  }
@@ -65,7 +64,12 @@ module ForwardMapping = {
65
64
  _id: string,
66
65
  cmd: TestEPSpec.command,
67
66
  _meta: Reventless.Message.meta,
68
- ): array<ReventlessInfra.ExtensionPointMapping.commandAction<DelegateAggSpec.command, TestEPSpec.directive>> =>
67
+ ): array<
68
+ ReventlessInfra.ExtensionPointMapping.commandAction<
69
+ DelegateAggSpec.command,
70
+ TestEPSpec.directive,
71
+ >,
72
+ > =>
69
73
  switch cmd {
70
74
  | Forward({targetId}) =>
71
75
  let execCmd = DelegateAggSpec.Execute({targetId: targetId})
@@ -93,7 +97,8 @@ module TestEPMapping1 = ReventlessInfra.ExtensionPointMapping.Make(ForwardMappin
93
97
 
94
98
  module TestEPMappings = {
95
99
  module Spec = TestEPSpec
96
- module type Mapping = ReventlessInfra.ExtensionPointMapping.T with module ExtensionPoint := TestEPSpec
100
+ module type Mapping = ReventlessInfra.ExtensionPointMapping.T
101
+ with module ExtensionPoint := TestEPSpec
97
102
  let name = "TestEPMappings"
98
103
  let moduleUrl: string = %raw(`import.meta.url`)
99
104
  let mappings: array<module(Mapping)> = [module(TestEPMapping1)]
@@ -29,8 +29,9 @@ describe("ExtensionPoint (in-memory)", () => {
29
29
  async () => {
30
30
  // Build the full command body: {id, meta, command}
31
31
  let forwardCmdJson =
32
- TestEPSpec.Forward({targetId: "target-1"})
33
- ->Reventless.Util_Sury.toJson(TestEPSpec.commandSchema)
32
+ TestEPSpec.Forward({targetId: "target-1"})->Reventless.Util_Sury.toJson(
33
+ TestEPSpec.commandSchema,
34
+ )
34
35
  let body = JSON.Encode.object(
35
36
  Dict.fromArray([
36
37
  ("id", JSON.Encode.string("ep-id-1")),
@@ -38,11 +38,10 @@ let mockPublish: ReventlessInfra.CommandTopic.publishJsons = async cmds => {
38
38
  let resolvedHandler: ref<option<(unit, unit) => promise<unit>>> = ref(None)
39
39
 
40
40
  let _ = beforeAllAsync(async () => {
41
- let h =
42
- await HeartbeatMaker.makeHandler(
43
- ~id="hb-id-1",
44
- ~timeout=1,
45
- ~publishToPluginExtensionPoint=mockPublish,
46
- )->TestRunner.resolve
41
+ let h = await HeartbeatMaker.makeHandler(
42
+ ~id="hb-id-1",
43
+ ~timeout=1,
44
+ ~publishToPluginExtensionPoint=mockPublish,
45
+ )->TestRunner.resolve
47
46
  resolvedHandler := Some(h)
48
47
  })
@@ -12,56 +12,65 @@ describe("Heartbeat_Builder.Make:", () => {
12
12
  })
13
13
 
14
14
  describe("makeHandler + connect:", () => {
15
- testPromise("handler fires once after 1-minute interval", async () => {
16
- let handler = resolvedHandler.contents->Option.getUnsafe
17
- let heartbeat = HeartbeatMaker.make(~name="hb-test-1")
18
- let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
19
- Deferred.make()->Effect.runSync
20
- Deferred.succeed(handlerDeferred, Obj.magic(handler))->Effect.runSync->ignore
21
- let runtime: ReventlessCore.Runtime.environment<LocalHeartbeatRunner.runtimeParts> = {
22
- parts: {
23
- handlerDeferred,
24
- subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
25
- },
26
- resources: [],
27
- }
28
- HeartbeatMaker.connect(~runtime, ~remoteChannel=Obj.magic(()), ~timeout=1, heartbeat)
29
- jest->advanceTimersByTime(1 * 60 * 1000)
30
- // Give the Effect.runPromise microtask one tick to complete
31
- let _ = await Promise.resolve()
32
- expect(capturedCount.contents)->toBe(1)
33
- LocalHeartbeatRunner.reset()
34
- })
15
+ testPromise(
16
+ "handler fires once after 1-minute interval",
17
+ async () => {
18
+ let handler = resolvedHandler.contents->Option.getUnsafe
19
+ let heartbeat = HeartbeatMaker.make(~name="hb-test-1")
20
+ let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
21
+ Deferred.make()->Effect.runSync
22
+ Deferred.succeed(handlerDeferred, Obj.magic(handler))->Effect.runSync->ignore
23
+ let runtime: ReventlessCore.Runtime.environment<LocalHeartbeatRunner.runtimeParts> = {
24
+ parts: {
25
+ handlerDeferred,
26
+ subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
27
+ },
28
+ resources: [],
29
+ }
30
+ HeartbeatMaker.connect(~runtime, ~remoteChannel=Obj.magic(), ~timeout=1, heartbeat)
31
+ jest->advanceTimersByTime(1 * 60 * 1000)
32
+ // Give the Effect.runPromise microtask one tick to complete
33
+ let _ = await Promise.resolve()
34
+ expect(capturedCount.contents)->toBe(1)
35
+ LocalHeartbeatRunner.reset()
36
+ },
37
+ )
35
38
 
36
- testPromise("handler fires twice after two interval advances", async () => {
37
- let handler = resolvedHandler.contents->Option.getUnsafe
38
- let heartbeat = HeartbeatMaker.make(~name="hb-test-2")
39
- let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
40
- Deferred.make()->Effect.runSync
41
- Deferred.succeed(handlerDeferred, Obj.magic(handler))->Effect.runSync->ignore
42
- let runtime: ReventlessCore.Runtime.environment<LocalHeartbeatRunner.runtimeParts> = {
43
- parts: {
44
- handlerDeferred,
45
- subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
46
- },
47
- resources: [],
48
- }
49
- HeartbeatMaker.connect(~runtime, ~remoteChannel=Obj.magic(()), ~timeout=1, heartbeat)
50
- jest->advanceTimersByTime(1 * 60 * 1000)
51
- let _ = await Promise.resolve()
52
- jest->advanceTimersByTime(1 * 60 * 1000)
53
- let _ = await Promise.resolve()
54
- expect(capturedCount.contents)->toBe(2)
55
- LocalHeartbeatRunner.reset()
56
- })
39
+ testPromise(
40
+ "handler fires twice after two interval advances",
41
+ async () => {
42
+ let handler = resolvedHandler.contents->Option.getUnsafe
43
+ let heartbeat = HeartbeatMaker.make(~name="hb-test-2")
44
+ let handlerDeferred: Deferred.t<LocalRuntimeEnvironment.handler, unit> =
45
+ Deferred.make()->Effect.runSync
46
+ Deferred.succeed(handlerDeferred, Obj.magic(handler))->Effect.runSync->ignore
47
+ let runtime: ReventlessCore.Runtime.environment<LocalHeartbeatRunner.runtimeParts> = {
48
+ parts: {
49
+ handlerDeferred,
50
+ subscriptionLatch: Effect.makeLatch(false)->Effect.runSync,
51
+ },
52
+ resources: [],
53
+ }
54
+ HeartbeatMaker.connect(~runtime, ~remoteChannel=Obj.magic(), ~timeout=1, heartbeat)
55
+ jest->advanceTimersByTime(1 * 60 * 1000)
56
+ let _ = await Promise.resolve()
57
+ jest->advanceTimersByTime(1 * 60 * 1000)
58
+ let _ = await Promise.resolve()
59
+ expect(capturedCount.contents)->toBe(2)
60
+ LocalHeartbeatRunner.reset()
61
+ },
62
+ )
57
63
  })
58
64
 
59
65
  describe("make:", () => {
60
- testPromise("creates a heartbeat component without throwing", async () => {
61
- let heartbeat = HeartbeatMaker.make(~name="hb-make-smoke")
62
- // Just verify component creation succeeds
63
- let _ = heartbeat
64
- expect(true)->toBe(true)
65
- })
66
+ testPromise(
67
+ "creates a heartbeat component without throwing",
68
+ async () => {
69
+ let heartbeat = HeartbeatMaker.make(~name="hb-make-smoke")
70
+ // Just verify component creation succeeds
71
+ let _ = heartbeat
72
+ expect(true)->toBe(true)
73
+ },
74
+ )
66
75
  })
67
76
  })