@rotorsoft/act 0.21.0 → 0.22.0
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/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts +14 -0
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/InMemoryStore.d.ts +5 -2
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +9 -4
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/index.cjs +90 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -427,18 +427,22 @@ var InMemoryStore = class {
|
|
|
427
427
|
/**
|
|
428
428
|
* Registers streams for event processing.
|
|
429
429
|
* @param streams - Streams to register with optional source.
|
|
430
|
-
* @returns
|
|
430
|
+
* @returns subscribed count and current max watermark.
|
|
431
431
|
*/
|
|
432
432
|
async subscribe(streams) {
|
|
433
433
|
await sleep();
|
|
434
|
-
let
|
|
434
|
+
let subscribed = 0;
|
|
435
435
|
for (const { stream, source } of streams) {
|
|
436
436
|
if (!this._streams.has(stream)) {
|
|
437
437
|
this._streams.set(stream, new InMemoryStream(stream, source));
|
|
438
|
-
|
|
438
|
+
subscribed++;
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
|
-
|
|
441
|
+
let watermark = -1;
|
|
442
|
+
for (const s of this._streams.values()) {
|
|
443
|
+
if (s.at > watermark) watermark = s.at;
|
|
444
|
+
}
|
|
445
|
+
return { subscribed, watermark };
|
|
442
446
|
}
|
|
443
447
|
/**
|
|
444
448
|
* Acknowledge completion of processing for leased streams.
|
|
@@ -725,15 +729,21 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
725
729
|
// src/act.ts
|
|
726
730
|
var tracer = build_tracer(config().logLevel);
|
|
727
731
|
var Act = class {
|
|
728
|
-
/**
|
|
729
|
-
* Create a new Act orchestrator.
|
|
730
|
-
*
|
|
731
|
-
* @param registry The registry of state, event, and action schemas
|
|
732
|
-
* @param states Map of state names to their (potentially merged) state definitions
|
|
733
|
-
*/
|
|
734
732
|
constructor(registry, _states = /* @__PURE__ */ new Map()) {
|
|
735
733
|
this.registry = registry;
|
|
736
734
|
this._states = _states;
|
|
735
|
+
const statics = [];
|
|
736
|
+
for (const register of Object.values(this.registry.events)) {
|
|
737
|
+
for (const reaction of register.reactions.values()) {
|
|
738
|
+
if (typeof reaction.resolver === "function") {
|
|
739
|
+
this._has_dynamic_resolvers = true;
|
|
740
|
+
} else if (reaction.resolver) {
|
|
741
|
+
const r = reaction.resolver;
|
|
742
|
+
statics.push({ stream: r.target, source: r.source });
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
this._static_targets = statics;
|
|
737
747
|
dispose(() => {
|
|
738
748
|
this._emitter.removeAllListeners();
|
|
739
749
|
this.stop_correlations();
|
|
@@ -747,6 +757,10 @@ var Act = class {
|
|
|
747
757
|
_correlation_timer = void 0;
|
|
748
758
|
_settle_timer = void 0;
|
|
749
759
|
_settling = false;
|
|
760
|
+
_correlation_checkpoint = -1;
|
|
761
|
+
_subscribed_statics = /* @__PURE__ */ new Set();
|
|
762
|
+
_has_dynamic_resolvers = false;
|
|
763
|
+
_correlation_initialized = false;
|
|
750
764
|
emit(event, args) {
|
|
751
765
|
return this._emitter.emit(event, args);
|
|
752
766
|
}
|
|
@@ -758,6 +772,14 @@ var Act = class {
|
|
|
758
772
|
this._emitter.off(event, listener);
|
|
759
773
|
return this;
|
|
760
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* Create a new Act orchestrator.
|
|
777
|
+
*
|
|
778
|
+
* @param registry The registry of state, event, and action schemas
|
|
779
|
+
* @param states Map of state names to their (potentially merged) state definitions
|
|
780
|
+
*/
|
|
781
|
+
/** Static resolver targets collected at build time */
|
|
782
|
+
_static_targets;
|
|
761
783
|
/**
|
|
762
784
|
* Executes an action on a state instance, committing resulting events.
|
|
763
785
|
*
|
|
@@ -1167,37 +1189,67 @@ var Act = class {
|
|
|
1167
1189
|
* @see {@link start_correlations} for automatic periodic correlation
|
|
1168
1190
|
* @see {@link stop_correlations} to stop automatic correlation
|
|
1169
1191
|
*/
|
|
1192
|
+
/**
|
|
1193
|
+
* Initialize correlation state on first call.
|
|
1194
|
+
* - Reads max(at) from store as cold-start checkpoint
|
|
1195
|
+
* - Subscribes static resolver targets (idempotent upsert)
|
|
1196
|
+
* - Populates the subscribed statics set
|
|
1197
|
+
* @internal
|
|
1198
|
+
*/
|
|
1199
|
+
async _init_correlation() {
|
|
1200
|
+
if (this._correlation_initialized) return;
|
|
1201
|
+
this._correlation_initialized = true;
|
|
1202
|
+
const { watermark } = await store().subscribe(this._static_targets);
|
|
1203
|
+
this._correlation_checkpoint = watermark;
|
|
1204
|
+
for (const { stream } of this._static_targets) {
|
|
1205
|
+
this._subscribed_statics.add(stream);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1170
1208
|
async correlate(query = { after: -1, limit: 10 }) {
|
|
1209
|
+
await this._init_correlation();
|
|
1210
|
+
if (!this._has_dynamic_resolvers)
|
|
1211
|
+
return { subscribed: 0, last_id: this._correlation_checkpoint };
|
|
1212
|
+
const after = Math.max(this._correlation_checkpoint, query.after || -1);
|
|
1171
1213
|
const correlated = /* @__PURE__ */ new Map();
|
|
1172
|
-
let last_id =
|
|
1173
|
-
await store().query(
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1214
|
+
let last_id = after;
|
|
1215
|
+
await store().query(
|
|
1216
|
+
(event) => {
|
|
1217
|
+
last_id = event.id;
|
|
1218
|
+
const register = this.registry.events[event.name];
|
|
1219
|
+
if (register) {
|
|
1220
|
+
for (const reaction of register.reactions.values()) {
|
|
1221
|
+
if (typeof reaction.resolver !== "function") continue;
|
|
1222
|
+
const resolved = reaction.resolver(event);
|
|
1223
|
+
if (resolved && !this._subscribed_statics.has(resolved.target)) {
|
|
1224
|
+
const entry = correlated.get(resolved.target) || {
|
|
1225
|
+
source: resolved.source,
|
|
1226
|
+
payloads: []
|
|
1227
|
+
};
|
|
1228
|
+
entry.payloads.push({
|
|
1229
|
+
...reaction,
|
|
1230
|
+
source: resolved.source,
|
|
1231
|
+
event
|
|
1232
|
+
});
|
|
1233
|
+
correlated.set(resolved.target, entry);
|
|
1234
|
+
}
|
|
1190
1235
|
}
|
|
1191
1236
|
}
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1237
|
+
},
|
|
1238
|
+
{ ...query, after }
|
|
1239
|
+
);
|
|
1240
|
+
this._correlation_checkpoint = last_id;
|
|
1194
1241
|
if (correlated.size) {
|
|
1195
1242
|
const streams = [...correlated.entries()].map(([stream, { source }]) => ({
|
|
1196
1243
|
stream,
|
|
1197
1244
|
source
|
|
1198
1245
|
}));
|
|
1199
|
-
const subscribed = await store().subscribe(streams);
|
|
1200
|
-
|
|
1246
|
+
const { subscribed } = await store().subscribe(streams);
|
|
1247
|
+
if (subscribed) {
|
|
1248
|
+
tracer.correlated(streams);
|
|
1249
|
+
for (const { stream } of streams) {
|
|
1250
|
+
this._subscribed_statics.add(stream);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1201
1253
|
return { subscribed, last_id };
|
|
1202
1254
|
}
|
|
1203
1255
|
return { subscribed: 0, last_id };
|
|
@@ -1260,10 +1312,8 @@ var Act = class {
|
|
|
1260
1312
|
start_correlations(query = {}, frequency = 1e4, callback) {
|
|
1261
1313
|
if (this._correlation_timer) return false;
|
|
1262
1314
|
const limit = query.limit || 100;
|
|
1263
|
-
let after = query.after || -1;
|
|
1264
1315
|
this._correlation_timer = setInterval(
|
|
1265
|
-
() => this.correlate({ ...query, after, limit }).then((result) => {
|
|
1266
|
-
after = result.last_id;
|
|
1316
|
+
() => this.correlate({ ...query, after: this._correlation_checkpoint, limit }).then((result) => {
|
|
1267
1317
|
if (callback && result.subscribed) callback(result.subscribed);
|
|
1268
1318
|
}).catch(console.error),
|
|
1269
1319
|
frequency
|
|
@@ -1346,9 +1396,13 @@ var Act = class {
|
|
|
1346
1396
|
if (this._settling) return;
|
|
1347
1397
|
this._settling = true;
|
|
1348
1398
|
(async () => {
|
|
1399
|
+
await this._init_correlation();
|
|
1349
1400
|
let lastDrain;
|
|
1350
1401
|
for (let i = 0; i < maxPasses; i++) {
|
|
1351
|
-
const { subscribed } = await this.correlate(
|
|
1402
|
+
const { subscribed } = await this.correlate({
|
|
1403
|
+
...correlateQuery,
|
|
1404
|
+
after: this._correlation_checkpoint
|
|
1405
|
+
});
|
|
1352
1406
|
if (subscribed === 0 && i > 0) break;
|
|
1353
1407
|
lastDrain = await this.drain(drainOptions);
|
|
1354
1408
|
if (!lastDrain.acked.length && !lastDrain.blocked.length) break;
|