@reventlessdev/reventless-core 3.0.0-alpha.170 → 3.0.0-alpha.171
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 +7 -0
- package/package.json +14 -14
- package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +5 -2
- package/src/components/ExtensionPoint/ExtensionPoint_Builder.res.mjs +3 -3
- package/src/components/Task/Task_Builder.res +6 -4
- package/src/components/Task/Task_Builder.res.mjs +4 -4
- package/src/plugin/connect/PluginExtensionPoint_Builder.res +2 -0
- package/src/plugin/connect/PluginExtensionPoint_Builder.res.mjs +3 -3
- package/tests/IdentityTest.res.mjs +0 -174
- package/tests/adapter/MonitoringTest.res.mjs +0 -82
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +0 -356
- package/tests/admin/Platform_UIFragmentsApiTest.res.mjs +0 -101
- package/tests/aggregate/AggregateCacheTest.res.mjs +0 -433
- package/tests/aggregate/AggregateCallbackTest.res.mjs +0 -143
- package/tests/aggregate/AggregateCausationTest.res.mjs +0 -47
- package/tests/aggregate/AggregateConflictTest.res.mjs +0 -386
- package/tests/aggregate/AggregateFixtures.res.mjs +0 -308
- package/tests/aggregate/AggregateRejectionTest.res.mjs +0 -166
- package/tests/aggregate/AggregateSnapshotTest.res.mjs +0 -645
- package/tests/api/ApiNoApiTest.res.mjs +0 -90
- package/tests/api/GraphQL_StitcherTest.res.mjs +0 -112
- package/tests/api/SimpleTest.res.mjs +0 -10
- package/tests/api/SuryToJsonSchemaTest.res.mjs +0 -674
- package/tests/commandgenerator/CommandGeneratorCallbackTest.res.mjs +0 -160
- package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +0 -197
- package/tests/commandtopic/CommandTopicCallbackFixtures.res.mjs +0 -152
- package/tests/commandtopic/CommandTopicCallbackTest.res.mjs +0 -106
- package/tests/commandtopic/CommandTopicHelpersRejectionTest.res.mjs +0 -109
- package/tests/counter/CounterCallbackTest.res.mjs +0 -140
- package/tests/counter/CounterFixtures.res.mjs +0 -67
- package/tests/dcb/DcbDecodeTest.res.mjs +0 -194
- package/tests/dcb/DcbEventLogOperationsTest.res.mjs +0 -268
- package/tests/dcb/DcbFixtures.res.mjs +0 -534
- package/tests/dcb/DcbScopeInferenceTest.res.mjs +0 -480
- package/tests/dcb/DcbStateChangeSliceTest.res.mjs +0 -540
- package/tests/dcb/DcbTagTest.res.mjs +0 -867
- package/tests/dcb/DcbValidationTest.res.mjs +0 -476
- package/tests/eventlog/EventLogFixtures.res.mjs +0 -196
- package/tests/eventlog/EventLogOperationsTest.res.mjs +0 -192
- package/tests/eventlog/EventLogRetryTest.res.mjs +0 -195
- package/tests/eventmapper/EventMapperCallbackTest.res.mjs +0 -141
- package/tests/eventmapper/EventMapperFixtures.res.mjs +0 -440
- package/tests/eventmapper/EventMapperTest.res.mjs +0 -83
- package/tests/eventtopic/EventTopicFixtures.res.mjs +0 -65
- package/tests/eventtopic/EventTopicOperationsTest.res.mjs +0 -71
- package/tests/extensionpoint/ExtensionPointCallbackTest.res.mjs +0 -94
- package/tests/extensionpoint/ExtensionPointFixtures.res.mjs +0 -205
- package/tests/extensionpoint/ExtensionPointOperationsTest.res.mjs +0 -304
- package/tests/ftp/FTPTest.res.mjs +0 -88
- package/tests/logger/LogFormatTest.res.mjs +0 -309
- package/tests/logger/LoggerLazyTest.res.mjs +0 -40
- package/tests/message/MessageTest.res.mjs +0 -218
- package/tests/message/MetaEnvelopeTest.res.mjs +0 -188
- package/tests/plugin/ManifestVisibilityTest.res.mjs +0 -215
- package/tests/plugin/PluginSpecExperiment.res.mjs +0 -31
- package/tests/plugin/PluginStructureTest.res.mjs +0 -419
- package/tests/plugin/PluginVersionTest.res.mjs +0 -30
- package/tests/plugin/SchemaWalkerTest.res.mjs +0 -160
- package/tests/plugin/StateChangeSlice/PsPlaceOrder.res.mjs +0 -62
- package/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs +0 -69
- package/tests/plugin/StateViewSlice/PsAnnotatedView.res.mjs +0 -95
- package/tests/plugin/StateViewSlice/PsAvailableProductsView.res.mjs +0 -69
- package/tests/plugin/StateViewSlice/PsCustomersView.res.mjs +0 -69
- package/tests/plugin/StateViewSlice/PsOrdersView.res.mjs +0 -81
- package/tests/poc/StructuralSubtypingPoc.res.mjs +0 -61
- package/tests/projection/ProjectionOptimizeTest.res.mjs +0 -75
- package/tests/querydb/QueryDbFixtures.res.mjs +0 -135
- package/tests/querydb/QueryDbOperationsTest.res.mjs +0 -168
- package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res.mjs +0 -77
- package/tests/sideeffecthandler/SideEffectHandlerFixtures.res.mjs +0 -139
- package/tests/util/CommandPublisherTest.res.mjs +0 -78
- package/tests/util/CsvStreamTest.res.mjs +0 -51
- package/tests/util/LruTest.res.mjs +0 -105
- package/tests/util/MetricsTest.res.mjs +0 -53
|
@@ -1,540 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
4
|
-
import * as Effect from "effect/Effect";
|
|
5
|
-
import * as Stream from "effect/Stream";
|
|
6
|
-
import * as DcbFixtures$ReventlessCore from "./DcbFixtures.res.mjs";
|
|
7
|
-
import * as DcbEventLog_Operations$ReventlessCore from "../../src/components/DcbEventLog/DcbEventLog_Operations.res.mjs";
|
|
8
|
-
import * as StateChangeSlice_Callback$ReventlessCore from "../../src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs";
|
|
9
|
-
|
|
10
|
-
let mock = DcbFixtures$ReventlessCore.makeMockStorage();
|
|
11
|
-
|
|
12
|
-
let storage = mock.operations;
|
|
13
|
-
|
|
14
|
-
let publishJson = mock.mockPublishJson;
|
|
15
|
-
|
|
16
|
-
let TestDcbOps = {
|
|
17
|
-
name: "TestDcbEventLog",
|
|
18
|
-
serviceName: "TestDcbEventLog",
|
|
19
|
-
storage: storage,
|
|
20
|
-
publishJson: publishJson
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
let EventLogOps = DcbEventLog_Operations$ReventlessCore.Make(TestDcbOps);
|
|
24
|
-
|
|
25
|
-
let testDcbEventLog_read = EventLogOps.read;
|
|
26
|
-
|
|
27
|
-
let testDcbEventLog_append = EventLogOps.append;
|
|
28
|
-
|
|
29
|
-
let testDcbEventLog_readStream = EventLogOps.readStream;
|
|
30
|
-
|
|
31
|
-
let testDcbEventLog_appendStream = EventLogOps.appendStream;
|
|
32
|
-
|
|
33
|
-
let testDcbEventLog = {
|
|
34
|
-
read: testDcbEventLog_read,
|
|
35
|
-
append: testDcbEventLog_append,
|
|
36
|
-
readStream: testDcbEventLog_readStream,
|
|
37
|
-
appendStream: testDcbEventLog_appendStream
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
let initialState = DcbFixtures$ReventlessCore.TestCommandSpec.initialState;
|
|
41
|
-
|
|
42
|
-
let evolve = DcbFixtures$ReventlessCore.TestCommandSpec.evolve;
|
|
43
|
-
|
|
44
|
-
let decide = DcbFixtures$ReventlessCore.TestCommandSpec.decide;
|
|
45
|
-
|
|
46
|
-
let moduleUrl = DcbFixtures$ReventlessCore.TestCommandSpec.moduleUrl;
|
|
47
|
-
|
|
48
|
-
let TestCommandBehavior = {
|
|
49
|
-
initialState: initialState,
|
|
50
|
-
evolve: evolve,
|
|
51
|
-
decide: decide,
|
|
52
|
-
moduleUrl: moduleUrl
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
let TestHandler = StateChangeSlice_Callback$ReventlessCore.Make({
|
|
56
|
-
name: DcbFixtures$ReventlessCore.TestCommandSpec.name,
|
|
57
|
-
moduleUrl: DcbFixtures$ReventlessCore.TestCommandSpec.moduleUrl,
|
|
58
|
-
Id: Id$Reventless.$$String,
|
|
59
|
-
consumedEventSchema: DcbFixtures$ReventlessCore.TestCommandSpec.consumedEventSchema,
|
|
60
|
-
errorSchema: DcbFixtures$ReventlessCore.TestCommandSpec.errorSchema,
|
|
61
|
-
eventSchema: DcbFixtures$ReventlessCore.TestCommandSpec.eventSchema,
|
|
62
|
-
commandSchema: DcbFixtures$ReventlessCore.TestCommandSpec.commandSchema,
|
|
63
|
-
commandAuthorization: DcbFixtures$ReventlessCore.TestCommandSpec.commandAuthorization,
|
|
64
|
-
readConsistency: DcbFixtures$ReventlessCore.TestCommandSpec.readConsistency
|
|
65
|
-
})(TestCommandBehavior);
|
|
66
|
-
|
|
67
|
-
let name = DcbFixtures$ReventlessCore.TestCommandSpec.name;
|
|
68
|
-
|
|
69
|
-
let moduleUrl$1 = DcbFixtures$ReventlessCore.TestCommandSpec.moduleUrl;
|
|
70
|
-
|
|
71
|
-
let eventSchema = DcbFixtures$ReventlessCore.TestCommandSpec.eventSchema;
|
|
72
|
-
|
|
73
|
-
let consumedEventSchema = DcbFixtures$ReventlessCore.TestCommandSpec.consumedEventSchema;
|
|
74
|
-
|
|
75
|
-
let commandSchema = DcbFixtures$ReventlessCore.TestCommandSpec.commandSchema;
|
|
76
|
-
|
|
77
|
-
let errorSchema = DcbFixtures$ReventlessCore.TestCommandSpec.errorSchema;
|
|
78
|
-
|
|
79
|
-
let commandAuthorization = DcbFixtures$ReventlessCore.TestCommandSpec.commandAuthorization;
|
|
80
|
-
|
|
81
|
-
let StrongSpec_Id = DcbFixtures$ReventlessCore.TestCommandSpec.Id;
|
|
82
|
-
|
|
83
|
-
let StrongSpec_initialState = DcbFixtures$ReventlessCore.TestCommandSpec.initialState;
|
|
84
|
-
|
|
85
|
-
let StrongSpec_evolve = DcbFixtures$ReventlessCore.TestCommandSpec.evolve;
|
|
86
|
-
|
|
87
|
-
let StrongSpec_decide = DcbFixtures$ReventlessCore.TestCommandSpec.decide;
|
|
88
|
-
|
|
89
|
-
let StrongSpec = {
|
|
90
|
-
name: name,
|
|
91
|
-
Id: StrongSpec_Id,
|
|
92
|
-
moduleUrl: moduleUrl$1,
|
|
93
|
-
eventSchema: eventSchema,
|
|
94
|
-
consumedEventSchema: consumedEventSchema,
|
|
95
|
-
commandSchema: commandSchema,
|
|
96
|
-
errorSchema: errorSchema,
|
|
97
|
-
initialState: StrongSpec_initialState,
|
|
98
|
-
evolve: StrongSpec_evolve,
|
|
99
|
-
decide: StrongSpec_decide,
|
|
100
|
-
commandAuthorization: commandAuthorization,
|
|
101
|
-
readConsistency: "AlwaysStrong"
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
let name$1 = DcbFixtures$ReventlessCore.TestCommandSpec.name;
|
|
105
|
-
|
|
106
|
-
let moduleUrl$2 = DcbFixtures$ReventlessCore.TestCommandSpec.moduleUrl;
|
|
107
|
-
|
|
108
|
-
let eventSchema$1 = DcbFixtures$ReventlessCore.TestCommandSpec.eventSchema;
|
|
109
|
-
|
|
110
|
-
let consumedEventSchema$1 = DcbFixtures$ReventlessCore.TestCommandSpec.consumedEventSchema;
|
|
111
|
-
|
|
112
|
-
let commandSchema$1 = DcbFixtures$ReventlessCore.TestCommandSpec.commandSchema;
|
|
113
|
-
|
|
114
|
-
let errorSchema$1 = DcbFixtures$ReventlessCore.TestCommandSpec.errorSchema;
|
|
115
|
-
|
|
116
|
-
let commandAuthorization$1 = DcbFixtures$ReventlessCore.TestCommandSpec.commandAuthorization;
|
|
117
|
-
|
|
118
|
-
let EventualSpec_Id = DcbFixtures$ReventlessCore.TestCommandSpec.Id;
|
|
119
|
-
|
|
120
|
-
let EventualSpec_initialState = DcbFixtures$ReventlessCore.TestCommandSpec.initialState;
|
|
121
|
-
|
|
122
|
-
let EventualSpec_evolve = DcbFixtures$ReventlessCore.TestCommandSpec.evolve;
|
|
123
|
-
|
|
124
|
-
let EventualSpec_decide = DcbFixtures$ReventlessCore.TestCommandSpec.decide;
|
|
125
|
-
|
|
126
|
-
let EventualSpec = {
|
|
127
|
-
name: name$1,
|
|
128
|
-
Id: EventualSpec_Id,
|
|
129
|
-
moduleUrl: moduleUrl$2,
|
|
130
|
-
eventSchema: eventSchema$1,
|
|
131
|
-
consumedEventSchema: consumedEventSchema$1,
|
|
132
|
-
commandSchema: commandSchema$1,
|
|
133
|
-
errorSchema: errorSchema$1,
|
|
134
|
-
initialState: EventualSpec_initialState,
|
|
135
|
-
evolve: EventualSpec_evolve,
|
|
136
|
-
decide: EventualSpec_decide,
|
|
137
|
-
commandAuthorization: commandAuthorization$1,
|
|
138
|
-
readConsistency: "AlwaysEventual"
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
let StrongHandler = StateChangeSlice_Callback$ReventlessCore.Make({
|
|
142
|
-
name: name,
|
|
143
|
-
moduleUrl: moduleUrl$1,
|
|
144
|
-
Id: Id$Reventless.$$String,
|
|
145
|
-
consumedEventSchema: consumedEventSchema,
|
|
146
|
-
errorSchema: errorSchema,
|
|
147
|
-
eventSchema: eventSchema,
|
|
148
|
-
commandSchema: commandSchema,
|
|
149
|
-
commandAuthorization: commandAuthorization,
|
|
150
|
-
readConsistency: "AlwaysStrong"
|
|
151
|
-
})(TestCommandBehavior);
|
|
152
|
-
|
|
153
|
-
let EventualHandler = StateChangeSlice_Callback$ReventlessCore.Make({
|
|
154
|
-
name: name$1,
|
|
155
|
-
moduleUrl: moduleUrl$2,
|
|
156
|
-
Id: Id$Reventless.$$String,
|
|
157
|
-
consumedEventSchema: consumedEventSchema$1,
|
|
158
|
-
errorSchema: errorSchema$1,
|
|
159
|
-
eventSchema: eventSchema$1,
|
|
160
|
-
commandSchema: commandSchema$1,
|
|
161
|
-
commandAuthorization: commandAuthorization$1,
|
|
162
|
-
readConsistency: "AlwaysEventual"
|
|
163
|
-
})(TestCommandBehavior);
|
|
164
|
-
|
|
165
|
-
function makeTopicItem(reference, command) {
|
|
166
|
-
return {
|
|
167
|
-
command: {
|
|
168
|
-
id: Id$Reventless.$$String.makeFromString("cmd-" + reference),
|
|
169
|
-
meta: DcbFixtures$ReventlessCore.testMeta,
|
|
170
|
-
command: command
|
|
171
|
-
},
|
|
172
|
-
reference: reference
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
globalThis.beforeEach(() => {
|
|
177
|
-
mock.reset();
|
|
178
|
-
TestHandler.resetCache();
|
|
179
|
-
StrongHandler.resetCache();
|
|
180
|
-
EventualHandler.resetCache();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
globalThis.describe("StateChangeSlice_Callback:", () => {
|
|
184
|
-
globalThis.describe("handleCommands - happy path", () => {
|
|
185
|
-
globalThis.test("CreateItem on empty log succeeds", async () => {
|
|
186
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
187
|
-
TAG: "CreateItem",
|
|
188
|
-
itemId: "item-1",
|
|
189
|
-
name: "Test"
|
|
190
|
-
})])));
|
|
191
|
-
globalThis.expect([
|
|
192
|
-
results,
|
|
193
|
-
mock.getEvents().length,
|
|
194
|
-
mock.publishedEvents.contents.length
|
|
195
|
-
]).toEqual([
|
|
196
|
-
[{
|
|
197
|
-
TAG: "Ok",
|
|
198
|
-
_0: "ref-1"
|
|
199
|
-
}],
|
|
200
|
-
1,
|
|
201
|
-
1
|
|
202
|
-
]);
|
|
203
|
-
});
|
|
204
|
-
globalThis.test("stored event carries only its entity tags (no framework provenance tag)", async () => {
|
|
205
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
206
|
-
TAG: "CreateItem",
|
|
207
|
-
itemId: "item-1",
|
|
208
|
-
name: "Test"
|
|
209
|
-
})])));
|
|
210
|
-
let storedEvent = mock.getEvents()[0];
|
|
211
|
-
globalThis.expect(storedEvent.tags).toEqual([{
|
|
212
|
-
key: "itemId",
|
|
213
|
-
value: "item-1"
|
|
214
|
-
}]);
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
globalThis.describe("handleCommands - decide returns Ok([])", () => {
|
|
218
|
-
globalThis.test("NoOp returns Ok without storing events", async () => {
|
|
219
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-noop", "NoOp")])));
|
|
220
|
-
globalThis.expect([
|
|
221
|
-
results,
|
|
222
|
-
mock.getEvents().length
|
|
223
|
-
]).toEqual([
|
|
224
|
-
[{
|
|
225
|
-
TAG: "Ok",
|
|
226
|
-
_0: "ref-noop"
|
|
227
|
-
}],
|
|
228
|
-
0
|
|
229
|
-
]);
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
globalThis.describe("handleCommands - decide returns Error", () => {
|
|
233
|
-
globalThis.test("CreateItem when item exists returns Ok (business-rule violations ACK, not NACK)", async () => {
|
|
234
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
235
|
-
TAG: "CreateItem",
|
|
236
|
-
itemId: "item-1",
|
|
237
|
-
name: "Test"
|
|
238
|
-
})])));
|
|
239
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-2", {
|
|
240
|
-
TAG: "CreateItem",
|
|
241
|
-
itemId: "item-1",
|
|
242
|
-
name: "Duplicate"
|
|
243
|
-
})])));
|
|
244
|
-
globalThis.expect(results).toEqual([{
|
|
245
|
-
TAG: "Ok",
|
|
246
|
-
_0: "ref-2"
|
|
247
|
-
}]);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
globalThis.describe("handleCommands - retry on conflict", () => {
|
|
251
|
-
globalThis.test("retries and succeeds after 1 append failure", async () => {
|
|
252
|
-
mock.failNextAppends.contents = 1;
|
|
253
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
254
|
-
TAG: "CreateItem",
|
|
255
|
-
itemId: "item-1",
|
|
256
|
-
name: "Test"
|
|
257
|
-
})])));
|
|
258
|
-
globalThis.expect([
|
|
259
|
-
results,
|
|
260
|
-
mock.getEvents().length
|
|
261
|
-
]).toEqual([
|
|
262
|
-
[{
|
|
263
|
-
TAG: "Ok",
|
|
264
|
-
_0: "ref-1"
|
|
265
|
-
}],
|
|
266
|
-
1
|
|
267
|
-
]);
|
|
268
|
-
});
|
|
269
|
-
globalThis.test("returns Error after retries exhausted (4 failures)", async () => {
|
|
270
|
-
mock.failNextAppends.contents = 4;
|
|
271
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
272
|
-
TAG: "CreateItem",
|
|
273
|
-
itemId: "item-1",
|
|
274
|
-
name: "Test"
|
|
275
|
-
})])));
|
|
276
|
-
globalThis.expect([
|
|
277
|
-
results,
|
|
278
|
-
mock.getEvents().length
|
|
279
|
-
]).toEqual([
|
|
280
|
-
[{
|
|
281
|
-
TAG: "Error",
|
|
282
|
-
_0: "ref-1"
|
|
283
|
-
}],
|
|
284
|
-
0
|
|
285
|
-
]);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
globalThis.describe("handleCommands - read consistency (eventual-first, strong-on-retry)", () => {
|
|
289
|
-
globalThis.test("a conflict-free command reads eventually-consistent (no strong read)", async () => {
|
|
290
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
291
|
-
TAG: "CreateItem",
|
|
292
|
-
itemId: "item-1",
|
|
293
|
-
name: "Test"
|
|
294
|
-
})])));
|
|
295
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([false]);
|
|
296
|
-
});
|
|
297
|
-
globalThis.test("escalates to strong consistency on retry after a conflict", async () => {
|
|
298
|
-
mock.failNextAppends.contents = 1;
|
|
299
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
300
|
-
TAG: "CreateItem",
|
|
301
|
-
itemId: "item-1",
|
|
302
|
-
name: "Test"
|
|
303
|
-
})])));
|
|
304
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([
|
|
305
|
-
false,
|
|
306
|
-
true
|
|
307
|
-
]);
|
|
308
|
-
});
|
|
309
|
-
globalThis.test("every retry after the first is strong (2 failures)", async () => {
|
|
310
|
-
mock.failNextAppends.contents = 2;
|
|
311
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
312
|
-
TAG: "CreateItem",
|
|
313
|
-
itemId: "item-1",
|
|
314
|
-
name: "Test"
|
|
315
|
-
})])));
|
|
316
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([
|
|
317
|
-
false,
|
|
318
|
-
true,
|
|
319
|
-
true
|
|
320
|
-
]);
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
-
globalThis.describe("handleCommands - read consistency (per-slice override)", () => {
|
|
324
|
-
globalThis.test("AlwaysStrong reads strong on the first attempt", async () => {
|
|
325
|
-
await Effect.runPromise(StrongHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
326
|
-
TAG: "CreateItem",
|
|
327
|
-
itemId: "item-1",
|
|
328
|
-
name: "Test"
|
|
329
|
-
})])));
|
|
330
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([true]);
|
|
331
|
-
});
|
|
332
|
-
globalThis.test("AlwaysStrong stays strong across retries (2 failures)", async () => {
|
|
333
|
-
mock.failNextAppends.contents = 2;
|
|
334
|
-
await Effect.runPromise(StrongHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
335
|
-
TAG: "CreateItem",
|
|
336
|
-
itemId: "item-1",
|
|
337
|
-
name: "Test"
|
|
338
|
-
})])));
|
|
339
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([
|
|
340
|
-
true,
|
|
341
|
-
true,
|
|
342
|
-
true
|
|
343
|
-
]);
|
|
344
|
-
});
|
|
345
|
-
globalThis.test("AlwaysEventual never reads strong, even on retry (2 failures)", async () => {
|
|
346
|
-
mock.failNextAppends.contents = 2;
|
|
347
|
-
await Effect.runPromise(EventualHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
348
|
-
TAG: "CreateItem",
|
|
349
|
-
itemId: "item-1",
|
|
350
|
-
name: "Test"
|
|
351
|
-
})])));
|
|
352
|
-
globalThis.expect(mock.readStrongConsistency.contents).toEqual([
|
|
353
|
-
false,
|
|
354
|
-
false,
|
|
355
|
-
false
|
|
356
|
-
]);
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
globalThis.describe("handleCommands - conditional append", () => {
|
|
360
|
-
globalThis.test("RenameItem after CreateItem uses headPosition in condition", async () => {
|
|
361
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-1", {
|
|
362
|
-
TAG: "CreateItem",
|
|
363
|
-
itemId: "item-1",
|
|
364
|
-
name: "Test"
|
|
365
|
-
})])));
|
|
366
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-2", {
|
|
367
|
-
TAG: "RenameItem",
|
|
368
|
-
itemId: "item-1",
|
|
369
|
-
newName: "Updated"
|
|
370
|
-
})])));
|
|
371
|
-
globalThis.expect([
|
|
372
|
-
results,
|
|
373
|
-
mock.getEvents().length
|
|
374
|
-
]).toEqual([
|
|
375
|
-
[{
|
|
376
|
-
TAG: "Ok",
|
|
377
|
-
_0: "ref-2"
|
|
378
|
-
}],
|
|
379
|
-
2
|
|
380
|
-
]);
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
globalThis.describe("handleCommands - batch", () => {
|
|
384
|
-
globalThis.test("multiple successful commands", async () => {
|
|
385
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([
|
|
386
|
-
makeTopicItem("ref-1", {
|
|
387
|
-
TAG: "CreateItem",
|
|
388
|
-
itemId: "item-1",
|
|
389
|
-
name: "First"
|
|
390
|
-
}),
|
|
391
|
-
makeTopicItem("ref-2", {
|
|
392
|
-
TAG: "CreateItem",
|
|
393
|
-
itemId: "item-2",
|
|
394
|
-
name: "Second"
|
|
395
|
-
})
|
|
396
|
-
])));
|
|
397
|
-
globalThis.expect(results).toEqual([
|
|
398
|
-
{
|
|
399
|
-
TAG: "Ok",
|
|
400
|
-
_0: "ref-1"
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
TAG: "Ok",
|
|
404
|
-
_0: "ref-2"
|
|
405
|
-
}
|
|
406
|
-
]);
|
|
407
|
-
});
|
|
408
|
-
globalThis.test("mixed: new item succeeds, duplicate item ACKs as Ok (business-rule violation)", async () => {
|
|
409
|
-
await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem("ref-0", {
|
|
410
|
-
TAG: "CreateItem",
|
|
411
|
-
itemId: "item-1",
|
|
412
|
-
name: "Existing"
|
|
413
|
-
})])));
|
|
414
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([
|
|
415
|
-
makeTopicItem("ref-1", {
|
|
416
|
-
TAG: "CreateItem",
|
|
417
|
-
itemId: "item-2",
|
|
418
|
-
name: "New"
|
|
419
|
-
}),
|
|
420
|
-
makeTopicItem("ref-2", {
|
|
421
|
-
TAG: "CreateItem",
|
|
422
|
-
itemId: "item-1",
|
|
423
|
-
name: "Duplicate"
|
|
424
|
-
})
|
|
425
|
-
])));
|
|
426
|
-
globalThis.expect(results).toEqual([
|
|
427
|
-
{
|
|
428
|
-
TAG: "Ok",
|
|
429
|
-
_0: "ref-1"
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
TAG: "Ok",
|
|
433
|
-
_0: "ref-2"
|
|
434
|
-
}
|
|
435
|
-
]);
|
|
436
|
-
});
|
|
437
|
-
globalThis.test("empty batch returns empty array", async () => {
|
|
438
|
-
let results = await Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([])));
|
|
439
|
-
globalThis.expect(results).toEqual([]);
|
|
440
|
-
});
|
|
441
|
-
});
|
|
442
|
-
globalThis.describe("handleCommands - projection cache", () => {
|
|
443
|
-
globalThis.test("a third same-entity command reads only the delta", async () => {
|
|
444
|
-
let run = (reference, command) => Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem(reference, command)])));
|
|
445
|
-
await run("ref-1", {
|
|
446
|
-
TAG: "CreateItem",
|
|
447
|
-
itemId: "item-1",
|
|
448
|
-
name: "A"
|
|
449
|
-
});
|
|
450
|
-
await run("ref-2", {
|
|
451
|
-
TAG: "RenameItem",
|
|
452
|
-
itemId: "item-1",
|
|
453
|
-
newName: "B"
|
|
454
|
-
});
|
|
455
|
-
let r3 = await run("ref-3", {
|
|
456
|
-
TAG: "RenameItem",
|
|
457
|
-
itemId: "item-1",
|
|
458
|
-
newName: "C"
|
|
459
|
-
});
|
|
460
|
-
globalThis.expect([
|
|
461
|
-
r3,
|
|
462
|
-
mock.readAfters.contents,
|
|
463
|
-
mock.getEvents().length
|
|
464
|
-
]).toEqual([
|
|
465
|
-
[{
|
|
466
|
-
TAG: "Ok",
|
|
467
|
-
_0: "ref-3"
|
|
468
|
-
}],
|
|
469
|
-
[
|
|
470
|
-
undefined,
|
|
471
|
-
undefined,
|
|
472
|
-
"1"
|
|
473
|
-
],
|
|
474
|
-
3
|
|
475
|
-
]);
|
|
476
|
-
});
|
|
477
|
-
globalThis.test("a different entity does not hit another entity's cache (full read)", async () => {
|
|
478
|
-
let run = (reference, command) => Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem(reference, command)])));
|
|
479
|
-
await run("ref-1", {
|
|
480
|
-
TAG: "CreateItem",
|
|
481
|
-
itemId: "item-1",
|
|
482
|
-
name: "A"
|
|
483
|
-
});
|
|
484
|
-
await run("ref-2", {
|
|
485
|
-
TAG: "CreateItem",
|
|
486
|
-
itemId: "item-2",
|
|
487
|
-
name: "B"
|
|
488
|
-
});
|
|
489
|
-
globalThis.expect(mock.readAfters.contents).toEqual([
|
|
490
|
-
undefined,
|
|
491
|
-
undefined
|
|
492
|
-
]);
|
|
493
|
-
});
|
|
494
|
-
globalThis.test("conflict re-seeds the cache so the retry reads the delta", async () => {
|
|
495
|
-
let run = (reference, command) => Effect.runPromise(TestHandler.handleCommands(undefined, undefined, testDcbEventLog, Stream.fromIterable([makeTopicItem(reference, command)])));
|
|
496
|
-
await run("ref-1", {
|
|
497
|
-
TAG: "CreateItem",
|
|
498
|
-
itemId: "item-1",
|
|
499
|
-
name: "A"
|
|
500
|
-
});
|
|
501
|
-
mock.failNextAppends.contents = 1;
|
|
502
|
-
let r2 = await run("ref-2", {
|
|
503
|
-
TAG: "RenameItem",
|
|
504
|
-
itemId: "item-1",
|
|
505
|
-
newName: "B"
|
|
506
|
-
});
|
|
507
|
-
globalThis.expect([
|
|
508
|
-
r2,
|
|
509
|
-
mock.readAfters.contents,
|
|
510
|
-
mock.getEvents().length
|
|
511
|
-
]).toEqual([
|
|
512
|
-
[{
|
|
513
|
-
TAG: "Ok",
|
|
514
|
-
_0: "ref-2"
|
|
515
|
-
}],
|
|
516
|
-
[
|
|
517
|
-
undefined,
|
|
518
|
-
undefined,
|
|
519
|
-
"1"
|
|
520
|
-
],
|
|
521
|
-
2
|
|
522
|
-
]);
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
export {
|
|
528
|
-
mock,
|
|
529
|
-
TestDcbOps,
|
|
530
|
-
EventLogOps,
|
|
531
|
-
testDcbEventLog,
|
|
532
|
-
TestCommandBehavior,
|
|
533
|
-
TestHandler,
|
|
534
|
-
StrongSpec,
|
|
535
|
-
EventualSpec,
|
|
536
|
-
StrongHandler,
|
|
537
|
-
EventualHandler,
|
|
538
|
-
makeTopicItem,
|
|
539
|
-
}
|
|
540
|
-
/* mock Not a pure module */
|