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

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 (170) hide show
  1. package/CHANGELOG.md +8 -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 +11 -15
  15. package/src/adapter/Auth/UserStore.res +5 -7
  16. package/src/adapter/Backend.res +1 -2
  17. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +42 -26
  18. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +13 -3
  19. package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +15 -17
  20. package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +18 -22
  21. package/src/adapter/Counter/LocalCounterHandler.res +1 -1
  22. package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +33 -22
  23. package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +57 -57
  24. package/src/adapter/DomainGraphQL_Server.res +35 -34
  25. package/src/adapter/DomainMCP_Server.res +45 -41
  26. package/src/adapter/EventCollector/LocalEventCollectorChannel.res +47 -36
  27. package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res +15 -12
  28. package/src/adapter/EventLog/EventLogStorage_InMemory.res +9 -4
  29. package/src/adapter/EventLog/EventLogStorage_Sqlite.res +36 -24
  30. package/src/adapter/EventTopic/LocalEventTopicPublisher.res +9 -3
  31. package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +9 -14
  32. package/src/adapter/LocalBus.res +12 -12
  33. package/src/adapter/LocalCapabilities.res.mjs +1 -1
  34. package/src/adapter/LocalGeocodeResolvers.res +1 -4
  35. package/src/adapter/LocalSideEffectHandler.res +1 -1
  36. package/src/adapter/LocalStateChangeDescriptor.res +2 -1
  37. package/src/adapter/MCP_ServerInstance.res +51 -39
  38. package/src/adapter/ObjectStore/LocalObjectStore.res +5 -2
  39. package/src/adapter/ObjectStore/ObjectStoreStorage_FileSystem.res +1 -2
  40. package/src/adapter/PlatformGraphQL_Server.res +9 -5
  41. package/src/adapter/ProjectionCheckpoint.res +8 -1
  42. package/src/adapter/ProjectionPending.res +1 -3
  43. package/src/adapter/QueryDb/LocalQueryDbStorage.res +2 -1
  44. package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +367 -269
  45. package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +5 -3
  46. package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +63 -40
  47. package/src/adapter/QueryDb/SortKey_Filter.res +14 -6
  48. package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +12 -10
  49. package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +8 -2
  50. package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +1 -4
  51. package/src/adapter/Scheduler/LocalScheduledPublisher.res +12 -12
  52. package/src/adapter/SqliteDriver.res +16 -4
  53. package/src/adapter/Task/TaskBucket_Sqlite.res +5 -6
  54. package/src/components/Aggregate_Builder.res +6 -1
  55. package/src/components/Counter_Builder.res +1 -5
  56. package/src/components/DcbEventLog_Builder.res +5 -3
  57. package/src/components/ExtensionPoint_Builder.res +13 -15
  58. package/src/components/InboundTranslationSlice_Builder.res +3 -2
  59. package/src/components/OutboundTranslationSlice_Builder.res +3 -2
  60. package/src/components/ReadModel_Builder.res +18 -20
  61. package/src/components/StateViewSlice_Builder.res +3 -2
  62. package/src/components/Task_Builder.res +12 -13
  63. package/src/reset/LocalSeedReset.res +2 -5
  64. package/src/test/Mocks/MockDcbEventLogStorage.res +5 -1
  65. package/src/test/Mocks/MockEventLogStorage.res +8 -3
  66. package/src/test/Mocks/MockQueryDbStorage.res +3 -2
  67. package/src/test/TestRunner.res +1 -1
  68. package/tests/BakedManifestFilesTest.res +7 -10
  69. package/tests/LocalEventTapTest.res +26 -21
  70. package/tests/LocalPlatformStartTest.res +33 -28
  71. package/tests/PluginEventDecodeTest.res +3 -3
  72. package/tests/ShellConfigTest.res +30 -21
  73. package/tests/SplitApiFixtures.res +34 -10
  74. package/tests/SplitApiTest.res +92 -62
  75. package/tests/adapter/BackendParityTest.res +180 -130
  76. package/tests/adapter/CollectNEventsTest.res +6 -4
  77. package/tests/adapter/CommandAuthorizationTest.res +47 -41
  78. package/tests/adapter/CommandTopicChannelTest.res +163 -139
  79. package/tests/adapter/CounterHandlerTest.res +95 -77
  80. package/tests/adapter/DcbEventLogStorageSqliteTest.res +171 -168
  81. package/tests/adapter/DcbEventLogStorageTest.res +264 -207
  82. package/tests/adapter/DomainGraphQL_ServerTest.res +53 -43
  83. package/tests/adapter/EventCollectorChannelTest.res +153 -124
  84. package/tests/adapter/EventHistoryResolverTest.res +46 -18
  85. package/tests/adapter/EventLogSnapshotParityTest.res +57 -45
  86. package/tests/adapter/EventLogStorageSqliteTest.res +9 -10
  87. package/tests/adapter/EventTapTest.res +37 -20
  88. package/tests/adapter/EventTopicPublisherTest.res +74 -50
  89. package/tests/adapter/GraphQLSubscriptionBridgeTest.res +4 -3
  90. package/tests/adapter/GraphQL_SchemaInspectorTest.res +666 -568
  91. package/tests/adapter/GraphQL_SubscriptionResolversTest.res +105 -96
  92. package/tests/adapter/HeartbeatRunnerTest.res +99 -81
  93. package/tests/adapter/InboundTranslationMutationTest.res +4 -1
  94. package/tests/adapter/LocalAuthHttpTest.res +79 -85
  95. package/tests/adapter/LocalAuthLoginTest.res +42 -50
  96. package/tests/adapter/LocalAuthTest.res +8 -16
  97. package/tests/adapter/LocalAuthUserStoreTest.res +2 -7
  98. package/tests/adapter/LocalBusBoundedTest.res +187 -117
  99. package/tests/adapter/LocalBusPubSubTest.res +118 -76
  100. package/tests/adapter/LocalDispatchContextTest.res +1 -2
  101. package/tests/adapter/LocalEvents_ServerTest.res +242 -187
  102. package/tests/adapter/PgProjectionCatchupTest.res +44 -10
  103. package/tests/adapter/ProjectionCheckpointTest.res +261 -206
  104. package/tests/adapter/QueryDbGsiTtlTest.res +123 -83
  105. package/tests/adapter/QueryDbListPushdownParityTest.res +107 -67
  106. package/tests/adapter/QueryDbListResolverTest.res +225 -208
  107. package/tests/adapter/QueryDbResolvedFieldsTest.res +17 -14
  108. package/tests/adapter/QueryDbStorageSqliteTest.res +33 -49
  109. package/tests/adapter/QueryDbStorageTest.res +163 -117
  110. package/tests/adapter/QueryDbUnionRoundTripTest.res +8 -10
  111. package/tests/adapter/QueryEngineTest.res +179 -126
  112. package/tests/adapter/ScheduledPublisherTest.res +171 -135
  113. package/tests/adapter/ServedBucketHttpTest.res +65 -59
  114. package/tests/adapter/SortKey_FilterTest.res +19 -3
  115. package/tests/adapter/SqliteDriverTest.res +13 -10
  116. package/tests/adapter/TaskBucketTest.res +94 -80
  117. package/tests/components/aggregate/AggregateTest.res +31 -18
  118. package/tests/components/automationslice/AutomationSliceCallbackTest.res +259 -222
  119. package/tests/components/automationslice/AutomationSliceFixtures.res +4 -2
  120. package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +38 -38
  121. package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +12 -14
  122. package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +8 -32
  123. package/tests/components/commandgenerator/CommandGeneratorFixtures.res +7 -5
  124. package/tests/components/commandgenerator/CommandGeneratorTest.res +40 -31
  125. package/tests/components/commandtopic/CommandTopicFixtures.res +3 -4
  126. package/tests/components/commandtopic/CommandTopicStreamFixtures.res +7 -5
  127. package/tests/components/commandtopic/CommandTopicTest.res +24 -15
  128. package/tests/components/counter/CounterFixtures.res +6 -8
  129. package/tests/components/dcb/DcbCrossPartitionFixtures.res +8 -2
  130. package/tests/components/dcb/DcbCrossPartitionReadTest.res +20 -13
  131. package/tests/components/dcb/DcbEventLogAppendStreamTest.res +12 -8
  132. package/tests/components/dcb/DcbEventLogStreamTest.res +88 -61
  133. package/tests/components/dcb/DcbFixtures.res +4 -1
  134. package/tests/components/dcb/DcbTest.res +9 -6
  135. package/tests/components/eventcollector/EventCollectorFixtures.res +0 -1
  136. package/tests/components/eventcollector/EventCollectorTest.res +6 -3
  137. package/tests/components/eventlog/EventLogAppendStreamTest.res +88 -68
  138. package/tests/components/eventlog/EventLogConflictTest.res +8 -4
  139. package/tests/components/eventlog/EventLogFixtures.res +3 -3
  140. package/tests/components/eventlog/EventLogProvisioningSeamTest.res +26 -13
  141. package/tests/components/eventlog/EventLogStreamTest.res +119 -56
  142. package/tests/components/eventlog/EventLogTest.res +20 -4
  143. package/tests/components/eventtopic/EventTopicFixtures.res +3 -3
  144. package/tests/components/eventtopic/EventTopicStreamFixtures.res +1 -2
  145. package/tests/components/eventtopic/EventTopicStreamTest.res +7 -1
  146. package/tests/components/extensionpoint/ExtensionPointFixtures.res +14 -9
  147. package/tests/components/extensionpoint/ExtensionPointTest.res +3 -2
  148. package/tests/components/heartbeat/HeartbeatFixtures.res +5 -6
  149. package/tests/components/heartbeat/HeartbeatTest.res +56 -47
  150. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +271 -249
  151. package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +3 -2
  152. package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +361 -276
  153. package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +8 -10
  154. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +37 -43
  155. package/tests/components/querydb/QueryDbFixtures.res +1 -5
  156. package/tests/components/querydb/QueryDbTest.res +2 -4
  157. package/tests/components/readmodel/DcbReadModelE2EFixtures.res +15 -18
  158. package/tests/components/readmodel/MixedSourceReadModelFixtures.res +5 -7
  159. package/tests/components/readmodel/ReadModelFixtures.res +8 -8
  160. package/tests/components/scheduler/SchedulerTest.res +76 -58
  161. package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +4 -4
  162. package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res +5 -7
  163. package/tests/components/stateviewslice/StateViewSliceFixtures.res +8 -6
  164. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +17 -11
  165. package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +12 -2
  166. package/tests/components/task/TaskFixtures.res +5 -5
  167. package/tests/components/task/TaskTest.res +95 -80
  168. package/tests/plugin/PluginsProjection_GWT.res +3 -1
  169. package/tests/plugin/UiFragments_GWT.res +6 -1
  170. package/tests/reset/LocalSeedResetTest.res +1 -0
