@rotorsoft/act 1.33.10 → 1.33.12

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
@@ -40,7 +40,7 @@ import {
40
40
  sleep,
41
41
  store,
42
42
  validate
43
- } from "./chunk-OCJXGHN6.js";
43
+ } from "./chunk-YZ2NKMVS.js";
44
44
  import {
45
45
  ActorSchema,
46
46
  CausationEventSchema,
@@ -70,7 +70,7 @@ import {
70
70
  pii_fields,
71
71
  pii_schemas,
72
72
  sensitive
73
- } from "./chunk-KHFMCJDR.js";
73
+ } from "./chunk-URF33KO3.js";
74
74
 
75
75
  // src/signals.ts
76
76
  process.once("SIGINT", async (arg) => {
@@ -1168,8 +1168,11 @@ var CorrelateCycle = class {
1168
1168
  */
1169
1169
  _raised = 1;
1170
1170
  _lowered = 0;
1171
- /** Counts releases, so a lease reply that lands after one is dropped. */
1172
- _releases = 0;
1171
+ /**
1172
+ * Bumped by a release (shutdown) and a restart (restore), so a scan or
1173
+ * lease reply that was out across one writes nothing.
1174
+ */
1175
+ _epoch = 0;
1173
1176
  _init_promise;
1174
1177
  // Bounded by `maxSubscribedStreams`; static records live apart so eviction
1175
1178
  // never drops their +Infinity floor.
@@ -1240,6 +1243,7 @@ var CorrelateCycle = class {
1240
1243
  this._dynamic_subscriptions.clear();
1241
1244
  this._static_subscriptions.clear();
1242
1245
  this._raised++;
1246
+ this._epoch++;
1243
1247
  }
1244
1248
  /** Forget dynamic targets whose rows a full close deleted, so they re-subscribe. */
1245
1249
  forget_subscribed(streams) {
@@ -1259,32 +1263,25 @@ var CorrelateCycle = class {
1259
1263
  /** Scan past the checkpoint, subscribe new targets and raise their work marks. */
1260
1264
  async correlate(query = { after: -1, limit: 10 }, lease = false) {
1261
1265
  await this.init();
1262
- if (this._raised === this._lowered)
1263
- return {
1264
- subscribed: 0,
1265
- last_id: this._checkpoint,
1266
- marked: 0,
1267
- scanned: false
1268
- };
1266
+ const epoch = this._epoch;
1267
+ const idle = () => ({
1268
+ subscribed: 0,
1269
+ last_id: this._checkpoint,
1270
+ marked: 0,
1271
+ scanned: false
1272
+ });
1273
+ if (this._raised === this._lowered) return idle();
1269
1274
  const raised = this._raised;
1270
1275
  const now = Date.now();
1271
1276
  if (lease && now >= this._lease_until - CORRELATION_LEASE_MS / 2) {
1272
- const releases = this._releases;
1273
1277
  const { correlating } = await this._cd.subscribe([], void 0, {
1274
1278
  key: this._key,
1275
1279
  by: this._by,
1276
1280
  millis: CORRELATION_LEASE_MS
1277
1281
  });
1278
- const released = this._releases !== releases;
1279
- if (!released)
1280
- this._lease_until = correlating ? now + CORRELATION_LEASE_MS : 0;
1281
- if (correlating === false || released)
1282
- return {
1283
- subscribed: 0,
1284
- last_id: this._checkpoint,
1285
- marked: 0,
1286
- scanned: false
1287
- };
1282
+ if (this._epoch !== epoch) return idle();
1283
+ this._lease_until = correlating ? now + CORRELATION_LEASE_MS : 0;
1284
+ if (correlating === false) return idle();
1288
1285
  }
1289
1286
  const after = Math.max(this._checkpoint, query.after || -1);
1290
1287
  const correlated = /* @__PURE__ */ new Map();
@@ -1363,6 +1360,7 @@ var CorrelateCycle = class {
1363
1360
  { ...query, after, with_pii: false }
1364
1361
  );
1365
1362
  if (this._declared_lanes.size > 1) await this._recall(correlated);
1363
+ if (this._epoch !== epoch) return idle();
1366
1364
  const streams = [];
1367
1365
  for (const [stream, entry] of correlated) {
1368
1366
  if (entry.upgraded || entry.correlated_at !== void 0)
@@ -1375,14 +1373,13 @@ var CorrelateCycle = class {
1375
1373
  });
1376
1374
  }
1377
1375
  if (streams.length) {
1378
- const held = lease && this._lease_until > 0;
1379
1376
  const renewed_at = Date.now();
1380
1377
  const { subscribed, correlating } = await this._cd.subscribe(
1381
1378
  streams,
1382
1379
  last_id,
1383
- held ? { key: this._key, by: this._by, millis: CORRELATION_LEASE_MS } : void 0
1380
+ lease ? { key: this._key, by: this._by, millis: CORRELATION_LEASE_MS } : void 0
1384
1381
  );
1385
- if (held && correlating !== false)
1382
+ if (lease && correlating !== false)
1386
1383
  this._lease_until = renewed_at + CORRELATION_LEASE_MS;
1387
1384
  const marked = streams.filter(
1388
1385
  (entry) => entry.correlated_at !== void 0
@@ -1445,7 +1442,7 @@ var CorrelateCycle = class {
1445
1442
  async release_correlation() {
1446
1443
  try {
1447
1444
  this._lease_until = 0;
1448
- this._releases++;
1445
+ this._epoch++;
1449
1446
  await this._cd.subscribe([], void 0, {
1450
1447
  key: this._key,
1451
1448
  by: this._by,
@@ -3202,9 +3199,10 @@ var Act = class {
3202
3199
  }
3203
3200
  _shutdown_promise;
3204
3201
  /**
3205
- * Per-instance teardown: stops scheduling, gives the cycles in flight up
3206
- * to `graceMs` to reach their `ack` (an abandoned handler holds its lease
3207
- * until it expires), then removes listeners and the notify subscription.
3202
+ * Per-instance teardown: stops scheduling, removes the notify
3203
+ * subscription, gives the cycles in flight up to `graceMs` to reach their
3204
+ * `ack` (an abandoned handler holds its lease until it expires), then
3205
+ * hands back the correlation lease and removes listeners.
3208
3206
  * The budget is a ceiling, not a delay.
3209
3207
  *
3210
3208
  * Idempotent: repeated calls return the same promise, with the first
@@ -3888,10 +3886,8 @@ var Act = class {
3888
3886
  * A local change that frees reaction work (a commit, `reset()`,
3889
3887
  * `unblock()`, `restore()`) schedules this on its own unless the app
3890
3888
  * sets `autoSettle: false`. Call it at startup, to run what was pending
3891
- * before a restart, or with options for the next pass. A pass already
3892
- * scheduled is never put off: calls before it runs join it (a shorter
3893
- * `debounceMs` brings it forward), and a call during a running cycle
3894
- * queues one more pass after it. Runs correlate→drain in a loop until a pass makes no
3889
+ * before a restart, or with options for the next pass; the scheduling
3890
+ * rule is in the event-sourcing docs (§ settle). Runs correlate→drain in a loop until a pass makes no
3895
3891
  * progress — no new subscriptions, no events read, no streams leased —
3896
3892
  * then emits the `"settled"` lifecycle event, so one call fully catches
3897
3893
  * up paginated streams without forcing callers to loop.