@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.
- package/CHANGELOG.md +8 -0
- package/package.json +13 -13
- package/src/BakedManifest.res +5 -6
- package/src/EmitCapabilities.res +3 -1
- package/src/LocalPlatformRegistry.res +3 -1
- package/src/LocalPlatformStart.res +7 -6
- package/src/LocalSeedTarget.res +3 -1
- package/src/Platform.res +291 -215
- package/src/ShellConfig.res +10 -17
- package/src/UiHints.res +8 -14
- package/src/UiSlots.res +10 -17
- package/src/adapter/Api/LocalEvents_Server.res +5 -3
- package/src/adapter/Api/LocalGraphQL_Adapter.res +4 -4
- package/src/adapter/Auth/LocalAuth.res +11 -15
- package/src/adapter/Auth/UserStore.res +5 -7
- package/src/adapter/Backend.res +1 -2
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +42 -26
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +13 -3
- package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +15 -17
- package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +18 -22
- package/src/adapter/Counter/LocalCounterHandler.res +1 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +33 -22
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +57 -57
- package/src/adapter/DomainGraphQL_Server.res +35 -34
- package/src/adapter/DomainMCP_Server.res +45 -41
- package/src/adapter/EventCollector/LocalEventCollectorChannel.res +47 -36
- package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res +15 -12
- package/src/adapter/EventLog/EventLogStorage_InMemory.res +9 -4
- package/src/adapter/EventLog/EventLogStorage_Sqlite.res +36 -24
- package/src/adapter/EventTopic/LocalEventTopicPublisher.res +9 -3
- package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +9 -14
- package/src/adapter/LocalBus.res +12 -12
- package/src/adapter/LocalCapabilities.res.mjs +1 -1
- package/src/adapter/LocalGeocodeResolvers.res +1 -4
- package/src/adapter/LocalSideEffectHandler.res +1 -1
- package/src/adapter/LocalStateChangeDescriptor.res +2 -1
- package/src/adapter/MCP_ServerInstance.res +51 -39
- package/src/adapter/ObjectStore/LocalObjectStore.res +5 -2
- package/src/adapter/ObjectStore/ObjectStoreStorage_FileSystem.res +1 -2
- package/src/adapter/PlatformGraphQL_Server.res +9 -5
- package/src/adapter/ProjectionCheckpoint.res +8 -1
- package/src/adapter/ProjectionPending.res +1 -3
- package/src/adapter/QueryDb/LocalQueryDbStorage.res +2 -1
- package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +367 -269
- package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +5 -3
- package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +63 -40
- package/src/adapter/QueryDb/SortKey_Filter.res +14 -6
- package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +12 -10
- package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +8 -2
- package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +1 -4
- package/src/adapter/Scheduler/LocalScheduledPublisher.res +12 -12
- package/src/adapter/SqliteDriver.res +16 -4
- package/src/adapter/Task/TaskBucket_Sqlite.res +5 -6
- package/src/components/Aggregate_Builder.res +6 -1
- package/src/components/Counter_Builder.res +1 -5
- package/src/components/DcbEventLog_Builder.res +5 -3
- package/src/components/ExtensionPoint_Builder.res +13 -15
- package/src/components/InboundTranslationSlice_Builder.res +3 -2
- package/src/components/OutboundTranslationSlice_Builder.res +3 -2
- package/src/components/ReadModel_Builder.res +18 -20
- package/src/components/StateViewSlice_Builder.res +3 -2
- package/src/components/Task_Builder.res +12 -13
- package/src/reset/LocalSeedReset.res +2 -5
- package/src/test/Mocks/MockDcbEventLogStorage.res +5 -1
- package/src/test/Mocks/MockEventLogStorage.res +8 -3
- package/src/test/Mocks/MockQueryDbStorage.res +3 -2
- package/src/test/TestRunner.res +1 -1
- package/tests/BakedManifestFilesTest.res +7 -10
- package/tests/LocalEventTapTest.res +26 -21
- package/tests/LocalPlatformStartTest.res +33 -28
- package/tests/PluginEventDecodeTest.res +3 -3
- package/tests/ShellConfigTest.res +30 -21
- package/tests/SplitApiFixtures.res +34 -10
- package/tests/SplitApiTest.res +92 -62
- package/tests/adapter/BackendParityTest.res +180 -130
- package/tests/adapter/CollectNEventsTest.res +6 -4
- package/tests/adapter/CommandAuthorizationTest.res +47 -41
- package/tests/adapter/CommandTopicChannelTest.res +163 -139
- package/tests/adapter/CounterHandlerTest.res +95 -77
- package/tests/adapter/DcbEventLogStorageSqliteTest.res +171 -168
- package/tests/adapter/DcbEventLogStorageTest.res +264 -207
- package/tests/adapter/DomainGraphQL_ServerTest.res +53 -43
- package/tests/adapter/EventCollectorChannelTest.res +153 -124
- package/tests/adapter/EventHistoryResolverTest.res +46 -18
- package/tests/adapter/EventLogSnapshotParityTest.res +57 -45
- package/tests/adapter/EventLogStorageSqliteTest.res +9 -10
- package/tests/adapter/EventTapTest.res +37 -20
- package/tests/adapter/EventTopicPublisherTest.res +74 -50
- package/tests/adapter/GraphQLSubscriptionBridgeTest.res +4 -3
- package/tests/adapter/GraphQL_SchemaInspectorTest.res +666 -568
- package/tests/adapter/GraphQL_SubscriptionResolversTest.res +105 -96
- package/tests/adapter/HeartbeatRunnerTest.res +99 -81
- package/tests/adapter/InboundTranslationMutationTest.res +4 -1
- package/tests/adapter/LocalAuthHttpTest.res +79 -85
- package/tests/adapter/LocalAuthLoginTest.res +42 -50
- package/tests/adapter/LocalAuthTest.res +8 -16
- package/tests/adapter/LocalAuthUserStoreTest.res +2 -7
- package/tests/adapter/LocalBusBoundedTest.res +187 -117
- package/tests/adapter/LocalBusPubSubTest.res +118 -76
- package/tests/adapter/LocalDispatchContextTest.res +1 -2
- package/tests/adapter/LocalEvents_ServerTest.res +242 -187
- package/tests/adapter/PgProjectionCatchupTest.res +44 -10
- package/tests/adapter/ProjectionCheckpointTest.res +261 -206
- package/tests/adapter/QueryDbGsiTtlTest.res +123 -83
- package/tests/adapter/QueryDbListPushdownParityTest.res +107 -67
- package/tests/adapter/QueryDbListResolverTest.res +225 -208
- package/tests/adapter/QueryDbResolvedFieldsTest.res +17 -14
- package/tests/adapter/QueryDbStorageSqliteTest.res +33 -49
- package/tests/adapter/QueryDbStorageTest.res +163 -117
- package/tests/adapter/QueryDbUnionRoundTripTest.res +8 -10
- package/tests/adapter/QueryEngineTest.res +179 -126
- package/tests/adapter/ScheduledPublisherTest.res +171 -135
- package/tests/adapter/ServedBucketHttpTest.res +65 -59
- package/tests/adapter/SortKey_FilterTest.res +19 -3
- package/tests/adapter/SqliteDriverTest.res +13 -10
- package/tests/adapter/TaskBucketTest.res +94 -80
- package/tests/components/aggregate/AggregateTest.res +31 -18
- package/tests/components/automationslice/AutomationSliceCallbackTest.res +259 -222
- package/tests/components/automationslice/AutomationSliceFixtures.res +4 -2
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +38 -38
- package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +12 -14
- package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +8 -32
- package/tests/components/commandgenerator/CommandGeneratorFixtures.res +7 -5
- package/tests/components/commandgenerator/CommandGeneratorTest.res +40 -31
- package/tests/components/commandtopic/CommandTopicFixtures.res +3 -4
- package/tests/components/commandtopic/CommandTopicStreamFixtures.res +7 -5
- package/tests/components/commandtopic/CommandTopicTest.res +24 -15
- package/tests/components/counter/CounterFixtures.res +6 -8
- package/tests/components/dcb/DcbCrossPartitionFixtures.res +8 -2
- package/tests/components/dcb/DcbCrossPartitionReadTest.res +20 -13
- package/tests/components/dcb/DcbEventLogAppendStreamTest.res +12 -8
- package/tests/components/dcb/DcbEventLogStreamTest.res +88 -61
- package/tests/components/dcb/DcbFixtures.res +4 -1
- package/tests/components/dcb/DcbTest.res +9 -6
- package/tests/components/eventcollector/EventCollectorFixtures.res +0 -1
- package/tests/components/eventcollector/EventCollectorTest.res +6 -3
- package/tests/components/eventlog/EventLogAppendStreamTest.res +88 -68
- package/tests/components/eventlog/EventLogConflictTest.res +8 -4
- package/tests/components/eventlog/EventLogFixtures.res +3 -3
- package/tests/components/eventlog/EventLogProvisioningSeamTest.res +26 -13
- package/tests/components/eventlog/EventLogStreamTest.res +119 -56
- package/tests/components/eventlog/EventLogTest.res +20 -4
- package/tests/components/eventtopic/EventTopicFixtures.res +3 -3
- package/tests/components/eventtopic/EventTopicStreamFixtures.res +1 -2
- package/tests/components/eventtopic/EventTopicStreamTest.res +7 -1
- package/tests/components/extensionpoint/ExtensionPointFixtures.res +14 -9
- package/tests/components/extensionpoint/ExtensionPointTest.res +3 -2
- package/tests/components/heartbeat/HeartbeatFixtures.res +5 -6
- package/tests/components/heartbeat/HeartbeatTest.res +56 -47
- package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +271 -249
- package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +3 -2
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +361 -276
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +8 -10
- package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +37 -43
- package/tests/components/querydb/QueryDbFixtures.res +1 -5
- package/tests/components/querydb/QueryDbTest.res +2 -4
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res +15 -18
- package/tests/components/readmodel/MixedSourceReadModelFixtures.res +5 -7
- package/tests/components/readmodel/ReadModelFixtures.res +8 -8
- package/tests/components/scheduler/SchedulerTest.res +76 -58
- package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +4 -4
- package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res +5 -7
- package/tests/components/stateviewslice/StateViewSliceFixtures.res +8 -6
- package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +17 -11
- package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +12 -2
- package/tests/components/task/TaskFixtures.res +5 -5
- package/tests/components/task/TaskTest.res +95 -80
- package/tests/plugin/PluginsProjection_GWT.res +3 -1
- package/tests/plugin/UiFragments_GWT.res +6 -1
- package/tests/reset/LocalSeedResetTest.res +1 -0
|
@@ -20,93 +20,135 @@ let defaultMeta: Reventless.Message.meta = {
|
|
|
20
20
|
|
|
21
21
|
describe("LocalBus PubSub (Phase F)", () => {
|
|
22
22
|
describe("publishEvent timing", () => {
|
|
23
|
-
testPromise(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
delivered
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
testPromise(
|
|
24
|
+
"resolves after exactly 2 microtask ticks",
|
|
25
|
+
async () => {
|
|
26
|
+
module TestBus = LocalBus.Make()
|
|
27
|
+
let delivered = ref(false)
|
|
28
|
+
TestBus.subscribeToEvents(
|
|
29
|
+
"T",
|
|
30
|
+
async (_, _, _) => {
|
|
31
|
+
delivered := true
|
|
32
|
+
},
|
|
33
|
+
)
|
|
34
|
+
// Start publishEvent without awaiting — drive manually tick by tick.
|
|
35
|
+
let pubPromise = TestBus.publishEvent("T", "svc", defaultMeta, JSON.parseOrThrow("{}"))
|
|
36
|
+
// Tick 0: publish is synchronous; drain fiber hasn't run yet.
|
|
37
|
+
expect(delivered.contents)->toBe(false)
|
|
38
|
+
// Tick 1: Effect scheduler runs drain fiber; handler sets delivered.
|
|
39
|
+
let _ = await Promise.resolve()
|
|
40
|
+
// Tick 2: allDone Deferred resolves; pubPromise completes.
|
|
41
|
+
let _ = await Promise.resolve()
|
|
42
|
+
let _ = await pubPromise
|
|
43
|
+
expect(delivered.contents)->toBe(true)
|
|
44
|
+
},
|
|
45
|
+
)
|
|
40
46
|
|
|
41
|
-
testPromise(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
testPromise(
|
|
48
|
+
"publishEvent with no subscribers returns immediately",
|
|
49
|
+
async () => {
|
|
50
|
+
module TestBus = LocalBus.Make()
|
|
51
|
+
// No subscribers registered — should not hang.
|
|
52
|
+
await TestBus.publishEvent("empty-topic", "svc", defaultMeta, JSON.Null)
|
|
53
|
+
// If we reach here the test passes (no timeout/hang).
|
|
54
|
+
},
|
|
55
|
+
)
|
|
47
56
|
})
|
|
48
57
|
|
|
49
58
|
describe("fan-out", () => {
|
|
50
|
-
testPromise(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
testPromise(
|
|
60
|
+
"delivers to all subscribers on the same topic",
|
|
61
|
+
async () => {
|
|
62
|
+
module TestBus = LocalBus.Make()
|
|
63
|
+
let count = ref(0)
|
|
64
|
+
TestBus.subscribeToEvents(
|
|
65
|
+
"T",
|
|
66
|
+
async (_, _, _) => {
|
|
67
|
+
count := count.contents + 1
|
|
68
|
+
},
|
|
69
|
+
)
|
|
70
|
+
TestBus.subscribeToEvents(
|
|
71
|
+
"T",
|
|
72
|
+
async (_, _, _) => {
|
|
73
|
+
count := count.contents + 1
|
|
74
|
+
},
|
|
75
|
+
)
|
|
76
|
+
TestBus.subscribeToEvents(
|
|
77
|
+
"T",
|
|
78
|
+
async (_, _, _) => {
|
|
79
|
+
count := count.contents + 1
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
let _ = await TestBus.publishEvent("T", "svc", defaultMeta, JSON.parseOrThrow("{}"))
|
|
83
|
+
expect(count.contents)->toBe(3)
|
|
84
|
+
},
|
|
85
|
+
)
|
|
65
86
|
|
|
66
|
-
testPromise(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
testPromise(
|
|
88
|
+
"publishing to topic-a does not reach topic-b subscribers",
|
|
89
|
+
async () => {
|
|
90
|
+
module TestBus = LocalBus.Make()
|
|
91
|
+
let countA = ref(0)
|
|
92
|
+
let countB = ref(0)
|
|
93
|
+
TestBus.subscribeToEvents(
|
|
94
|
+
"topic-a",
|
|
95
|
+
async (_, _, _) => {
|
|
96
|
+
countA := countA.contents + 1
|
|
97
|
+
},
|
|
98
|
+
)
|
|
99
|
+
TestBus.subscribeToEvents(
|
|
100
|
+
"topic-b",
|
|
101
|
+
async (_, _, _) => {
|
|
102
|
+
countB := countB.contents + 1
|
|
103
|
+
},
|
|
104
|
+
)
|
|
105
|
+
let _ = await TestBus.publishEvent("topic-a", "svc", defaultMeta, JSON.Null)
|
|
106
|
+
expect(countA.contents)->toBe(1)
|
|
107
|
+
expect(countB.contents)->toBe(0)
|
|
108
|
+
},
|
|
109
|
+
)
|
|
80
110
|
})
|
|
81
111
|
|
|
82
112
|
// A5: a throwing/rejecting subscriber must not (a) hang publishEvent (its
|
|
83
113
|
// done_ countdown never reaching zero) nor (b) kill the drain fiber so the
|
|
84
114
|
// topic stops working. If either regressed, these tests would time out.
|
|
85
115
|
describe("failing subscriber", () => {
|
|
86
|
-
testPromise(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
testPromise(
|
|
117
|
+
"a throwing subscriber does not hang publish; healthy siblings still receive it",
|
|
118
|
+
async () => {
|
|
119
|
+
module TestBus = LocalBus.Make()
|
|
120
|
+
let healthy = ref(0)
|
|
121
|
+
TestBus.subscribeToEvents("T", async (_, _, _) => JsError.throwWithMessage("boom"))
|
|
122
|
+
TestBus.subscribeToEvents(
|
|
123
|
+
"T",
|
|
124
|
+
async (_, _, _) => {
|
|
125
|
+
healthy := healthy.contents + 1
|
|
126
|
+
},
|
|
127
|
+
)
|
|
128
|
+
// Must resolve — not hang — even though one subscriber threw.
|
|
129
|
+
await TestBus.publishEvent("T", "svc", defaultMeta, JSON.Null)
|
|
130
|
+
expect(healthy.contents)->toBe(1)
|
|
131
|
+
},
|
|
132
|
+
)
|
|
97
133
|
|
|
98
|
-
testPromise(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
134
|
+
testPromise(
|
|
135
|
+
"the topic keeps working after a subscriber throws (drain fiber survives)",
|
|
136
|
+
async () => {
|
|
137
|
+
module TestBus = LocalBus.Make()
|
|
138
|
+
let healthy = ref(0)
|
|
139
|
+
TestBus.subscribeToEvents("T", async (_, _, _) => JsError.throwWithMessage("boom"))
|
|
140
|
+
TestBus.subscribeToEvents(
|
|
141
|
+
"T",
|
|
142
|
+
async (_, _, _) => {
|
|
143
|
+
healthy := healthy.contents + 1
|
|
144
|
+
},
|
|
145
|
+
)
|
|
146
|
+
await TestBus.publishEvent("T", "svc", defaultMeta, JSON.Null)
|
|
147
|
+
// Second publish on the same topic must also complete and be delivered —
|
|
148
|
+
// proving the dead-fiber cascade is gone.
|
|
149
|
+
await TestBus.publishEvent("T", "svc", defaultMeta, JSON.Null)
|
|
150
|
+
expect(healthy.contents)->toBe(2)
|
|
151
|
+
},
|
|
152
|
+
)
|
|
111
153
|
})
|
|
112
154
|
})
|
|
@@ -16,8 +16,7 @@ let _ = TestRunner.setup()
|
|
|
16
16
|
|
|
17
17
|
// Hand the provided context back as the handler's result — the assertions then
|
|
18
18
|
// see exactly what an application handler would.
|
|
19
|
-
let capture = (_event, _ctx) =>
|
|
20
|
-
Effect.serviceWith(ReventlessCore.RequestContext.tag, ctx => ctx)
|
|
19
|
+
let capture = (_event, _ctx) => Effect.serviceWith(ReventlessCore.RequestContext.tag, ctx => ctx)
|
|
21
20
|
|
|
22
21
|
let comp = "EventCollector(TestCollector)"
|
|
23
22
|
|