@reventlessdev/reventless-core 3.0.0-alpha.170 → 3.0.0-alpha.172
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 +14 -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/Heartbeat/Heartbeat.res +2 -2
- package/src/components/Heartbeat/Heartbeat_Builder.res +2 -2
- package/src/components/Heartbeat/Heartbeat_Builder.res.mjs +2 -4
- package/src/components/Task/Task_Builder.res +6 -4
- package/src/components/Task/Task_Builder.res.mjs +4 -4
- package/src/plugin/component/Plugin_Builder.res +5 -1
- package/src/plugin/component/Plugin_Builder.res.mjs +1 -1
- package/src/plugin/component/Plugin_Helpers.res +6 -1
- package/src/plugin/connect/PluginExtensionPoint_Builder.res +2 -0
- package/src/plugin/connect/PluginExtensionPoint_Builder.res.mjs +3 -3
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res +12 -5
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +8 -2
- package/tests/plugin/HeartbeatDisconnectGraceTest.res +98 -0
- 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,101 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
4
|
-
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
-
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
6
|
-
import * as Platform_UIFragmentsApi$ReventlessCore from "../../src/admin/Platform_UIFragmentsApi.res.mjs";
|
|
7
|
-
|
|
8
|
-
let panel_positions = ["platform-summary"];
|
|
9
|
-
|
|
10
|
-
let panel = {
|
|
11
|
-
fragmentId: "Catalog.Categories.list",
|
|
12
|
-
title: "Categories",
|
|
13
|
-
description: "",
|
|
14
|
-
positions: panel_positions,
|
|
15
|
-
requiredAccess: undefined
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
let page = {
|
|
19
|
-
fragmentId: "Catalog.Categories.list",
|
|
20
|
-
title: "Categories",
|
|
21
|
-
menuEntry: {
|
|
22
|
-
label: "Categories",
|
|
23
|
-
icon: undefined,
|
|
24
|
-
group: undefined,
|
|
25
|
-
sortOrder: 0
|
|
26
|
-
},
|
|
27
|
-
requiredAccess: "admin"
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
let state_panels = [panel];
|
|
31
|
-
|
|
32
|
-
let state_pages = [page];
|
|
33
|
-
|
|
34
|
-
let state = {
|
|
35
|
-
pluginId: "Catalog",
|
|
36
|
-
remoteEntryUrl: "https://cdn.example.com/catalog@1.0/remoteEntry.js",
|
|
37
|
-
panels: state_panels,
|
|
38
|
-
pages: state_pages,
|
|
39
|
-
registeredAt: "2026-05-14T00:00:00.000Z",
|
|
40
|
-
updatedAt: "2026-05-14T00:00:00.000Z"
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
let encoded = Platform_UIFragmentsApi$ReventlessCore.encodeUIFragmentEntry(state);
|
|
44
|
-
|
|
45
|
-
let json = JSON.stringify(encoded);
|
|
46
|
-
|
|
47
|
-
globalThis.describe("encodeUIFragmentEntry", () => {
|
|
48
|
-
globalThis.test("produces a JSON object with the expected top-level keys", () => {
|
|
49
|
-
let dict = Stdlib_Option.getOr(Stdlib_JSON.Decode.object(encoded), {});
|
|
50
|
-
let keys = Object.keys(dict).toSorted(Primitive_string.compare);
|
|
51
|
-
globalThis.expect(keys).toEqual([
|
|
52
|
-
"pages",
|
|
53
|
-
"panels",
|
|
54
|
-
"pluginId",
|
|
55
|
-
"registeredAt",
|
|
56
|
-
"remoteEntryUrl",
|
|
57
|
-
"updatedAt"
|
|
58
|
-
]);
|
|
59
|
-
});
|
|
60
|
-
globalThis.test("encodes pluginId", () => {
|
|
61
|
-
globalThis.expect(json.includes("\"pluginId\":\"Catalog\"")).toEqual(true);
|
|
62
|
-
});
|
|
63
|
-
globalThis.test("encodes remoteEntryUrl", () => {
|
|
64
|
-
globalThis.expect(json.includes("\"remoteEntryUrl\":\"https://cdn.example.com/catalog@1.0/remoteEntry.js\"")).toEqual(true);
|
|
65
|
-
});
|
|
66
|
-
globalThis.test("encodes None requiredAccess on panel as null", () => {
|
|
67
|
-
globalThis.expect(json.includes("\"requiredAccess\":null")).toEqual(true);
|
|
68
|
-
});
|
|
69
|
-
globalThis.test("encodes Some requiredAccess on page as its inner string", () => {
|
|
70
|
-
globalThis.expect(json.includes("\"requiredAccess\":\"admin\"")).toEqual(true);
|
|
71
|
-
});
|
|
72
|
-
globalThis.test("encodes nested menuEntry as an object with sortOrder", () => {
|
|
73
|
-
globalThis.expect(json.includes("\"sortOrder\":0")).toEqual(true);
|
|
74
|
-
});
|
|
75
|
-
globalThis.test("encodes panel positions as an array of strings", () => {
|
|
76
|
-
globalThis.expect(json.includes("\"positions\":[\"platform-summary\"]")).toEqual(true);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
globalThis.describe("Platform_UIFragmentsApi.sdl", () => {
|
|
81
|
-
globalThis.test("query field declares the list type", () => {
|
|
82
|
-
globalThis.expect(Platform_UIFragmentsApi$ReventlessCore.sdlQueryField.includes("[Platform_UIFragmentEntry!]!")).toEqual(true);
|
|
83
|
-
});
|
|
84
|
-
globalThis.test("sdlTypes includes Platform_UIFragmentEntry", () => {
|
|
85
|
-
let allTypes = Platform_UIFragmentsApi$ReventlessCore.sdlTypes.join("\n");
|
|
86
|
-
globalThis.expect(allTypes.includes("Platform_UIFragmentEntry")).toEqual(true);
|
|
87
|
-
});
|
|
88
|
-
globalThis.test("sdlTypes includes Platform_UIPanel with positions field", () => {
|
|
89
|
-
let allTypes = Platform_UIFragmentsApi$ReventlessCore.sdlTypes.join("\n");
|
|
90
|
-
globalThis.expect(allTypes.includes("positions: [String!]!")).toEqual(true);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
export {
|
|
95
|
-
panel,
|
|
96
|
-
page,
|
|
97
|
-
state,
|
|
98
|
-
encoded,
|
|
99
|
-
json,
|
|
100
|
-
}
|
|
101
|
-
/* encoded Not a pure module */
|
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as S from "sury/src/S.res.mjs";
|
|
4
|
-
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
5
|
-
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
6
|
-
import * as Effect from "effect/Effect";
|
|
7
|
-
import * as Stream from "effect/Stream";
|
|
8
|
-
import * as Aggregate_Callback$ReventlessCore from "../../src/components/Aggregate/Aggregate_Callback.res.mjs";
|
|
9
|
-
|
|
10
|
-
S.enableJson();
|
|
11
|
-
|
|
12
|
-
let name = "CacheTestAggregate";
|
|
13
|
-
|
|
14
|
-
let commandSchema = S.union([
|
|
15
|
-
S.schema(s => ({
|
|
16
|
-
TAG: "Add",
|
|
17
|
-
name: s.m(S.string)
|
|
18
|
-
})),
|
|
19
|
-
S.literal("Checkpoint"),
|
|
20
|
-
S.literal("Noop")
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
let eventSchema = S.union([
|
|
24
|
-
S.schema(s => ({
|
|
25
|
-
TAG: "Added",
|
|
26
|
-
name: s.m(S.string)
|
|
27
|
-
})),
|
|
28
|
-
S.schema(s => ({
|
|
29
|
-
TAG: "CheckpointTaken",
|
|
30
|
-
count: s.m(S.int)
|
|
31
|
-
}))
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
let errorSchema = S.literal("Never");
|
|
35
|
-
|
|
36
|
-
let moduleUrl = import.meta.url;
|
|
37
|
-
|
|
38
|
-
function commandAuthorization(param) {
|
|
39
|
-
return "AllowAuthenticated";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let AggSpec = {
|
|
43
|
-
Id: undefined,
|
|
44
|
-
name: name,
|
|
45
|
-
commandSchema: commandSchema,
|
|
46
|
-
eventSchema: eventSchema,
|
|
47
|
-
errorSchema: errorSchema,
|
|
48
|
-
moduleUrl: moduleUrl,
|
|
49
|
-
commandAuthorization: commandAuthorization
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
let initialState = {
|
|
53
|
-
names: []
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
let moduleUrl$1 = import.meta.url;
|
|
57
|
-
|
|
58
|
-
function evolve(state, event) {
|
|
59
|
-
if (event.TAG === "Added") {
|
|
60
|
-
return {
|
|
61
|
-
names: state.names.concat([event.name])
|
|
62
|
-
};
|
|
63
|
-
} else {
|
|
64
|
-
return state;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function decide(state, command) {
|
|
69
|
-
if (typeof command !== "object") {
|
|
70
|
-
if (command === "Checkpoint") {
|
|
71
|
-
return {
|
|
72
|
-
TAG: "Ok",
|
|
73
|
-
_0: [{
|
|
74
|
-
TAG: "CheckpointTaken",
|
|
75
|
-
count: state.names.length
|
|
76
|
-
}]
|
|
77
|
-
};
|
|
78
|
-
} else {
|
|
79
|
-
return {
|
|
80
|
-
TAG: "Ok",
|
|
81
|
-
_0: []
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
return {
|
|
86
|
-
TAG: "Ok",
|
|
87
|
-
_0: [{
|
|
88
|
-
TAG: "Added",
|
|
89
|
-
name: command.name
|
|
90
|
-
}]
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let TestBehavior = {
|
|
96
|
-
Spec: undefined,
|
|
97
|
-
initialState: initialState,
|
|
98
|
-
snapshot: undefined,
|
|
99
|
-
moduleUrl: moduleUrl$1,
|
|
100
|
-
evolve: evolve,
|
|
101
|
-
decide: decide
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
let testMeta = {
|
|
105
|
-
service: "CacheTestAggregate",
|
|
106
|
-
time: "2024-01-01T00:00:00Z",
|
|
107
|
-
ip: "127.0.0.1",
|
|
108
|
-
user: "test-user",
|
|
109
|
-
msgId: "msg-1",
|
|
110
|
-
correlationId: "corr-1"
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
function makeMockEL() {
|
|
114
|
-
let storedRef = {
|
|
115
|
-
contents: []
|
|
116
|
-
};
|
|
117
|
-
let appendCount = {
|
|
118
|
-
contents: 0
|
|
119
|
-
};
|
|
120
|
-
let replayCount = {
|
|
121
|
-
contents: 0
|
|
122
|
-
};
|
|
123
|
-
let eventsFor = id => storedRef.contents.filter(e => e.id === id);
|
|
124
|
-
let appendFn = async (seqNr, id, newEvents) => {
|
|
125
|
-
appendCount.contents = appendCount.contents + 1 | 0;
|
|
126
|
-
if (seqNr !== eventsFor(id).length) {
|
|
127
|
-
return {
|
|
128
|
-
TAG: "Error",
|
|
129
|
-
_0: "Conflict"
|
|
130
|
-
};
|
|
131
|
-
} else {
|
|
132
|
-
storedRef.contents = storedRef.contents.concat(newEvents);
|
|
133
|
-
return {
|
|
134
|
-
TAG: "Ok",
|
|
135
|
-
_0: undefined
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
let replayFn = async id => {
|
|
140
|
-
replayCount.contents = replayCount.contents + 1 | 0;
|
|
141
|
-
return eventsFor(id).map(e => e.event);
|
|
142
|
-
};
|
|
143
|
-
let replayStreamFn = id => {
|
|
144
|
-
replayCount.contents = replayCount.contents + 1 | 0;
|
|
145
|
-
return Stream.fromIterable(eventsFor(id).map(e => e.event));
|
|
146
|
-
};
|
|
147
|
-
return {
|
|
148
|
-
appendFn: appendFn,
|
|
149
|
-
replayFn: replayFn,
|
|
150
|
-
replayStreamFn: replayStreamFn,
|
|
151
|
-
getAll: () => storedRef.contents,
|
|
152
|
-
injectExternal: (id, event) => {
|
|
153
|
-
storedRef.contents = storedRef.contents.concat([{
|
|
154
|
-
id: id,
|
|
155
|
-
meta: testMeta,
|
|
156
|
-
event: event
|
|
157
|
-
}]);
|
|
158
|
-
},
|
|
159
|
-
appendCallCount: appendCount,
|
|
160
|
-
replayCallCount: replayCount,
|
|
161
|
-
reset: () => {
|
|
162
|
-
storedRef.contents = [];
|
|
163
|
-
appendCount.contents = 0;
|
|
164
|
-
replayCount.contents = 0;
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
let mock = makeMockEL();
|
|
170
|
-
|
|
171
|
-
let name$1 = "CacheMockEventLog";
|
|
172
|
-
|
|
173
|
-
let Spec = {
|
|
174
|
-
Id: undefined,
|
|
175
|
-
name: name$1,
|
|
176
|
-
eventSchema: eventSchema
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
function make(param, param$1) {
|
|
180
|
-
return 0;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let EventLog = {
|
|
184
|
-
Spec: Spec,
|
|
185
|
-
make: make
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
let eventLog_append = mock.appendFn;
|
|
189
|
-
|
|
190
|
-
let eventLog_replay = mock.replayFn;
|
|
191
|
-
|
|
192
|
-
function eventLog_replayStream(id, param) {
|
|
193
|
-
return mock.replayStreamFn(id);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function eventLog_appendStream(_startingSeqNr, _id, stream) {
|
|
197
|
-
return Stream.runDrain(stream);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function eventLog_latestSnapshot(param) {
|
|
201
|
-
return {
|
|
202
|
-
TAG: "Ok",
|
|
203
|
-
_0: undefined
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
async function eventLog_writeSnapshot(param, param$1) {
|
|
208
|
-
return {
|
|
209
|
-
TAG: "Ok",
|
|
210
|
-
_0: undefined
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
let eventLog = {
|
|
215
|
-
append: eventLog_append,
|
|
216
|
-
replay: eventLog_replay,
|
|
217
|
-
replayStream: eventLog_replayStream,
|
|
218
|
-
appendStream: eventLog_appendStream,
|
|
219
|
-
latestSnapshot: eventLog_latestSnapshot,
|
|
220
|
-
writeSnapshot: eventLog_writeSnapshot
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
let TestOps = {
|
|
224
|
-
Spec: undefined,
|
|
225
|
-
EventLog: EventLog,
|
|
226
|
-
eventLog: eventLog
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
230
|
-
Id: {
|
|
231
|
-
schema: Id$Reventless.StringPure.schema,
|
|
232
|
-
make: prim => prim,
|
|
233
|
-
makeFromString: prim => prim,
|
|
234
|
-
toString: prim => prim,
|
|
235
|
-
cmp: Id$Reventless.StringPure.cmp
|
|
236
|
-
},
|
|
237
|
-
name: name,
|
|
238
|
-
eventSchema: eventSchema,
|
|
239
|
-
errorSchema: errorSchema,
|
|
240
|
-
commandSchema: commandSchema,
|
|
241
|
-
moduleUrl: moduleUrl,
|
|
242
|
-
commandAuthorization: commandAuthorization
|
|
243
|
-
})({
|
|
244
|
-
initialState: initialState,
|
|
245
|
-
evolve: evolve,
|
|
246
|
-
decide: decide,
|
|
247
|
-
snapshot: undefined,
|
|
248
|
-
moduleUrl: moduleUrl$1
|
|
249
|
-
})({
|
|
250
|
-
Spec: {
|
|
251
|
-
Id: {
|
|
252
|
-
schema: Id$Reventless.StringPure.schema,
|
|
253
|
-
make: prim => prim,
|
|
254
|
-
makeFromString: prim => prim,
|
|
255
|
-
toString: prim => prim,
|
|
256
|
-
cmp: Id$Reventless.StringPure.cmp
|
|
257
|
-
},
|
|
258
|
-
name: name,
|
|
259
|
-
eventSchema: eventSchema,
|
|
260
|
-
errorSchema: errorSchema,
|
|
261
|
-
commandSchema: commandSchema,
|
|
262
|
-
moduleUrl: moduleUrl,
|
|
263
|
-
commandAuthorization: commandAuthorization
|
|
264
|
-
},
|
|
265
|
-
EventLog: {
|
|
266
|
-
Spec: {
|
|
267
|
-
Id: {
|
|
268
|
-
schema: Id$Reventless.StringPure.schema,
|
|
269
|
-
make: prim => prim,
|
|
270
|
-
makeFromString: prim => prim,
|
|
271
|
-
toString: prim => prim,
|
|
272
|
-
cmp: Id$Reventless.StringPure.cmp
|
|
273
|
-
},
|
|
274
|
-
name: name$1,
|
|
275
|
-
eventSchema: eventSchema
|
|
276
|
-
},
|
|
277
|
-
make: make
|
|
278
|
-
},
|
|
279
|
-
eventLog: eventLog
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
function makeTopicItem(reference, command) {
|
|
283
|
-
return {
|
|
284
|
-
command: {
|
|
285
|
-
id: "agg-1",
|
|
286
|
-
meta: testMeta,
|
|
287
|
-
command: command
|
|
288
|
-
},
|
|
289
|
-
reference: reference
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async function run(command) {
|
|
294
|
-
return await Effect.runPromise(TestHandler.handleCommands(Stream.fromIterable([makeTopicItem("ref", command)])));
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
globalThis.beforeEach(() => {
|
|
298
|
-
mock.reset();
|
|
299
|
-
TestHandler.resetCache();
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
globalThis.describe("Aggregate_Callback — replay cache:", () => {
|
|
303
|
-
globalThis.test("warm same-id command skips the replay", async () => {
|
|
304
|
-
let r1 = await run({
|
|
305
|
-
TAG: "Add",
|
|
306
|
-
name: "a"
|
|
307
|
-
});
|
|
308
|
-
let r2 = await run({
|
|
309
|
-
TAG: "Add",
|
|
310
|
-
name: "b"
|
|
311
|
-
});
|
|
312
|
-
globalThis.expect([
|
|
313
|
-
r1,
|
|
314
|
-
r2
|
|
315
|
-
]).toEqual([
|
|
316
|
-
[{
|
|
317
|
-
TAG: "Ok",
|
|
318
|
-
_0: "ref"
|
|
319
|
-
}],
|
|
320
|
-
[{
|
|
321
|
-
TAG: "Ok",
|
|
322
|
-
_0: "ref"
|
|
323
|
-
}]
|
|
324
|
-
]);
|
|
325
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(1);
|
|
326
|
-
globalThis.expect([
|
|
327
|
-
mock.appendCallCount.contents,
|
|
328
|
-
mock.getAll().length
|
|
329
|
-
]).toEqual([
|
|
330
|
-
2,
|
|
331
|
-
2
|
|
332
|
-
]);
|
|
333
|
-
});
|
|
334
|
-
globalThis.test("cached fold state equals a cold replay of the log", async () => {
|
|
335
|
-
await run({
|
|
336
|
-
TAG: "Add",
|
|
337
|
-
name: "a"
|
|
338
|
-
});
|
|
339
|
-
await run({
|
|
340
|
-
TAG: "Add",
|
|
341
|
-
name: "b"
|
|
342
|
-
});
|
|
343
|
-
await run({
|
|
344
|
-
TAG: "Add",
|
|
345
|
-
name: "c"
|
|
346
|
-
});
|
|
347
|
-
await run("Checkpoint");
|
|
348
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(1);
|
|
349
|
-
TestHandler.resetCache();
|
|
350
|
-
await run("Checkpoint");
|
|
351
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(2);
|
|
352
|
-
let checkpoints = Stdlib_Array.filterMap(mock.getAll(), e => {
|
|
353
|
-
let match = e.event;
|
|
354
|
-
if (match.TAG === "Added") {
|
|
355
|
-
return;
|
|
356
|
-
} else {
|
|
357
|
-
return match.count;
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
globalThis.expect(checkpoints).toEqual([
|
|
361
|
-
3,
|
|
362
|
-
3
|
|
363
|
-
]);
|
|
364
|
-
});
|
|
365
|
-
globalThis.test("stale cache conflicts, invalidates, and self-heals", async () => {
|
|
366
|
-
await run({
|
|
367
|
-
TAG: "Add",
|
|
368
|
-
name: "a"
|
|
369
|
-
});
|
|
370
|
-
mock.injectExternal("agg-1", {
|
|
371
|
-
TAG: "Added",
|
|
372
|
-
name: "external"
|
|
373
|
-
});
|
|
374
|
-
let results = await run({
|
|
375
|
-
TAG: "Add",
|
|
376
|
-
name: "b"
|
|
377
|
-
});
|
|
378
|
-
globalThis.expect(results).toEqual([{
|
|
379
|
-
TAG: "Ok",
|
|
380
|
-
_0: "ref"
|
|
381
|
-
}]);
|
|
382
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(2);
|
|
383
|
-
globalThis.expect(mock.getAll().length).toBe(3);
|
|
384
|
-
await run("Checkpoint");
|
|
385
|
-
let last = mock.getAll()[3];
|
|
386
|
-
globalThis.expect(last.event).toEqual({
|
|
387
|
-
TAG: "CheckpointTaken",
|
|
388
|
-
count: 3
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
globalThis.test("Ok([]) keeps the read snapshot warm", async () => {
|
|
392
|
-
await run({
|
|
393
|
-
TAG: "Add",
|
|
394
|
-
name: "a"
|
|
395
|
-
});
|
|
396
|
-
await run("Noop");
|
|
397
|
-
await run({
|
|
398
|
-
TAG: "Add",
|
|
399
|
-
name: "b"
|
|
400
|
-
});
|
|
401
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(1);
|
|
402
|
-
globalThis.expect(mock.getAll().length).toBe(2);
|
|
403
|
-
});
|
|
404
|
-
globalThis.test("resetCache forces the next command to replay cold", async () => {
|
|
405
|
-
await run({
|
|
406
|
-
TAG: "Add",
|
|
407
|
-
name: "a"
|
|
408
|
-
});
|
|
409
|
-
TestHandler.resetCache();
|
|
410
|
-
await run({
|
|
411
|
-
TAG: "Add",
|
|
412
|
-
name: "b"
|
|
413
|
-
});
|
|
414
|
-
globalThis.expect(mock.replayCallCount.contents).toBe(2);
|
|
415
|
-
globalThis.expect(mock.getAll().length).toBe(2);
|
|
416
|
-
});
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
let OuterEventLog;
|
|
420
|
-
|
|
421
|
-
export {
|
|
422
|
-
AggSpec,
|
|
423
|
-
TestBehavior,
|
|
424
|
-
testMeta,
|
|
425
|
-
makeMockEL,
|
|
426
|
-
mock,
|
|
427
|
-
OuterEventLog,
|
|
428
|
-
TestOps,
|
|
429
|
-
TestHandler,
|
|
430
|
-
makeTopicItem,
|
|
431
|
-
run,
|
|
432
|
-
}
|
|
433
|
-
/* Not a pure module */
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Stream from "effect/Stream";
|
|
5
|
-
import * as AggregateFixtures$ReventlessCore from "./AggregateFixtures.res.mjs";
|
|
6
|
-
|
|
7
|
-
globalThis.beforeEach(() => {
|
|
8
|
-
AggregateFixtures$ReventlessCore.mock.reset();
|
|
9
|
-
AggregateFixtures$ReventlessCore.TestHandler.resetCache();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
globalThis.describe("Aggregate_Callback.handleCommands:", () => {
|
|
13
|
-
globalThis.describe("single command — new aggregate", () => {
|
|
14
|
-
globalThis.test("Create returns Ok(reference) and stores 1 event", async () => {
|
|
15
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([AggregateFixtures$ReventlessCore.makeTopicItem(undefined, "ref-1", {
|
|
16
|
-
TAG: "Create",
|
|
17
|
-
name: "Widget"
|
|
18
|
-
})])));
|
|
19
|
-
globalThis.expect([
|
|
20
|
-
results,
|
|
21
|
-
AggregateFixtures$ReventlessCore.mock.getAll().length
|
|
22
|
-
]).toEqual([
|
|
23
|
-
[{
|
|
24
|
-
TAG: "Ok",
|
|
25
|
-
_0: "ref-1"
|
|
26
|
-
}],
|
|
27
|
-
1
|
|
28
|
-
]);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
globalThis.describe("command on existing aggregate", () => {
|
|
32
|
-
globalThis.test("Rename after Create replays history and appends new event", async () => {
|
|
33
|
-
await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([AggregateFixtures$ReventlessCore.makeTopicItem(undefined, "ref-1", {
|
|
34
|
-
TAG: "Create",
|
|
35
|
-
name: "Widget"
|
|
36
|
-
})])));
|
|
37
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([AggregateFixtures$ReventlessCore.makeTopicItem(undefined, "ref-2", {
|
|
38
|
-
TAG: "Rename",
|
|
39
|
-
newName: "Gadget"
|
|
40
|
-
})])));
|
|
41
|
-
globalThis.expect([
|
|
42
|
-
results,
|
|
43
|
-
AggregateFixtures$ReventlessCore.mock.getAll().length
|
|
44
|
-
]).toEqual([
|
|
45
|
-
[{
|
|
46
|
-
TAG: "Ok",
|
|
47
|
-
_0: "ref-2"
|
|
48
|
-
}],
|
|
49
|
-
2
|
|
50
|
-
]);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
globalThis.describe("behavior returns no events", () => {
|
|
54
|
-
globalThis.test("Rename on new aggregate returns Ok with no event stored", async () => {
|
|
55
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([AggregateFixtures$ReventlessCore.makeTopicItem(undefined, "ref-1", {
|
|
56
|
-
TAG: "Rename",
|
|
57
|
-
newName: "Gadget"
|
|
58
|
-
})])));
|
|
59
|
-
globalThis.expect([
|
|
60
|
-
results,
|
|
61
|
-
AggregateFixtures$ReventlessCore.mock.getAll().length
|
|
62
|
-
]).toEqual([
|
|
63
|
-
[{
|
|
64
|
-
TAG: "Ok",
|
|
65
|
-
_0: "ref-1"
|
|
66
|
-
}],
|
|
67
|
-
0
|
|
68
|
-
]);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
globalThis.describe("append failure", () => {
|
|
72
|
-
globalThis.test("eventLog.append fails → reference returned Error", async () => {
|
|
73
|
-
AggregateFixtures$ReventlessCore.mock.failNextAppend.contents = true;
|
|
74
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([AggregateFixtures$ReventlessCore.makeTopicItem(undefined, "ref-1", {
|
|
75
|
-
TAG: "Create",
|
|
76
|
-
name: "Widget"
|
|
77
|
-
})])));
|
|
78
|
-
globalThis.expect(results).toEqual([{
|
|
79
|
-
TAG: "Error",
|
|
80
|
-
_0: "ref-1"
|
|
81
|
-
}]);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
globalThis.describe("multiple commands for same aggregate ID", () => {
|
|
85
|
-
globalThis.test("Create then Rename in one batch accumulate state correctly", async () => {
|
|
86
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([
|
|
87
|
-
AggregateFixtures$ReventlessCore.makeTopicItem("agg-1", "ref-1", {
|
|
88
|
-
TAG: "Create",
|
|
89
|
-
name: "Widget"
|
|
90
|
-
}),
|
|
91
|
-
AggregateFixtures$ReventlessCore.makeTopicItem("agg-1", "ref-2", {
|
|
92
|
-
TAG: "Rename",
|
|
93
|
-
newName: "Gadget"
|
|
94
|
-
})
|
|
95
|
-
])));
|
|
96
|
-
globalThis.expect([
|
|
97
|
-
results,
|
|
98
|
-
AggregateFixtures$ReventlessCore.mock.getAll().length
|
|
99
|
-
]).toEqual([
|
|
100
|
-
[
|
|
101
|
-
{
|
|
102
|
-
TAG: "Ok",
|
|
103
|
-
_0: "ref-1"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
TAG: "Ok",
|
|
107
|
-
_0: "ref-2"
|
|
108
|
-
}
|
|
109
|
-
],
|
|
110
|
-
2
|
|
111
|
-
]);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
globalThis.describe("commands for different aggregate IDs", () => {
|
|
115
|
-
globalThis.test("each ID processed independently", async () => {
|
|
116
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([
|
|
117
|
-
AggregateFixtures$ReventlessCore.makeTopicItem("agg-a", "ref-a", {
|
|
118
|
-
TAG: "Create",
|
|
119
|
-
name: "Alpha"
|
|
120
|
-
}),
|
|
121
|
-
AggregateFixtures$ReventlessCore.makeTopicItem("agg-b", "ref-b", {
|
|
122
|
-
TAG: "Create",
|
|
123
|
-
name: "Beta"
|
|
124
|
-
})
|
|
125
|
-
])));
|
|
126
|
-
globalThis.expect([
|
|
127
|
-
results.length,
|
|
128
|
-
AggregateFixtures$ReventlessCore.mock.getAll().length
|
|
129
|
-
]).toEqual([
|
|
130
|
-
2,
|
|
131
|
-
2
|
|
132
|
-
]);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
globalThis.describe("empty batch", () => {
|
|
136
|
-
globalThis.test("returns empty array", async () => {
|
|
137
|
-
let results = await Effect.runPromise(AggregateFixtures$ReventlessCore.TestHandler.handleCommands(Stream.fromIterable([])));
|
|
138
|
-
globalThis.expect(results).toEqual([]);
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
/* Not a pure module */
|