@rotorsoft/act 0.23.0 → 0.23.2

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/index.js CHANGED
@@ -222,21 +222,19 @@ var InMemoryStream = class {
222
222
  * @returns The granted lease or undefined if blocked.
223
223
  */
224
224
  lease(lease, millis) {
225
- if (this.is_avaliable) {
226
- if (millis > 0) {
227
- this._leased_by = lease.by;
228
- this._leased_until = new Date(Date.now() + millis);
229
- this._retry = this._retry + 1;
230
- }
231
- return {
232
- stream: this.stream,
233
- source: this.source,
234
- at: lease.at,
235
- by: lease.by,
236
- retry: this._retry,
237
- lagging: lease.lagging
238
- };
225
+ if (millis > 0) {
226
+ this._leased_by = lease.by;
227
+ this._leased_until = new Date(Date.now() + millis);
239
228
  }
229
+ this._retry = this._retry + 1;
230
+ return {
231
+ stream: this.stream,
232
+ source: this.source,
233
+ at: lease.at,
234
+ by: lease.by,
235
+ retry: this._retry,
236
+ lagging: lease.lagging
237
+ };
240
238
  }
241
239
  /**
242
240
  * Acknowledge completion of processing for this stream.
@@ -737,13 +735,18 @@ var Act = class {
737
735
  this.registry = registry;
738
736
  this._states = _states;
739
737
  const statics = [];
740
- for (const register of Object.values(this.registry.events)) {
738
+ for (const [name, register] of Object.entries(this.registry.events)) {
739
+ if (register.reactions.size > 0) {
740
+ this._reactive_events.add(name);
741
+ }
741
742
  for (const reaction of register.reactions.values()) {
742
743
  if (typeof reaction.resolver === "function") {
743
744
  this._has_dynamic_resolvers = true;
744
- } else if (reaction.resolver) {
745
- const r = reaction.resolver;
746
- statics.push({ stream: r.target, source: r.source });
745
+ } else {
746
+ statics.push({
747
+ stream: reaction.resolver.target,
748
+ source: reaction.resolver.source
749
+ });
747
750
  }
748
751
  }
749
752
  }
@@ -765,6 +768,10 @@ var Act = class {
765
768
  _subscribed_statics = /* @__PURE__ */ new Set();
766
769
  _has_dynamic_resolvers = false;
767
770
  _correlation_initialized = false;
771
+ /** Event names with at least one registered reaction (computed at build time) */
772
+ _reactive_events = /* @__PURE__ */ new Set();
773
+ /** Set in do() when a committed event has reactions — cleared by drain() */
774
+ _needs_drain = false;
768
775
  emit(event, args) {
769
776
  return this._emitter.emit(event, args);
770
777
  }
@@ -876,6 +883,12 @@ var Act = class {
876
883
  reactingTo,
877
884
  skipValidation
878
885
  );
886
+ for (const snap2 of snapshots) {
887
+ if (snap2.event?.name && this._reactive_events.has(snap2.event.name)) {
888
+ this._needs_drain = true;
889
+ break;
890
+ }
891
+ }
879
892
  this.emit("committed", snapshots);
880
893
  return snapshots;
881
894
  }
@@ -1063,6 +1076,9 @@ var Act = class {
1063
1076
  eventLimit = 10,
1064
1077
  leaseMillis = 1e4
1065
1078
  } = {}) {
1079
+ if (!this._needs_drain) {
1080
+ return { fetched: [], leased: [], acked: [], blocked: [] };
1081
+ }
1066
1082
  if (!this._drain_locked) {
1067
1083
  try {
1068
1084
  this._drain_locked = true;
@@ -1074,8 +1090,10 @@ var Act = class {
1074
1090
  randomUUID2(),
1075
1091
  leaseMillis
1076
1092
  );
1077
- if (!leased.length)
1093
+ if (!leased.length) {
1094
+ this._needs_drain = false;
1078
1095
  return { fetched: [], leased: [], acked: [], blocked: [] };
1096
+ }
1079
1097
  const fetched = await Promise.all(
1080
1098
  leased.map(async ({ stream, source, at, lagging: lagging2 }) => {
1081
1099
  const events = await this.query_array({
@@ -1110,7 +1128,7 @@ var Act = class {
1110
1128
  const at = streamFetch?.events.at(-1)?.id || fetch_window_at;
1111
1129
  return this.handle(
1112
1130
  { ...lease, at },
1113
- payloadsMap.get(lease.stream) || []
1131
+ payloadsMap.get(lease.stream)
1114
1132
  );
1115
1133
  })
1116
1134
  );
@@ -1139,7 +1157,11 @@ var Act = class {
1139
1157
  tracer.blocked(blocked);
1140
1158
  this.emit("blocked", blocked);
1141
1159
  }
1142
- return { fetched, leased, acked, blocked };
1160
+ const result = { fetched, leased, acked, blocked };
1161
+ const hasErrors = handled.some(({ error }) => error);
1162
+ if (!acked.length && !blocked.length && !hasErrors)
1163
+ this._needs_drain = false;
1164
+ return result;
1143
1165
  } catch (error) {
1144
1166
  logger.error(error);
1145
1167
  } finally {
@@ -1205,6 +1227,7 @@ var Act = class {
1205
1227
  this._correlation_initialized = true;
1206
1228
  const { watermark } = await store().subscribe(this._static_targets);
1207
1229
  this._correlation_checkpoint = watermark;
1230
+ if (this._reactive_events.size > 0) this._needs_drain = true;
1208
1231
  for (const { stream } of this._static_targets) {
1209
1232
  this._subscribed_statics.add(stream);
1210
1233
  }
@@ -1241,13 +1264,13 @@ var Act = class {
1241
1264
  },
1242
1265
  { ...query, after }
1243
1266
  );
1244
- this._correlation_checkpoint = last_id;
1245
1267
  if (correlated.size) {
1246
1268
  const streams = [...correlated.entries()].map(([stream, { source }]) => ({
1247
1269
  stream,
1248
1270
  source
1249
1271
  }));
1250
1272
  const { subscribed } = await store().subscribe(streams);
1273
+ this._correlation_checkpoint = last_id;
1251
1274
  if (subscribed) {
1252
1275
  tracer.correlated(streams);
1253
1276
  for (const { stream } of streams) {
@@ -1256,6 +1279,7 @@ var Act = class {
1256
1279
  }
1257
1280
  return { subscribed, last_id };
1258
1281
  }
1282
+ this._correlation_checkpoint = last_id;
1259
1283
  return { subscribed: 0, last_id };
1260
1284
  }
1261
1285
  /**
@@ -1369,7 +1393,7 @@ var Act = class {
1369
1393
  * @param options - Settle configuration options
1370
1394
  * @param options.debounceMs - Debounce window in milliseconds (default: 10)
1371
1395
  * @param options.correlate - Query filter for correlation scans (default: `{ after: -1, limit: 100 }`)
1372
- * @param options.maxPasses - Maximum correlate→drain loops (default: 5)
1396
+ * @param options.maxPasses - Maximum correlate→drain loops (default: 1)
1373
1397
  * @param options.streamLimit - Maximum streams per drain cycle (default: 10)
1374
1398
  * @param options.eventLimit - Maximum events per stream (default: 10)
1375
1399
  * @param options.leaseMillis - Lease duration in milliseconds (default: 10000)
@@ -1391,7 +1415,7 @@ var Act = class {
1391
1415
  const {
1392
1416
  debounceMs = 10,
1393
1417
  correlate: correlateQuery = { after: -1, limit: 100 },
1394
- maxPasses = 5,
1418
+ maxPasses = 1,
1395
1419
  ...drainOptions
1396
1420
  } = options;
1397
1421
  if (this._settle_timer) clearTimeout(this._settle_timer);