@rotorsoft/act 1.33.16 → 1.33.18
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 +9 -2
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/in-memory-store.d.ts +1 -2
- package/dist/@types/adapters/in-memory-store.d.ts.map +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts +11 -4
- package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
- package/dist/@types/internal/drain-cycle.d.ts +4 -1
- package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
- package/dist/@types/internal/settle.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +4 -2
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/{chunk-E5H3NRCT.js → chunk-3OTABSIB.js} +29 -38
- package/dist/chunk-3OTABSIB.js.map +1 -0
- package/dist/{chunk-PMS6BMIU.cjs → chunk-N7K4FQEM.cjs} +1 -1
- package/dist/{chunk-PMS6BMIU.cjs.map → chunk-N7K4FQEM.cjs.map} +1 -1
- package/dist/{chunk-EN2KFJ7W.cjs → chunk-OYR5RIFE.cjs} +45 -54
- package/dist/chunk-OYR5RIFE.cjs.map +1 -0
- package/dist/{chunk-CAL4XEVN.js → chunk-SD7SW47Z.js} +1 -1
- package/dist/{chunk-CAL4XEVN.js.map → chunk-SD7SW47Z.js.map} +1 -1
- package/dist/index.cjs +212 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -23
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +4 -4
- package/dist/test/index.js +2 -2
- package/dist/types/index.cjs +2 -2
- package/dist/types/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-E5H3NRCT.js.map +0 -1
- package/dist/chunk-EN2KFJ7W.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
sleep,
|
|
41
41
|
store,
|
|
42
42
|
validate
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-3OTABSIB.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-
|
|
73
|
+
} from "./chunk-SD7SW47Z.js";
|
|
74
74
|
|
|
75
75
|
// src/signals.ts
|
|
76
76
|
process.once("SIGINT", async (arg) => {
|
|
@@ -1168,10 +1168,13 @@ var CorrelateCycle = class {
|
|
|
1168
1168
|
_raised = 1;
|
|
1169
1169
|
_lowered = 0;
|
|
1170
1170
|
/**
|
|
1171
|
-
* Bumped by a release (shutdown)
|
|
1172
|
-
*
|
|
1171
|
+
* Bumped by a release (shutdown), so a scan or lease reply that was out
|
|
1172
|
+
* across one writes nothing.
|
|
1173
1173
|
*/
|
|
1174
1174
|
_epoch = 0;
|
|
1175
|
+
/** Passes in flight: a restore waits for them, and refuses new ones. */
|
|
1176
|
+
_passes = /* @__PURE__ */ new Set();
|
|
1177
|
+
_restoring = false;
|
|
1175
1178
|
_init_promise;
|
|
1176
1179
|
// Bounded by `maxSubscribedStreams`; static records live apart so eviction
|
|
1177
1180
|
// never drops their +Infinity floor.
|
|
@@ -1230,14 +1233,22 @@ var CorrelateCycle = class {
|
|
|
1230
1233
|
}
|
|
1231
1234
|
await this._on_init?.();
|
|
1232
1235
|
}
|
|
1233
|
-
/**
|
|
1234
|
-
|
|
1236
|
+
/**
|
|
1237
|
+
* Replace the log with no pass in flight, then cold-start: a pass that
|
|
1238
|
+
* read the old log writes before the restore, never into the new one.
|
|
1239
|
+
*/
|
|
1240
|
+
async restart(restore) {
|
|
1241
|
+
this._restoring = true;
|
|
1242
|
+
try {
|
|
1243
|
+
await Promise.allSettled(this._passes);
|
|
1244
|
+
await restore();
|
|
1245
|
+
} finally {
|
|
1246
|
+
this._restoring = false;
|
|
1247
|
+
}
|
|
1235
1248
|
this._init_promise = void 0;
|
|
1236
1249
|
this._checkpoint = -1;
|
|
1237
1250
|
this._dynamic_subscriptions.clear();
|
|
1238
1251
|
this._static_subscriptions.clear();
|
|
1239
|
-
this._raised++;
|
|
1240
|
-
this._epoch++;
|
|
1241
1252
|
}
|
|
1242
1253
|
/** Forget dynamic targets whose rows a full close deleted, so they re-subscribe. */
|
|
1243
1254
|
forget_subscribed(streams) {
|
|
@@ -1256,6 +1267,16 @@ var CorrelateCycle = class {
|
|
|
1256
1267
|
}
|
|
1257
1268
|
/** Scan past the checkpoint, subscribe new targets and raise their work marks. */
|
|
1258
1269
|
async correlate(query, lease = false) {
|
|
1270
|
+
if (this._restoring) return { kind: "idle", last_id: this._checkpoint };
|
|
1271
|
+
const pass = this._scan(query, lease);
|
|
1272
|
+
this._passes.add(pass);
|
|
1273
|
+
try {
|
|
1274
|
+
return await pass;
|
|
1275
|
+
} finally {
|
|
1276
|
+
this._passes.delete(pass);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
async _scan(query, lease) {
|
|
1259
1280
|
await this._init();
|
|
1260
1281
|
const epoch = this._epoch;
|
|
1261
1282
|
const idle = () => ({
|
|
@@ -1275,7 +1296,7 @@ var CorrelateCycle = class {
|
|
|
1275
1296
|
this._lease_until = correlating ? now + CORRELATION_LEASE_MS : 0;
|
|
1276
1297
|
if (correlating === false) return idle();
|
|
1277
1298
|
}
|
|
1278
|
-
const after =
|
|
1299
|
+
const after = this._checkpoint;
|
|
1279
1300
|
const correlated = /* @__PURE__ */ new Map();
|
|
1280
1301
|
let last_id = after;
|
|
1281
1302
|
let stopped = false;
|
|
@@ -1349,7 +1370,7 @@ var CorrelateCycle = class {
|
|
|
1349
1370
|
},
|
|
1350
1371
|
// Resolvers see `pii: null`: correlate runs actor-less, and one
|
|
1351
1372
|
// undecryptable row would otherwise stop every stream's reactions.
|
|
1352
|
-
{
|
|
1373
|
+
{ after, limit: query.limit, with_pii: false }
|
|
1353
1374
|
);
|
|
1354
1375
|
if (this._declared_lanes.size > 1) await this._recall(correlated);
|
|
1355
1376
|
const read = last_id > after;
|
|
@@ -2408,9 +2429,11 @@ var DrainController = class {
|
|
|
2408
2429
|
get lane() {
|
|
2409
2430
|
return this._deps.lane;
|
|
2410
2431
|
}
|
|
2411
|
-
/**
|
|
2432
|
+
/**
|
|
2433
|
+
* Drains every `cycleMs` while armed; the unref'd timer never holds the
|
|
2434
|
+
* process. Called once, when the controller is built.
|
|
2435
|
+
*/
|
|
2412
2436
|
start(cycleMs) {
|
|
2413
|
-
if (this._worker || this._stopped) return;
|
|
2414
2437
|
const run = this._deps.run_scoped;
|
|
2415
2438
|
const tick = async () => {
|
|
2416
2439
|
if (this.armed) await run(() => this.drain());
|
|
@@ -2856,8 +2879,7 @@ var SettleLoop = class {
|
|
|
2856
2879
|
this._timer = void 0;
|
|
2857
2880
|
const {
|
|
2858
2881
|
debounceMs: _,
|
|
2859
|
-
|
|
2860
|
-
correlate: { after: _after, ...correlate_query } = {},
|
|
2882
|
+
correlate: correlate_query = {},
|
|
2861
2883
|
maxPasses = Infinity,
|
|
2862
2884
|
...drain_options
|
|
2863
2885
|
} = this._next ?? {};
|
|
@@ -2870,7 +2892,7 @@ var SettleLoop = class {
|
|
|
2870
2892
|
if (scanned) this._deps.breaker.passed();
|
|
2871
2893
|
const drain = await this._deps.drain(drain_options);
|
|
2872
2894
|
passes.push(drain);
|
|
2873
|
-
const made_progress = drain.leased.length > 0 || scanned &&
|
|
2895
|
+
const made_progress = drain.leased.length > 0 || scanned && pass.read;
|
|
2874
2896
|
if (!made_progress) break;
|
|
2875
2897
|
}
|
|
2876
2898
|
if (passes.length) this._deps.on_settled(merge_drains(passes));
|
|
@@ -3529,8 +3551,9 @@ var Act = class {
|
|
|
3529
3551
|
* target streams their reactions resolve to (static or computed from
|
|
3530
3552
|
* the event), and marks their work so the next drain can claim it.
|
|
3531
3553
|
*
|
|
3532
|
-
* @param query -
|
|
3533
|
-
*
|
|
3554
|
+
* @param query - Only `limit` is used: the most events the pass reads
|
|
3555
|
+
* (default 10). The scan always starts at the correlation checkpoint,
|
|
3556
|
+
* which every reaction shares, so filters and `after` are ignored.
|
|
3534
3557
|
* @returns The number of newly subscribed streams and the last scanned event id
|
|
3535
3558
|
*
|
|
3536
3559
|
* @example Manual correlation
|
|
@@ -3540,7 +3563,7 @@ var Act = class {
|
|
|
3540
3563
|
*
|
|
3541
3564
|
* @see {@link start_correlations} for automatic periodic correlation
|
|
3542
3565
|
*/
|
|
3543
|
-
async correlate(query = {
|
|
3566
|
+
async correlate(query = { limit: 10 }) {
|
|
3544
3567
|
const pass = await this._correlate_pass(query);
|
|
3545
3568
|
return {
|
|
3546
3569
|
subscribed: pass.kind === "scanned" ? pass.subscribed : 0,
|
|
@@ -3552,8 +3575,7 @@ var Act = class {
|
|
|
3552
3575
|
if (!this._drain) return { kind: "idle", last_id: -1 };
|
|
3553
3576
|
return this._scoped(async () => {
|
|
3554
3577
|
const pass = await this._correlate.correlate(query, lease);
|
|
3555
|
-
if (pass.kind === "scanned" &&
|
|
3556
|
-
this._arm_all();
|
|
3578
|
+
if (pass.kind === "scanned" && pass.marked > 0) this._arm_all();
|
|
3557
3579
|
return pass;
|
|
3558
3580
|
});
|
|
3559
3581
|
}
|
|
@@ -3694,6 +3716,12 @@ var Act = class {
|
|
|
3694
3716
|
* adapter's {@link Store.restore} driver supplies the transaction
|
|
3695
3717
|
* lifecycle and per-event insert.
|
|
3696
3718
|
*
|
|
3719
|
+
* Safe in a live process: restoring into this Act's own store waits
|
|
3720
|
+
* for its correlate passes in flight, replaces the log, then restarts
|
|
3721
|
+
* correlation and settles. A correlate pass that starts meanwhile
|
|
3722
|
+
* reads nothing. Other processes on the same store keep their
|
|
3723
|
+
* correlation state and must be restarted.
|
|
3724
|
+
*
|
|
3697
3725
|
* Throws if the adapter has no restore capability. Throws on the
|
|
3698
3726
|
* first invalid event (negative version, malformed `created`) with
|
|
3699
3727
|
* the running index in the message; atomic transaction rollback in
|
|
@@ -3736,14 +3764,15 @@ var Act = class {
|
|
|
3736
3764
|
let kept = 0;
|
|
3737
3765
|
let migrated = 0;
|
|
3738
3766
|
let dropped = { closed_streams: 0, snapshots: 0 };
|
|
3739
|
-
|
|
3767
|
+
const run = () => target.restore(async (callback) => {
|
|
3740
3768
|
const partial = await scan(source, opts, callback);
|
|
3741
3769
|
kept = partial.kept;
|
|
3742
3770
|
migrated = partial.migrated;
|
|
3743
3771
|
dropped = partial.dropped;
|
|
3744
3772
|
});
|
|
3745
|
-
if (
|
|
3746
|
-
|
|
3773
|
+
if (sink) await run();
|
|
3774
|
+
else {
|
|
3775
|
+
await this._correlate.restart(run);
|
|
3747
3776
|
this._wake();
|
|
3748
3777
|
}
|
|
3749
3778
|
return { kept, migrated, dropped, duration_ms: Date.now() - started };
|