@rotorsoft/act 0.23.1 → 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.cjs CHANGED
@@ -291,21 +291,19 @@ var InMemoryStream = class {
291
291
  * @returns The granted lease or undefined if blocked.
292
292
  */
293
293
  lease(lease, millis) {
294
- if (this.is_avaliable) {
295
- if (millis > 0) {
296
- this._leased_by = lease.by;
297
- this._leased_until = new Date(Date.now() + millis);
298
- this._retry = this._retry + 1;
299
- }
300
- return {
301
- stream: this.stream,
302
- source: this.source,
303
- at: lease.at,
304
- by: lease.by,
305
- retry: this._retry,
306
- lagging: lease.lagging
307
- };
294
+ if (millis > 0) {
295
+ this._leased_by = lease.by;
296
+ this._leased_until = new Date(Date.now() + millis);
308
297
  }
298
+ this._retry = this._retry + 1;
299
+ return {
300
+ stream: this.stream,
301
+ source: this.source,
302
+ at: lease.at,
303
+ by: lease.by,
304
+ retry: this._retry,
305
+ lagging: lease.lagging
306
+ };
309
307
  }
310
308
  /**
311
309
  * Acknowledge completion of processing for this stream.
@@ -806,13 +804,18 @@ var Act = class {
806
804
  this.registry = registry;
807
805
  this._states = _states;
808
806
  const statics = [];
809
- for (const register of Object.values(this.registry.events)) {
807
+ for (const [name, register] of Object.entries(this.registry.events)) {
808
+ if (register.reactions.size > 0) {
809
+ this._reactive_events.add(name);
810
+ }
810
811
  for (const reaction of register.reactions.values()) {
811
812
  if (typeof reaction.resolver === "function") {
812
813
  this._has_dynamic_resolvers = true;
813
- } else if (reaction.resolver) {
814
- const r = reaction.resolver;
815
- statics.push({ stream: r.target, source: r.source });
814
+ } else {
815
+ statics.push({
816
+ stream: reaction.resolver.target,
817
+ source: reaction.resolver.source
818
+ });
816
819
  }
817
820
  }
818
821
  }
@@ -834,6 +837,10 @@ var Act = class {
834
837
  _subscribed_statics = /* @__PURE__ */ new Set();
835
838
  _has_dynamic_resolvers = false;
836
839
  _correlation_initialized = false;
840
+ /** Event names with at least one registered reaction (computed at build time) */
841
+ _reactive_events = /* @__PURE__ */ new Set();
842
+ /** Set in do() when a committed event has reactions — cleared by drain() */
843
+ _needs_drain = false;
837
844
  emit(event, args) {
838
845
  return this._emitter.emit(event, args);
839
846
  }
@@ -945,6 +952,12 @@ var Act = class {
945
952
  reactingTo,
946
953
  skipValidation
947
954
  );
955
+ for (const snap2 of snapshots) {
956
+ if (snap2.event?.name && this._reactive_events.has(snap2.event.name)) {
957
+ this._needs_drain = true;
958
+ break;
959
+ }
960
+ }
948
961
  this.emit("committed", snapshots);
949
962
  return snapshots;
950
963
  }
@@ -1132,6 +1145,9 @@ var Act = class {
1132
1145
  eventLimit = 10,
1133
1146
  leaseMillis = 1e4
1134
1147
  } = {}) {
1148
+ if (!this._needs_drain) {
1149
+ return { fetched: [], leased: [], acked: [], blocked: [] };
1150
+ }
1135
1151
  if (!this._drain_locked) {
1136
1152
  try {
1137
1153
  this._drain_locked = true;
@@ -1143,8 +1159,10 @@ var Act = class {
1143
1159
  (0, import_crypto2.randomUUID)(),
1144
1160
  leaseMillis
1145
1161
  );
1146
- if (!leased.length)
1162
+ if (!leased.length) {
1163
+ this._needs_drain = false;
1147
1164
  return { fetched: [], leased: [], acked: [], blocked: [] };
1165
+ }
1148
1166
  const fetched = await Promise.all(
1149
1167
  leased.map(async ({ stream, source, at, lagging: lagging2 }) => {
1150
1168
  const events = await this.query_array({
@@ -1179,7 +1197,7 @@ var Act = class {
1179
1197
  const at = streamFetch?.events.at(-1)?.id || fetch_window_at;
1180
1198
  return this.handle(
1181
1199
  { ...lease, at },
1182
- payloadsMap.get(lease.stream) || []
1200
+ payloadsMap.get(lease.stream)
1183
1201
  );
1184
1202
  })
1185
1203
  );
@@ -1208,7 +1226,11 @@ var Act = class {
1208
1226
  tracer.blocked(blocked);
1209
1227
  this.emit("blocked", blocked);
1210
1228
  }
1211
- return { fetched, leased, acked, blocked };
1229
+ const result = { fetched, leased, acked, blocked };
1230
+ const hasErrors = handled.some(({ error }) => error);
1231
+ if (!acked.length && !blocked.length && !hasErrors)
1232
+ this._needs_drain = false;
1233
+ return result;
1212
1234
  } catch (error) {
1213
1235
  logger.error(error);
1214
1236
  } finally {
@@ -1274,6 +1296,7 @@ var Act = class {
1274
1296
  this._correlation_initialized = true;
1275
1297
  const { watermark } = await store().subscribe(this._static_targets);
1276
1298
  this._correlation_checkpoint = watermark;
1299
+ if (this._reactive_events.size > 0) this._needs_drain = true;
1277
1300
  for (const { stream } of this._static_targets) {
1278
1301
  this._subscribed_statics.add(stream);
1279
1302
  }
@@ -1439,7 +1462,7 @@ var Act = class {
1439
1462
  * @param options - Settle configuration options
1440
1463
  * @param options.debounceMs - Debounce window in milliseconds (default: 10)
1441
1464
  * @param options.correlate - Query filter for correlation scans (default: `{ after: -1, limit: 100 }`)
1442
- * @param options.maxPasses - Maximum correlate→drain loops (default: 5)
1465
+ * @param options.maxPasses - Maximum correlate→drain loops (default: 1)
1443
1466
  * @param options.streamLimit - Maximum streams per drain cycle (default: 10)
1444
1467
  * @param options.eventLimit - Maximum events per stream (default: 10)
1445
1468
  * @param options.leaseMillis - Lease duration in milliseconds (default: 10000)
@@ -1461,7 +1484,7 @@ var Act = class {
1461
1484
  const {
1462
1485
  debounceMs = 10,
1463
1486
  correlate: correlateQuery = { after: -1, limit: 100 },
1464
- maxPasses = 5,
1487
+ maxPasses = 1,
1465
1488
  ...drainOptions
1466
1489
  } = options;
1467
1490
  if (this._settle_timer) clearTimeout(this._settle_timer);