@reventlessdev/reventless-local 3.0.0-alpha.173 → 3.0.0-alpha.175
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 +15 -0
- package/package.json +9 -9
- package/src/Platform.res +19 -6
- package/src/Platform.res.mjs +10 -0
- package/src/adapter/Api/LocalEvents_Server.res +324 -0
- package/src/adapter/Api/LocalEvents_Server.res.mjs +341 -0
- package/src/adapter/DomainGraphQL_Server.res +23 -0
- package/src/adapter/DomainGraphQL_Server.res.mjs +36 -14
- package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res +352 -0
- package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res.mjs +362 -0
- package/src/adapter/LocalBus.res +12 -1
- package/src/adapter/LocalBus.res.mjs +36 -0
- package/tests/adapter/EventHistoryResolverTest.res +208 -0
- package/tests/adapter/EventHistoryResolverTest.res.mjs +286 -0
- package/tests/adapter/LocalEvents_ServerTest.res +200 -0
- package/tests/adapter/LocalEvents_ServerTest.res.mjs +147 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
4
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
5
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
8
|
+
import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
|
|
9
|
+
import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
|
|
10
|
+
import * as QueryDbListQuery$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/QueryDbListQuery.res.mjs";
|
|
11
|
+
import * as Plugin_EventQuerySchema$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_EventQuerySchema.res.mjs";
|
|
12
|
+
|
|
13
|
+
function comparePosition(a, b) {
|
|
14
|
+
let match = Stdlib_Int.fromString(a, undefined);
|
|
15
|
+
let match$1 = Stdlib_Int.fromString(b, undefined);
|
|
16
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
17
|
+
return match - match$1 | 0;
|
|
18
|
+
}
|
|
19
|
+
if (a < b) {
|
|
20
|
+
return -1;
|
|
21
|
+
} else if (a > b) {
|
|
22
|
+
return 1;
|
|
23
|
+
} else {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function positionGt(a, b) {
|
|
29
|
+
return comparePosition(a, b) > 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function positionLt(a, b) {
|
|
33
|
+
return comparePosition(a, b) < 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function str(prim) {
|
|
37
|
+
return prim;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function optStr(o) {
|
|
41
|
+
return Stdlib_Option.mapOr(o, null, str);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function metaJson(m) {
|
|
45
|
+
return Object.fromEntries([
|
|
46
|
+
[
|
|
47
|
+
"service",
|
|
48
|
+
m.service
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"time",
|
|
52
|
+
m.time
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"user",
|
|
56
|
+
Stdlib_Option.mapOr(m.user, null, str)
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"msgId",
|
|
60
|
+
m.msgId
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
"correlationId",
|
|
64
|
+
m.correlationId
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
"causationId",
|
|
68
|
+
Stdlib_Option.mapOr(m.causationId, null, str)
|
|
69
|
+
]
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function metaJsonFromEnvelope(envelope) {
|
|
74
|
+
let m = Stdlib_Option.getOr(Stdlib_Option.flatMap(envelope["meta"], Stdlib_JSON.Decode.object), {});
|
|
75
|
+
let get = k => Stdlib_Option.flatMap(m[k], Stdlib_JSON.Decode.string);
|
|
76
|
+
return Object.fromEntries([
|
|
77
|
+
[
|
|
78
|
+
"service",
|
|
79
|
+
Stdlib_Option.getOr(get("service"), "")
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"time",
|
|
83
|
+
Stdlib_Option.getOr(get("time"), "")
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
"user",
|
|
87
|
+
Stdlib_Option.mapOr(get("user"), null, str)
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"msgId",
|
|
91
|
+
Stdlib_Option.getOr(get("msgId"), "")
|
|
92
|
+
],
|
|
93
|
+
[
|
|
94
|
+
"correlationId",
|
|
95
|
+
Stdlib_Option.getOr(get("correlationId"), "")
|
|
96
|
+
],
|
|
97
|
+
[
|
|
98
|
+
"causationId",
|
|
99
|
+
Stdlib_Option.mapOr(get("causationId"), null, str)
|
|
100
|
+
]
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function recordJson(r) {
|
|
105
|
+
return Object.fromEntries([
|
|
106
|
+
[
|
|
107
|
+
"position",
|
|
108
|
+
r.position
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"eventType",
|
|
112
|
+
r.eventType
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"payload",
|
|
116
|
+
r.payload
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
"tags",
|
|
120
|
+
r.tags.map(t => Object.fromEntries([
|
|
121
|
+
[
|
|
122
|
+
"key",
|
|
123
|
+
t.key
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"value",
|
|
127
|
+
t.value
|
|
128
|
+
]
|
|
129
|
+
]))
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"meta",
|
|
133
|
+
r.meta
|
|
134
|
+
],
|
|
135
|
+
[
|
|
136
|
+
"recordedAt",
|
|
137
|
+
r.recordedAt
|
|
138
|
+
]
|
|
139
|
+
]);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function readFilter(args) {
|
|
143
|
+
let f = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(args), d => d["filter"]), Stdlib_JSON.Decode.object), {});
|
|
144
|
+
let s = k => Stdlib_Option.flatMap(f[k], Stdlib_JSON.Decode.string);
|
|
145
|
+
return {
|
|
146
|
+
entityId: s("entityId"),
|
|
147
|
+
tagKey: s("tagKey"),
|
|
148
|
+
tagValue: s("tagValue"),
|
|
149
|
+
eventTypes: Stdlib_Option.map(Stdlib_Option.flatMap(f["eventTypes"], Stdlib_JSON.Decode.array), a => Stdlib_Array.filterMap(a, Stdlib_JSON.Decode.string)),
|
|
150
|
+
user: s("user"),
|
|
151
|
+
timeFrom: s("timeFrom"),
|
|
152
|
+
timeTo: s("timeTo")
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function matchesTag(r, f) {
|
|
157
|
+
let match = f.tagKey;
|
|
158
|
+
let match$1 = f.tagValue;
|
|
159
|
+
if (match !== undefined) {
|
|
160
|
+
if (match$1 !== undefined) {
|
|
161
|
+
return r.tags.some(t => {
|
|
162
|
+
if (t.key === match) {
|
|
163
|
+
return t.value === match$1;
|
|
164
|
+
} else {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
return r.tags.some(t => t.key === match);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (match$1 !== undefined) {
|
|
173
|
+
return r.tags.some(t => t.value === match$1);
|
|
174
|
+
}
|
|
175
|
+
let id = f.entityId;
|
|
176
|
+
if (id !== undefined) {
|
|
177
|
+
return r.tags.some(t => t.value === id);
|
|
178
|
+
} else {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function matchesFilter(r, f) {
|
|
184
|
+
let userOf = () => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(r.meta), d => d["user"]), Stdlib_JSON.Decode.string);
|
|
185
|
+
let timeOf = () => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(r.meta), d => d["time"]), Stdlib_JSON.Decode.string), r.recordedAt);
|
|
186
|
+
if (matchesTag(r, f) && Stdlib_Option.mapOr(f.eventTypes, true, types => types.includes(r.eventType)) && Stdlib_Option.mapOr(f.user, true, u => Primitive_object.equal(userOf(), u)) && Stdlib_Option.mapOr(f.timeFrom, true, from => timeOf() >= from)) {
|
|
187
|
+
return Stdlib_Option.mapOr(f.timeTo, true, to_ => timeOf() <= to_);
|
|
188
|
+
} else {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function paginate(records, args) {
|
|
194
|
+
let argsDict = Stdlib_Option.getOr(Stdlib_JSON.Decode.object(args), {});
|
|
195
|
+
let getInt = k => Stdlib_Option.map(Stdlib_Option.flatMap(argsDict[k], Stdlib_JSON.Decode.float), prim => prim | 0);
|
|
196
|
+
let getStr = k => Stdlib_Option.flatMap(argsDict[k], Stdlib_JSON.Decode.string);
|
|
197
|
+
let sorted = records.toSorted((a, b) => comparePosition(a.position, b.position));
|
|
198
|
+
let first = getInt("first");
|
|
199
|
+
let last = getInt("last");
|
|
200
|
+
let after = getStr("after");
|
|
201
|
+
let before = getStr("before");
|
|
202
|
+
let isBackward = Stdlib_Option.isSome(last);
|
|
203
|
+
let bounded;
|
|
204
|
+
let exit = 0;
|
|
205
|
+
if (after !== undefined && !isBackward) {
|
|
206
|
+
let cv = QueryDbListQuery$ReventlessCore.decodeCursor(after);
|
|
207
|
+
bounded = sorted.filter(r => positionGt(r.position, cv));
|
|
208
|
+
} else {
|
|
209
|
+
exit = 1;
|
|
210
|
+
}
|
|
211
|
+
if (exit === 1) {
|
|
212
|
+
if (before !== undefined && isBackward) {
|
|
213
|
+
let cv$1 = QueryDbListQuery$ReventlessCore.decodeCursor(before);
|
|
214
|
+
bounded = sorted.filter(r => positionLt(r.position, cv$1));
|
|
215
|
+
} else {
|
|
216
|
+
bounded = sorted;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
let pageSize = Stdlib_Option.getOr(isBackward ? last : first, QueryDbListQuery$ReventlessCore.defaultListPageSize);
|
|
220
|
+
let take = pageSize + 1 | 0;
|
|
221
|
+
let match;
|
|
222
|
+
if (isBackward) {
|
|
223
|
+
let len = bounded.length;
|
|
224
|
+
let startIdx = len > take ? len - take | 0 : 0;
|
|
225
|
+
let arr = bounded.slice(startIdx, len);
|
|
226
|
+
let hasMore = arr.length > pageSize;
|
|
227
|
+
match = [
|
|
228
|
+
hasMore ? arr.slice(1, arr.length) : arr,
|
|
229
|
+
hasMore
|
|
230
|
+
];
|
|
231
|
+
} else {
|
|
232
|
+
let arr$1 = bounded.slice(0, take);
|
|
233
|
+
let hasMore$1 = arr$1.length > pageSize;
|
|
234
|
+
match = [
|
|
235
|
+
arr$1.slice(0, pageSize),
|
|
236
|
+
hasMore$1
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
let hasMore$2 = match[1];
|
|
240
|
+
return QueryDbListQuery$ReventlessCore.buildConnection(match[0].map(recordJson), !isBackward && hasMore$2, isBackward && hasMore$2, item => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(item), d => d["position"]), Stdlib_JSON.Decode.string), ""));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function emptyConnection() {
|
|
244
|
+
return QueryDbListQuery$ReventlessCore.buildConnection([], false, false, param => "");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function Make(Bus) {
|
|
248
|
+
let log = Logger$ReventlessCore.fromEnv();
|
|
249
|
+
let dcbQueryFor = f => {
|
|
250
|
+
let match = f.tagKey;
|
|
251
|
+
let match$1 = f.tagValue;
|
|
252
|
+
if (match !== undefined) {
|
|
253
|
+
if (match$1 !== undefined) {
|
|
254
|
+
return [{
|
|
255
|
+
tags: [{
|
|
256
|
+
key: match,
|
|
257
|
+
value: match$1
|
|
258
|
+
}]
|
|
259
|
+
}];
|
|
260
|
+
} else {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
let readDcb = async (read, f) => {
|
|
268
|
+
let result = await read(dcbQueryFor(f), undefined);
|
|
269
|
+
return result.events.map(e => ({
|
|
270
|
+
position: e.position,
|
|
271
|
+
eventType: e.eventType,
|
|
272
|
+
payload: e.data,
|
|
273
|
+
tags: e.tags,
|
|
274
|
+
meta: metaJson(e.meta),
|
|
275
|
+
recordedAt: e.recordedAt
|
|
276
|
+
}));
|
|
277
|
+
};
|
|
278
|
+
let readAggregate = async (replay, entityId) => {
|
|
279
|
+
let envelopes = await replay(entityId);
|
|
280
|
+
return envelopes.map((json, i) => {
|
|
281
|
+
let obj = Stdlib_Option.getOr(Stdlib_JSON.Decode.object(json), {});
|
|
282
|
+
let event = Stdlib_Option.getOr(obj["event"], null);
|
|
283
|
+
let id = Stdlib_Option.getOr(Stdlib_Option.flatMap(obj["id"], Stdlib_JSON.Decode.string), entityId);
|
|
284
|
+
let meta = metaJsonFromEnvelope(obj);
|
|
285
|
+
let time = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(meta), d => d["time"]), Stdlib_JSON.Decode.string), "");
|
|
286
|
+
return {
|
|
287
|
+
position: i.toString(),
|
|
288
|
+
eventType: Message$Reventless.variantNameOfJson(event),
|
|
289
|
+
payload: event,
|
|
290
|
+
tags: [{
|
|
291
|
+
key: "id",
|
|
292
|
+
value: id
|
|
293
|
+
}],
|
|
294
|
+
meta: meta,
|
|
295
|
+
recordedAt: time
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
let register = (server, params) => {
|
|
300
|
+
let seen = new Set();
|
|
301
|
+
params.eventLogEntries.forEach(entry => {
|
|
302
|
+
let displayName = entry.displayName;
|
|
303
|
+
if (seen.has(displayName)) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
seen.add(displayName);
|
|
307
|
+
let fieldName = Plugin_EventQuerySchema$ReventlessCore.historyFieldName(params.pluginName, displayName);
|
|
308
|
+
let resolver = async (_root, args, _ctx) => {
|
|
309
|
+
let f = readFilter(args);
|
|
310
|
+
let replay = Bus.getEventLogReplay(entry.busKey);
|
|
311
|
+
let records;
|
|
312
|
+
if (replay !== undefined) {
|
|
313
|
+
let entityId = f.entityId;
|
|
314
|
+
if (entityId !== undefined) {
|
|
315
|
+
records = await readAggregate(replay, entityId);
|
|
316
|
+
} else {
|
|
317
|
+
log.warn("EventHistoryResolvers_GraphQL", undefined, fieldName + `: ` + displayName + ` is an aggregate event log — it can only be read per entity. Supply filter.entityId.`);
|
|
318
|
+
records = [];
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
let read = Bus.getDcbEventLogRead(entry.busKey);
|
|
322
|
+
records = read !== undefined ? await readDcb(read, f) : [];
|
|
323
|
+
}
|
|
324
|
+
if (records.length !== 0) {
|
|
325
|
+
return paginate(records.filter(r => matchesFilter(r, f)), args);
|
|
326
|
+
} else {
|
|
327
|
+
return emptyConnection();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
let sdlFields = Plugin_EventQuerySchema$ReventlessCore.generate(params.pluginName, [entry]).queryFields;
|
|
331
|
+
server.registerQueries(sdlFields, Object.fromEntries([[
|
|
332
|
+
fieldName,
|
|
333
|
+
resolver
|
|
334
|
+
]]));
|
|
335
|
+
});
|
|
336
|
+
};
|
|
337
|
+
return {
|
|
338
|
+
log: log,
|
|
339
|
+
dcbQueryFor: dcbQueryFor,
|
|
340
|
+
readDcb: readDcb,
|
|
341
|
+
readAggregate: readAggregate,
|
|
342
|
+
register: register
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export {
|
|
347
|
+
comparePosition,
|
|
348
|
+
positionGt,
|
|
349
|
+
positionLt,
|
|
350
|
+
str,
|
|
351
|
+
optStr,
|
|
352
|
+
metaJson,
|
|
353
|
+
metaJsonFromEnvelope,
|
|
354
|
+
recordJson,
|
|
355
|
+
readFilter,
|
|
356
|
+
matchesTag,
|
|
357
|
+
matchesFilter,
|
|
358
|
+
paginate,
|
|
359
|
+
emptyConnection,
|
|
360
|
+
Make,
|
|
361
|
+
}
|
|
362
|
+
/* Message-Reventless Not a pure module */
|
package/src/adapter/LocalBus.res
CHANGED
|
@@ -216,6 +216,10 @@ module type T = {
|
|
|
216
216
|
// "Removed". `position` is omitted (Phase 3 deferred).
|
|
217
217
|
let publishStateChange: (~name: string, ~descriptor: JSON.t) => unit
|
|
218
218
|
let subscribeToStateChanges: (string, JSON.t => unit) => unit
|
|
219
|
+
// All-changes variant: receives every publishStateChange with its read-model
|
|
220
|
+
// name. Used by the local Events transport to bridge descriptors onto
|
|
221
|
+
// `/default/{name}/{id}` channels without enumerating read models up front.
|
|
222
|
+
let subscribeToAllStateChanges: ((~name: string, ~descriptor: JSON.t) => unit) => unit
|
|
219
223
|
|
|
220
224
|
// Cross-plugin EP subscription registry.
|
|
221
225
|
// EventCollectors register their handler once resolved; makePlatform subscribes
|
|
@@ -463,17 +467,23 @@ module Impl = (C: BusConfig): T => {
|
|
|
463
467
|
|
|
464
468
|
// Source B state-change hook — per QueryDb name, zero or more listeners.
|
|
465
469
|
let stateChangeListeners: ref<dict<array<JSON.t => unit>>> = ref(Dict.make())
|
|
470
|
+
let allStateChangeListeners: ref<array<(~name: string, ~descriptor: JSON.t) => unit>> = ref([])
|
|
466
471
|
|
|
467
472
|
let subscribeToStateChanges = (name, callback) => {
|
|
468
473
|
let listeners = stateChangeListeners.contents->Dict.get(name)->Option.getOr([])
|
|
469
474
|
stateChangeListeners.contents->Dict.set(name, Array.concat(listeners, [callback]))
|
|
470
475
|
}
|
|
471
476
|
|
|
472
|
-
let
|
|
477
|
+
let subscribeToAllStateChanges = callback =>
|
|
478
|
+
allStateChangeListeners.contents->Array.push(callback)
|
|
479
|
+
|
|
480
|
+
let publishStateChange = (~name, ~descriptor) => {
|
|
473
481
|
stateChangeListeners.contents
|
|
474
482
|
->Dict.get(name)
|
|
475
483
|
->Option.getOr([])
|
|
476
484
|
->Array.forEach(cb => cb(descriptor))
|
|
485
|
+
allStateChangeListeners.contents->Array.forEach(cb => cb(~name, ~descriptor))
|
|
486
|
+
}
|
|
477
487
|
|
|
478
488
|
let eventCollectorHandlers: ref<dict<(JSON.t, unit) => promise<unit>>> = ref(Dict.make())
|
|
479
489
|
let eventCollectorPendingTopics: ref<dict<array<string>>> = ref(Dict.make())
|
|
@@ -541,6 +551,7 @@ module Impl = (C: BusConfig): T => {
|
|
|
541
551
|
eventLogReplayRegistry := Dict.make()
|
|
542
552
|
dcbEventLogReadRegistry := Dict.make()
|
|
543
553
|
stateChangeListeners := Dict.make()
|
|
554
|
+
allStateChangeListeners := []
|
|
544
555
|
eventCollectorHandlers := Dict.make()
|
|
545
556
|
eventCollectorPendingTopics := Dict.make()
|
|
546
557
|
projectionCatchupRegistry := Dict.make()
|
|
@@ -259,12 +259,19 @@ function Impl(C) {
|
|
|
259
259
|
let stateChangeListeners = {
|
|
260
260
|
contents: {}
|
|
261
261
|
};
|
|
262
|
+
let allStateChangeListeners = {
|
|
263
|
+
contents: []
|
|
264
|
+
};
|
|
262
265
|
let subscribeToStateChanges = (name, callback) => {
|
|
263
266
|
let listeners = Stdlib_Option.getOr(stateChangeListeners.contents[name], []);
|
|
264
267
|
stateChangeListeners.contents[name] = listeners.concat([callback]);
|
|
265
268
|
};
|
|
269
|
+
let subscribeToAllStateChanges = callback => {
|
|
270
|
+
allStateChangeListeners.contents.push(callback);
|
|
271
|
+
};
|
|
266
272
|
let publishStateChange = (name, descriptor) => {
|
|
267
273
|
Stdlib_Option.getOr(stateChangeListeners.contents[name], []).forEach(cb => cb(descriptor));
|
|
274
|
+
allStateChangeListeners.contents.forEach(cb => cb(name, descriptor));
|
|
268
275
|
};
|
|
269
276
|
let eventCollectorHandlers = {
|
|
270
277
|
contents: {}
|
|
@@ -320,6 +327,7 @@ function Impl(C) {
|
|
|
320
327
|
eventLogReplayRegistry.contents = {};
|
|
321
328
|
dcbEventLogReadRegistry.contents = {};
|
|
322
329
|
stateChangeListeners.contents = {};
|
|
330
|
+
allStateChangeListeners.contents = [];
|
|
323
331
|
eventCollectorHandlers.contents = {};
|
|
324
332
|
eventCollectorPendingTopics.contents = {};
|
|
325
333
|
projectionCatchupRegistry.contents = {};
|
|
@@ -346,6 +354,7 @@ function Impl(C) {
|
|
|
346
354
|
getDcbEventLogRead: getDcbEventLogRead,
|
|
347
355
|
publishStateChange: publishStateChange,
|
|
348
356
|
subscribeToStateChanges: subscribeToStateChanges,
|
|
357
|
+
subscribeToAllStateChanges: subscribeToAllStateChanges,
|
|
349
358
|
registerEventCollectorHandler: registerEventCollectorHandler,
|
|
350
359
|
subscribeEventCollectorToTopic: subscribeEventCollectorToTopic,
|
|
351
360
|
registerProjectionCatchupHandler: registerProjectionCatchupHandler,
|
|
@@ -525,12 +534,19 @@ function Make($star) {
|
|
|
525
534
|
let stateChangeListeners = {
|
|
526
535
|
contents: {}
|
|
527
536
|
};
|
|
537
|
+
let allStateChangeListeners = {
|
|
538
|
+
contents: []
|
|
539
|
+
};
|
|
528
540
|
let subscribeToStateChanges = (name, callback) => {
|
|
529
541
|
let listeners = Stdlib_Option.getOr(stateChangeListeners.contents[name], []);
|
|
530
542
|
stateChangeListeners.contents[name] = listeners.concat([callback]);
|
|
531
543
|
};
|
|
544
|
+
let subscribeToAllStateChanges = callback => {
|
|
545
|
+
allStateChangeListeners.contents.push(callback);
|
|
546
|
+
};
|
|
532
547
|
let publishStateChange = (name, descriptor) => {
|
|
533
548
|
Stdlib_Option.getOr(stateChangeListeners.contents[name], []).forEach(cb => cb(descriptor));
|
|
549
|
+
allStateChangeListeners.contents.forEach(cb => cb(name, descriptor));
|
|
534
550
|
};
|
|
535
551
|
let eventCollectorHandlers = {
|
|
536
552
|
contents: {}
|
|
@@ -586,6 +602,7 @@ function Make($star) {
|
|
|
586
602
|
eventLogReplayRegistry.contents = {};
|
|
587
603
|
dcbEventLogReadRegistry.contents = {};
|
|
588
604
|
stateChangeListeners.contents = {};
|
|
605
|
+
allStateChangeListeners.contents = [];
|
|
589
606
|
eventCollectorHandlers.contents = {};
|
|
590
607
|
eventCollectorPendingTopics.contents = {};
|
|
591
608
|
projectionCatchupRegistry.contents = {};
|
|
@@ -612,6 +629,7 @@ function Make($star) {
|
|
|
612
629
|
getDcbEventLogRead: getDcbEventLogRead,
|
|
613
630
|
publishStateChange: publishStateChange,
|
|
614
631
|
subscribeToStateChanges: subscribeToStateChanges,
|
|
632
|
+
subscribeToAllStateChanges: subscribeToAllStateChanges,
|
|
615
633
|
registerEventCollectorHandler: registerEventCollectorHandler,
|
|
616
634
|
subscribeEventCollectorToTopic: subscribeEventCollectorToTopic,
|
|
617
635
|
registerProjectionCatchupHandler: registerProjectionCatchupHandler,
|
|
@@ -791,12 +809,19 @@ function MakeSilent($star) {
|
|
|
791
809
|
let stateChangeListeners = {
|
|
792
810
|
contents: {}
|
|
793
811
|
};
|
|
812
|
+
let allStateChangeListeners = {
|
|
813
|
+
contents: []
|
|
814
|
+
};
|
|
794
815
|
let subscribeToStateChanges = (name, callback) => {
|
|
795
816
|
let listeners = Stdlib_Option.getOr(stateChangeListeners.contents[name], []);
|
|
796
817
|
stateChangeListeners.contents[name] = listeners.concat([callback]);
|
|
797
818
|
};
|
|
819
|
+
let subscribeToAllStateChanges = callback => {
|
|
820
|
+
allStateChangeListeners.contents.push(callback);
|
|
821
|
+
};
|
|
798
822
|
let publishStateChange = (name, descriptor) => {
|
|
799
823
|
Stdlib_Option.getOr(stateChangeListeners.contents[name], []).forEach(cb => cb(descriptor));
|
|
824
|
+
allStateChangeListeners.contents.forEach(cb => cb(name, descriptor));
|
|
800
825
|
};
|
|
801
826
|
let eventCollectorHandlers = {
|
|
802
827
|
contents: {}
|
|
@@ -852,6 +877,7 @@ function MakeSilent($star) {
|
|
|
852
877
|
eventLogReplayRegistry.contents = {};
|
|
853
878
|
dcbEventLogReadRegistry.contents = {};
|
|
854
879
|
stateChangeListeners.contents = {};
|
|
880
|
+
allStateChangeListeners.contents = [];
|
|
855
881
|
eventCollectorHandlers.contents = {};
|
|
856
882
|
eventCollectorPendingTopics.contents = {};
|
|
857
883
|
projectionCatchupRegistry.contents = {};
|
|
@@ -878,6 +904,7 @@ function MakeSilent($star) {
|
|
|
878
904
|
getDcbEventLogRead: getDcbEventLogRead,
|
|
879
905
|
publishStateChange: publishStateChange,
|
|
880
906
|
subscribeToStateChanges: subscribeToStateChanges,
|
|
907
|
+
subscribeToAllStateChanges: subscribeToAllStateChanges,
|
|
881
908
|
registerEventCollectorHandler: registerEventCollectorHandler,
|
|
882
909
|
subscribeEventCollectorToTopic: subscribeEventCollectorToTopic,
|
|
883
910
|
registerProjectionCatchupHandler: registerProjectionCatchupHandler,
|
|
@@ -1055,12 +1082,19 @@ function MakeBounded(C) {
|
|
|
1055
1082
|
let stateChangeListeners = {
|
|
1056
1083
|
contents: {}
|
|
1057
1084
|
};
|
|
1085
|
+
let allStateChangeListeners = {
|
|
1086
|
+
contents: []
|
|
1087
|
+
};
|
|
1058
1088
|
let subscribeToStateChanges = (name, callback) => {
|
|
1059
1089
|
let listeners = Stdlib_Option.getOr(stateChangeListeners.contents[name], []);
|
|
1060
1090
|
stateChangeListeners.contents[name] = listeners.concat([callback]);
|
|
1061
1091
|
};
|
|
1092
|
+
let subscribeToAllStateChanges = callback => {
|
|
1093
|
+
allStateChangeListeners.contents.push(callback);
|
|
1094
|
+
};
|
|
1062
1095
|
let publishStateChange = (name, descriptor) => {
|
|
1063
1096
|
Stdlib_Option.getOr(stateChangeListeners.contents[name], []).forEach(cb => cb(descriptor));
|
|
1097
|
+
allStateChangeListeners.contents.forEach(cb => cb(name, descriptor));
|
|
1064
1098
|
};
|
|
1065
1099
|
let eventCollectorHandlers = {
|
|
1066
1100
|
contents: {}
|
|
@@ -1116,6 +1150,7 @@ function MakeBounded(C) {
|
|
|
1116
1150
|
eventLogReplayRegistry.contents = {};
|
|
1117
1151
|
dcbEventLogReadRegistry.contents = {};
|
|
1118
1152
|
stateChangeListeners.contents = {};
|
|
1153
|
+
allStateChangeListeners.contents = [];
|
|
1119
1154
|
eventCollectorHandlers.contents = {};
|
|
1120
1155
|
eventCollectorPendingTopics.contents = {};
|
|
1121
1156
|
projectionCatchupRegistry.contents = {};
|
|
@@ -1142,6 +1177,7 @@ function MakeBounded(C) {
|
|
|
1142
1177
|
getDcbEventLogRead: getDcbEventLogRead,
|
|
1143
1178
|
publishStateChange: publishStateChange,
|
|
1144
1179
|
subscribeToStateChanges: subscribeToStateChanges,
|
|
1180
|
+
subscribeToAllStateChanges: subscribeToAllStateChanges,
|
|
1145
1181
|
registerEventCollectorHandler: registerEventCollectorHandler,
|
|
1146
1182
|
subscribeEventCollectorToTopic: subscribeEventCollectorToTopic,
|
|
1147
1183
|
registerProjectionCatchupHandler: registerProjectionCatchupHandler,
|