@@ -30,65 +30,69 @@ let appendErrMsg = e =>
30
30
 
31
31
  describe("DcbEventLogStorage_Sqlite", () => {
32
32
  testPromise("append + read round-trips events with tags", async () => {
33
- await runUnderSqlite(async () => {
34
- module TestBus = LocalBus.Make()
35
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
36
- let s = Storage.make(
37
- ~name="dcb-rt",
38
- ~indexes=[],
39
- ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
40
- ~opts,
41
- )
42
- let ops = await s.operations->TestRunner.resolve
33
+ await runUnderSqlite(
34
+ async () => {
35
+ module TestBus = LocalBus.Make()
36
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
37
+ let s = Storage.make(
38
+ ~name="dcb-rt",
39
+ ~indexes=[],
40
+ ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
41
+ ~opts,
42
+ )
43
+ let ops = await s.operations->TestRunner.resolve
43
44
 
44
- let tag1: Reventless.DcbTag.tag = {key: "itemId", value: "x1"}
45
- let e1 = stored(
46
- "ItemAdded",
47
- [tag1],
48
- JSON.Encode.object(Dict.fromArray([("name", JSON.Encode.string("widget"))])),
49
- )
50
- let result = await ops.append([e1])
51
- switch result {
52
- | Ok(_) => expect(true)->toBe(true)
53
- | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
54
- }
45
+ let tag1: Reventless.DcbTag.tag = {key: "itemId", value: "x1"}
46
+ let e1 = stored(
47
+ "ItemAdded",
48
+ [tag1],
49
+ JSON.Encode.object(Dict.fromArray([("name", JSON.Encode.string("widget"))])),
50
+ )
51
+ let result = await ops.append([e1])
52
+ switch result {
53
+ | Ok(_) => expect(true)->toBe(true)
54
+ | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
55
+ }
55
56
 
56
- let read = await ops.read(~query=[])
57
- expect(read.events->Array.length)->toBe(1)
58
- let first = read.events->Array.getUnsafe(0)
59
- expect(first.eventType)->toBe("ItemAdded")
60
- expect(first.tags->Array.length)->toBe(1)
61
- expect((first.tags->Array.getUnsafe(0)).key)->toBe("itemId")
62
- expect((first.tags->Array.getUnsafe(0)).value)->toBe("x1")
63
- })
57
+ let read = await ops.read(~query=[])
58
+ expect(read.events->Array.length)->toBe(1)
59
+ let first = read.events->Array.getUnsafe(0)
60
+ expect(first.eventType)->toBe("ItemAdded")
61
+ expect(first.tags->Array.length)->toBe(1)
62
+ expect((first.tags->Array.getUnsafe(0)).key)->toBe("itemId")
63
+ expect((first.tags->Array.getUnsafe(0)).value)->toBe("x1")
64
+ },
65
+ )
64
66
  })
65
67
 
66
68
  testPromise("read filters by tag", async () => {
67
- await runUnderSqlite(async () => {
68
- module TestBus = LocalBus.Make()
69
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
70
- let s = Storage.make(
71
- ~name="dcb-tagfilter",
72
- ~indexes=[],
73
- ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
74
- ~opts,
75
- )
76
- let ops = await s.operations->TestRunner.resolve
77
-
78
- let mk = (id, name) =>
79
- stored(
80
- "ItemAdded",
81
- [{key: "itemId", value: id}],
82
- JSON.Encode.object(Dict.fromArray([("name", JSON.Encode.string(name))])),
69
+ await runUnderSqlite(
70
+ async () => {
71
+ module TestBus = LocalBus.Make()
72
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
73
+ let s = Storage.make(
74
+ ~name="dcb-tagfilter",
75
+ ~indexes=[],
76
+ ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
77
+ ~opts,
83
78
  )
79
+ let ops = await s.operations->TestRunner.resolve
84
80
 
85
- let _ = await ops.append([mk("a1", "alpha")])
86
- let _ = await ops.append([mk("b1", "beta")])
87
- let _ = await ops.append([mk("a1", "again")])
81
+ let mk = (id, name) =>
82
+ stored(
83
+ "ItemAdded",
84
+ [{key: "itemId", value: id}],
85
+ JSON.Encode.object(Dict.fromArray([("name", JSON.Encode.string(name))])),
86
+ )
88
87
 
89
- let read = await ops.read(~query=[{tags: [{key: "itemId", value: "a1"}]}])
90
- expect(read.events->Array.length)->toBe(2)
91
- })
88
+ let _ = await ops.append([mk("a1", "alpha")])
89
+ let _ = await ops.append([mk("b1", "beta")])
90
+ let _ = await ops.append([mk("a1", "again")])
91
+
92
+ let read = await ops.read(~query=[{tags: [{key: "itemId", value: "a1"}]}])
93
+ expect(read.events->Array.length)->toBe(2)
94
+ },
95
+ )
92
96
  })
93
97
 
94
98
  // Backend contract: an empty tag value (an absent composite-partition member) is
@@ -96,135 +100,138 @@ describe("DcbEventLogStorage_Sqlite", () => {
96
100
  // the partition read and a composite read. Held identically by the in-memory and
97
101
  // DynamoDB backends. See docs/plans/done/dcb-empty-tag-values-break-append.md.
98
102
  testPromise("an empty tag value appends and stays readable", async () => {
99
- await runUnderSqlite(async () => {
100
- module TestBus = LocalBus.Make()
101
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
102
- let s = Storage.make(
103
- ~name="dcb-emptytag",
104
- ~indexes=[],
105
- ~partitionTag=Reventless.DcbTag.Simple({key: "itemId"}),
106
- ~opts,
107
- )
108
- let ops = await s.operations->TestRunner.resolve
103
+ await runUnderSqlite(
104
+ async () => {
105
+ module TestBus = LocalBus.Make()
106
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
107
+ let s = Storage.make(
108
+ ~name="dcb-emptytag",
109
+ ~indexes=[],
110
+ ~partitionTag=Reventless.DcbTag.Simple({key: "itemId"}),
111
+ ~opts,
112
+ )
113
+ let ops = await s.operations->TestRunner.resolve
109
114
 
110
- let tags = [{Reventless.DcbTag.key: "itemId", value: "i1"}, {key: "variantId", value: ""}]
111
- let result = await ops.append([stored("ItemAdded", tags, JSON.Encode.string("x"))])
112
- switch result {
113
- | Ok(_) => expect(true)->toBe(true)
114
- | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
115
- }
115
+ let tags = [{Reventless.DcbTag.key: "itemId", value: "i1"}, {key: "variantId", value: ""}]
116
+ let result = await ops.append([stored("ItemAdded", tags, JSON.Encode.string("x"))])
117
+ switch result {
118
+ | Ok(_) => expect(true)->toBe(true)
119
+ | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
120
+ }
116
121
 
117
- let byPartition = await ops.read(~query=[{tags: [{key: "itemId", value: "i1"}]}])
118
- expect(byPartition.events->Array.length)->toBe(1)
119
- expect((byPartition.events->Array.getUnsafe(0)).tags->Array.map(t => (t.key, t.value)))
120
- ->toEqual([("itemId", "i1"), ("variantId", "")])
122
+ let byPartition = await ops.read(~query=[{tags: [{key: "itemId", value: "i1"}]}])
123
+ expect(byPartition.events->Array.length)->toBe(1)
124
+ expect(
125
+ (byPartition.events->Array.getUnsafe(0)).tags->Array.map(t => (t.key, t.value)),
126
+ )->toEqual([("itemId", "i1"), ("variantId", "")])
121
127
 
122
- let byComposite = await ops.read(~query=[{tags: tags}])
123
- expect(byComposite.events->Array.length)->toBe(1)
124
- })
128
+ let byComposite = await ops.read(~query=[{tags: tags}])
129
+ expect(byComposite.events->Array.length)->toBe(1)
130
+ },
131
+ )
125
132
  })
126
133
 
127
134
  testPromise("batched tag hydration preserves per-event tags and order", async () => {
128
- await runUnderSqlite(async () => {
129
- module TestBus = LocalBus.Make()
130
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
131
- let s = Storage.make(
132
- ~name="dcb-multitag",
133
- ~indexes=[],
134
- ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
135
- ~opts,
136
- )
137
- let ops = await s.operations->TestRunner.resolve
135
+ await runUnderSqlite(
136
+ async () => {
137
+ module TestBus = LocalBus.Make()
138
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
139
+ let s = Storage.make(
140
+ ~name="dcb-multitag",
141
+ ~indexes=[],
142
+ ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
143
+ ~opts,
144
+ )
145
+ let ops = await s.operations->TestRunner.resolve
138
146
 
139
- // e1 carries three tags (declaration order matters); e2 carries one; e3 none.
140
- let e1 = stored(
141
- "Multi",
142
- [
143
- {key: "a", value: "1"},
144
- {key: "b", value: "2"},
145
- {key: "c", value: "3"},
146
- ],
147
- JSON.Encode.string("first"),
148
- )
149
- let e2 = stored("Single", [{key: "only", value: "z"}], JSON.Encode.string("second"))
150
- let e3 = stored("None", [], JSON.Encode.string("third"))
151
- let _ = await ops.append([e1])
152
- let _ = await ops.append([e2])
153
- let _ = await ops.append([e3])
147
+ // e1 carries three tags (declaration order matters); e2 carries one; e3 none.
148
+ let e1 = stored(
149
+ "Multi",
150
+ [{key: "a", value: "1"}, {key: "b", value: "2"}, {key: "c", value: "3"}],
151
+ JSON.Encode.string("first"),
152
+ )
153
+ let e2 = stored("Single", [{key: "only", value: "z"}], JSON.Encode.string("second"))
154
+ let e3 = stored("None", [], JSON.Encode.string("third"))
155
+ let _ = await ops.append([e1])
156
+ let _ = await ops.append([e2])
157
+ let _ = await ops.append([e3])
154
158
 
155
- let read = await ops.read(~query=[])
156
- expect(read.events->Array.length)->toBe(3)
157
- let first = read.events->Array.getUnsafe(0)
158
- // Order and grouping survive the single batched IN query.
159
- expect(first.tags->Array.map(t => t.key))->toEqual(["a", "b", "c"])
160
- expect(first.tags->Array.map(t => t.value))->toEqual(["1", "2", "3"])
161
- let second = read.events->Array.getUnsafe(1)
162
- expect(second.tags->Array.length)->toBe(1)
163
- expect((second.tags->Array.getUnsafe(0)).key)->toBe("only")
164
- let third = read.events->Array.getUnsafe(2)
165
- expect(third.tags->Array.length)->toBe(0)
166
- })
159
+ let read = await ops.read(~query=[])
160
+ expect(read.events->Array.length)->toBe(3)
161
+ let first = read.events->Array.getUnsafe(0)
162
+ // Order and grouping survive the single batched IN query.
163
+ expect(first.tags->Array.map(t => t.key))->toEqual(["a", "b", "c"])
164
+ expect(first.tags->Array.map(t => t.value))->toEqual(["1", "2", "3"])
165
+ let second = read.events->Array.getUnsafe(1)
166
+ expect(second.tags->Array.length)->toBe(1)
167
+ expect((second.tags->Array.getUnsafe(0)).key)->toBe("only")
168
+ let third = read.events->Array.getUnsafe(2)
169
+ expect(third.tags->Array.length)->toBe(0)
170
+ },
171
+ )
167
172
  })
168
173
 
169
174
  testPromise("append with a non-conflicting condition succeeds", async () => {
170
- await runUnderSqlite(async () => {
171
- module TestBus = LocalBus.Make()
172
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
173
- let s = Storage.make(
174
- ~name="dcb-noconflict",
175
- ~indexes=[],
176
- ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
177
- ~opts,
178
- )
179
- let ops = await s.operations->TestRunner.resolve
175
+ await runUnderSqlite(
176
+ async () => {
177
+ module TestBus = LocalBus.Make()
178
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
179
+ let s = Storage.make(
180
+ ~name="dcb-noconflict",
181
+ ~indexes=[],
182
+ ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
183
+ ~opts,
184
+ )
185
+ let ops = await s.operations->TestRunner.resolve
180
186
 
181
- let _ = await ops.append([stored("Created", [{key: "id", value: "x"}], JSON.Encode.string("a"))])
182
- // Condition queries a tag value that does not exist → anyMatch is false →
183
- // the append is allowed.
184
- let cond: Reventless.DcbTag.appendCondition = {
185
- query: [{tags: [{key: "id", value: "other"}]}],
186
- }
187
- let result = await ops.append(
188
- [stored("Created", [{key: "id", value: "other"}], JSON.Encode.string("b"))],
189
- ~condition=cond,
190
- )
191
- switch result {
192
- | Ok(_) => expect(true)->toBe(true)
193
- | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
194
- }
195
- let read = await ops.read(~query=[])
196
- expect(read.events->Array.length)->toBe(2)
197
- })
187
+ let _ = await ops.append([
188
+ stored("Created", [{key: "id", value: "x"}], JSON.Encode.string("a")),
189
+ ])
190
+ // Condition queries a tag value that does not exist → anyMatch is false →
191
+ // the append is allowed.
192
+ let cond: Reventless.DcbTag.appendCondition = {
193
+ query: [{tags: [{key: "id", value: "other"}]}],
194
+ }
195
+ let result = await ops.append(
196
+ [stored("Created", [{key: "id", value: "other"}], JSON.Encode.string("b"))],
197
+ ~condition=cond,
198
+ )
199
+ switch result {
200
+ | Ok(_) => expect(true)->toBe(true)
201
+ | Error(e) => expect(appendErrMsg(e))->toBe("Ok")
202
+ }
203
+ let read = await ops.read(~query=[])
204
+ expect(read.events->Array.length)->toBe(2)
205
+ },
206
+ )
198
207
  })
199
208
 
200
209
  testPromise("append with conflicting condition returns Error", async () => {
201
- await runUnderSqlite(async () => {
202
- module TestBus = LocalBus.Make()
203
- module Storage = LocalDcbEventLogStorage.Make(TestBus)
204
- let s = Storage.make(
205
- ~name="dcb-conflict",
206
- ~indexes=[],
207
- ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
208
- ~opts,
209
- )
210
- let ops = await s.operations->TestRunner.resolve
210
+ await runUnderSqlite(
211
+ async () => {
212
+ module TestBus = LocalBus.Make()
213
+ module Storage = LocalDcbEventLogStorage.Make(TestBus)
214
+ let s = Storage.make(
215
+ ~name="dcb-conflict",
216
+ ~indexes=[],
217
+ ~partitionTag=Reventless.DcbTag.Simple({key: "k"}),
218
+ ~opts,
219
+ )
220
+ let ops = await s.operations->TestRunner.resolve
211
221
 
212
- let e = stored(
213
- "Created",
214
- [{key: "id", value: "x"}],
215
- JSON.Encode.string("first"),
216
- )
217
- let _ = await ops.append([e])
222
+ let e = stored("Created", [{key: "id", value: "x"}], JSON.Encode.string("first"))
223
+ let _ = await ops.append([e])
218
224
 
219
- let cond: Reventless.DcbTag.appendCondition = {
220
- query: [{tags: [{key: "id", value: "x"}]}],
221
- }
222
- let result = await ops.append([e], ~condition=cond)
223
- switch result {
224
- | Error(_) => expect(true)->toBe(true)
225
- | Ok(_) => expect("expected conflict")->toBe("got Ok")
226
- }
227
- })
225
+ let cond: Reventless.DcbTag.appendCondition = {
226
+ query: [{tags: [{key: "id", value: "x"}]}],
227
+ }
228
+ let result = await ops.append([e], ~condition=cond)
229
+ switch result {
230
+ | Error(_) => expect(true)->toBe(true)
231
+ | Ok(_) => expect("expected conflict")->toBe("got Ok")
232
+ }
233
+ },
234
+ )
228
235
  })
229
236
 
230
237
  testPromise("events persist across a file reopen", async () => {
@@ -242,11 +249,7 @@ describe("DcbEventLogStorage_Sqlite", () => {
242
249
  ~opts,
243
250
  )
244
251
  let ops = await s.operations->TestRunner.resolve
245
- let e = stored(
246
- "Created",
247
- [{key: "id", value: "p"}],
248
- JSON.Encode.int(1),
249
- )
252
+ let e = stored("Created", [{key: "id", value: "p"}], JSON.Encode.int(1))
250
253
  let _ = await ops.append([e])
251
254
  db->SqliteDriver.close
252
255
  BackendState.setMemory()