@rotorsoft/act 0.41.0 → 0.42.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 +19 -1
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/internal/close-cycle.d.ts +7 -0
- package/dist/@types/internal/close-cycle.d.ts.map +1 -1
- package/dist/@types/internal/correlator.d.ts +44 -0
- package/dist/@types/internal/correlator.d.ts.map +1 -0
- package/dist/@types/internal/event-sourcing.d.ts +10 -3
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/internal/index.d.ts +2 -1
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/@types/internal/tracing.d.ts +2 -2
- package/dist/@types/internal/tracing.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +32 -0
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/index.cjs +57 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +59 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -95,7 +95,6 @@ function classifyRegistry(registry, states) {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// src/internal/close-cycle.ts
|
|
98
|
-
import { randomUUID } from "crypto";
|
|
99
98
|
async function runCloseCycle(targets, deps) {
|
|
100
99
|
const targetMap = new Map(targets.map((t) => [t.stream, t]));
|
|
101
100
|
const streams = [...targetMap.keys()];
|
|
@@ -107,11 +106,10 @@ async function runCloseCycle(targets, deps) {
|
|
|
107
106
|
skipped
|
|
108
107
|
);
|
|
109
108
|
if (!safe.length) return { truncated: /* @__PURE__ */ new Map(), skipped };
|
|
110
|
-
const correlation = randomUUID();
|
|
111
109
|
const { guarded, guardEvents } = await guardWithTombstones(
|
|
112
110
|
safe,
|
|
113
111
|
streamInfo,
|
|
114
|
-
correlation,
|
|
112
|
+
deps.correlation,
|
|
115
113
|
deps.tombstone,
|
|
116
114
|
skipped
|
|
117
115
|
);
|
|
@@ -129,7 +127,7 @@ async function runCloseCycle(targets, deps) {
|
|
|
129
127
|
guarded,
|
|
130
128
|
seedStates,
|
|
131
129
|
guardEvents,
|
|
132
|
-
correlation
|
|
130
|
+
deps.correlation
|
|
133
131
|
);
|
|
134
132
|
return { truncated, skipped };
|
|
135
133
|
}
|
|
@@ -370,8 +368,32 @@ var CorrelateCycle = class {
|
|
|
370
368
|
}
|
|
371
369
|
};
|
|
372
370
|
|
|
371
|
+
// src/internal/correlator.ts
|
|
372
|
+
import { randomInt } from "crypto";
|
|
373
|
+
var BASE = 36;
|
|
374
|
+
var SEG_WIDTH = 4;
|
|
375
|
+
var SEG_SPACE = BASE ** SEG_WIDTH;
|
|
376
|
+
function seg(n) {
|
|
377
|
+
return n.toString(BASE).padStart(SEG_WIDTH, "0");
|
|
378
|
+
}
|
|
379
|
+
var defaultCorrelator = ({ state: state2, action: action2 }) => {
|
|
380
|
+
const s = state2.slice(0, SEG_WIDTH).toLowerCase();
|
|
381
|
+
const a = action2.slice(0, SEG_WIDTH).toLowerCase();
|
|
382
|
+
const ts = seg(Date.now() % SEG_SPACE);
|
|
383
|
+
const rnd = seg(randomInt(SEG_SPACE));
|
|
384
|
+
return `${s}-${a}-${ts}${rnd}`;
|
|
385
|
+
};
|
|
386
|
+
function closeCorrelation(correlator, actor) {
|
|
387
|
+
return correlator({
|
|
388
|
+
state: "$close",
|
|
389
|
+
action: "close",
|
|
390
|
+
stream: "$close",
|
|
391
|
+
actor
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
373
395
|
// src/internal/drain-cycle.ts
|
|
374
|
-
import { randomUUID
|
|
396
|
+
import { randomUUID } from "crypto";
|
|
375
397
|
|
|
376
398
|
// src/internal/drain-ratio.ts
|
|
377
399
|
var RATIO_MIN = 0.2;
|
|
@@ -393,7 +415,7 @@ function computeLagLeadRatio(handled, lagging, leading) {
|
|
|
393
415
|
|
|
394
416
|
// src/internal/drain-cycle.ts
|
|
395
417
|
async function runDrainCycle(ops, registry, batchHandlers, handle, handleBatch, lagging, leading, eventLimit, leaseMillis, isDeferred) {
|
|
396
|
-
const leased = await ops.claim(lagging, leading,
|
|
418
|
+
const leased = await ops.claim(lagging, leading, randomUUID(), leaseMillis);
|
|
397
419
|
if (!leased.length) return void 0;
|
|
398
420
|
const active = isDeferred ? leased.filter((l) => !isDeferred(l.stream)) : leased;
|
|
399
421
|
if (!active.length) {
|
|
@@ -912,7 +934,6 @@ var block = (leases) => store().block(leases);
|
|
|
912
934
|
var subscribe = (streams) => store().subscribe(streams);
|
|
913
935
|
|
|
914
936
|
// src/internal/event-sourcing.ts
|
|
915
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
916
937
|
import { patch } from "@rotorsoft/act-patch";
|
|
917
938
|
async function snap(snapshot) {
|
|
918
939
|
try {
|
|
@@ -1000,7 +1021,7 @@ async function load(me, stream, callback, asOf) {
|
|
|
1000
1021
|
}
|
|
1001
1022
|
return { event, state: state2, version, patches, snaps, cache_hit, replayed };
|
|
1002
1023
|
}
|
|
1003
|
-
async function action(me, action2, target, payload, reactingTo, skipValidation = false) {
|
|
1024
|
+
async function action(me, action2, target, payload, reactingTo, skipValidation = false, correlator = defaultCorrelator) {
|
|
1004
1025
|
const { stream, expectedVersion, actor } = target;
|
|
1005
1026
|
if (!stream) throw new Error("Missing target stream");
|
|
1006
1027
|
const validated = skipValidation ? payload : validate(action2, payload, me.actions[action2]);
|
|
@@ -1046,7 +1067,12 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
1046
1067
|
data: skipValidation ? data : validate(name, data, me.events[name])
|
|
1047
1068
|
}));
|
|
1048
1069
|
const meta = {
|
|
1049
|
-
correlation: reactingTo?.meta.correlation ||
|
|
1070
|
+
correlation: reactingTo?.meta.correlation || correlator({
|
|
1071
|
+
action: action2,
|
|
1072
|
+
state: me.name,
|
|
1073
|
+
stream,
|
|
1074
|
+
actor: target.actor
|
|
1075
|
+
}),
|
|
1050
1076
|
causation: {
|
|
1051
1077
|
action: {
|
|
1052
1078
|
name: action2,
|
|
@@ -1150,12 +1176,21 @@ var traced = (inner, exit, entry) => (async (...args) => {
|
|
|
1150
1176
|
exit?.(result, ...args);
|
|
1151
1177
|
return result;
|
|
1152
1178
|
});
|
|
1153
|
-
function buildEs(logger) {
|
|
1179
|
+
function buildEs(logger, correlator = defaultCorrelator) {
|
|
1180
|
+
const boundAction = (me, actionName, target, payload, reactingTo, skipValidation = false) => action(
|
|
1181
|
+
me,
|
|
1182
|
+
actionName,
|
|
1183
|
+
target,
|
|
1184
|
+
payload,
|
|
1185
|
+
reactingTo,
|
|
1186
|
+
skipValidation,
|
|
1187
|
+
correlator
|
|
1188
|
+
);
|
|
1154
1189
|
if (logger.level !== "trace") {
|
|
1155
1190
|
return {
|
|
1156
1191
|
snap,
|
|
1157
1192
|
load,
|
|
1158
|
-
action,
|
|
1193
|
+
action: boundAction,
|
|
1159
1194
|
tombstone
|
|
1160
1195
|
};
|
|
1161
1196
|
}
|
|
@@ -1185,7 +1220,7 @@ function buildEs(logger) {
|
|
|
1185
1220
|
);
|
|
1186
1221
|
}),
|
|
1187
1222
|
action: traced(
|
|
1188
|
-
|
|
1223
|
+
boundAction,
|
|
1189
1224
|
(snapshots, _me, _action, target) => {
|
|
1190
1225
|
const committed = snapshots.filter((s) => s.event);
|
|
1191
1226
|
if (committed.length) {
|
|
@@ -1293,7 +1328,8 @@ var Act = class {
|
|
|
1293
1328
|
this._states = _states;
|
|
1294
1329
|
this._batch_handlers = batchHandlers;
|
|
1295
1330
|
this._scoped = options.scoped ? (fn) => scoped.run(options.scoped, fn) : (fn) => fn();
|
|
1296
|
-
this.
|
|
1331
|
+
this._correlator = options.correlator ?? defaultCorrelator;
|
|
1332
|
+
this._es = buildEs(this._logger, this._correlator);
|
|
1297
1333
|
this._cd = buildDrain(this._logger);
|
|
1298
1334
|
this._handle = buildHandle({
|
|
1299
1335
|
logger: this._logger,
|
|
@@ -1406,6 +1442,13 @@ var Act = class {
|
|
|
1406
1442
|
* path keeps reading fresh `store()`/`cache()` per call, which matters for
|
|
1407
1443
|
* tests that dispose and re-seed mid-suite. */
|
|
1408
1444
|
_scoped;
|
|
1445
|
+
/**
|
|
1446
|
+
* Correlation-id generator for originating actions. Bound at
|
|
1447
|
+
* construction from `options.correlator ?? defaultCorrelator`. The
|
|
1448
|
+
* `do()` path passes this into the `_es.action` closure; close-cycle
|
|
1449
|
+
* uses it via {@link closeCorrelation}.
|
|
1450
|
+
*/
|
|
1451
|
+
_correlator;
|
|
1409
1452
|
/** Pre-bound IAct methods reused across drain cycles. Only `do` varies per
|
|
1410
1453
|
* payload (it captures the triggering event for reactingTo auto-inject). */
|
|
1411
1454
|
_bound_do = this.do.bind(this);
|
|
@@ -1966,12 +2009,14 @@ var Act = class {
|
|
|
1966
2009
|
if (!targets.length) return { truncated: /* @__PURE__ */ new Map(), skipped: [] };
|
|
1967
2010
|
return this._scoped(async () => {
|
|
1968
2011
|
await this.correlate({ limit: 1e3 });
|
|
2012
|
+
const closeActor = { id: "$close", name: "close" };
|
|
1969
2013
|
const result = await runCloseCycle(targets, {
|
|
1970
2014
|
reactiveEventsSize: this._reactive_events.size,
|
|
1971
2015
|
eventToState: this._event_to_state,
|
|
1972
2016
|
load: this._es.load,
|
|
1973
2017
|
tombstone: this._es.tombstone,
|
|
1974
|
-
logger: this._logger
|
|
2018
|
+
logger: this._logger,
|
|
2019
|
+
correlation: closeCorrelation(this._correlator, closeActor)
|
|
1975
2020
|
});
|
|
1976
2021
|
this.emit("closed", result);
|
|
1977
2022
|
return result;
|