@rotorsoft/act 1.20.0 → 1.22.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 +55 -43
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/in-memory-store.d.ts +13 -4
- package/dist/@types/adapters/in-memory-store.d.ts.map +1 -1
- package/dist/@types/builders/state-builder.d.ts +35 -9
- package/dist/@types/builders/state-builder.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-config.d.ts +39 -15
- package/dist/@types/internal/autoclose-config.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-policy.d.ts +39 -13
- package/dist/@types/internal/autoclose-policy.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-reaction.d.ts.map +1 -1
- package/dist/@types/internal/close-cycle.d.ts +5 -0
- package/dist/@types/internal/close-cycle.d.ts.map +1 -1
- package/dist/@types/internal/close-signal.d.ts +8 -0
- package/dist/@types/internal/close-signal.d.ts.map +1 -1
- package/dist/@types/internal/index.d.ts +2 -2
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/@types/internal/reactions.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +46 -13
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +29 -3
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/{chunk-TODGOWEZ.js → chunk-KBTC3NGQ.js} +64 -14
- package/dist/chunk-KBTC3NGQ.js.map +1 -0
- package/dist/index.cjs +237 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +175 -26
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +63 -13
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-TODGOWEZ.js.map +0 -1
package/dist/test/index.cjs
CHANGED
|
@@ -641,6 +641,10 @@ var InMemoryStream = class {
|
|
|
641
641
|
var InMemoryStore = class {
|
|
642
642
|
// stored events
|
|
643
643
|
_events = [];
|
|
644
|
+
// next event id — monotonic, never reused. Deletions (truncate, windowed
|
|
645
|
+
// prune) punch holes in the id sequence, so ids are NOT array indexes and
|
|
646
|
+
// NOT `_events.length`; they only stay sorted ascending in `_events`.
|
|
647
|
+
_next_id = 0;
|
|
644
648
|
// stored stream positions and other metadata
|
|
645
649
|
_streams = /* @__PURE__ */ new Map();
|
|
646
650
|
// last committed version per stream — O(1) replacement for filter-on-commit
|
|
@@ -658,11 +662,26 @@ var InMemoryStore = class {
|
|
|
658
662
|
_pii = /* @__PURE__ */ new Map();
|
|
659
663
|
_reset_indexes() {
|
|
660
664
|
this._events.length = 0;
|
|
665
|
+
this._next_id = 0;
|
|
661
666
|
this._stream_versions.clear();
|
|
662
667
|
this._max_event_id_by_stream.clear();
|
|
663
668
|
this._max_non_snap_event_id = -1;
|
|
664
669
|
this._pii.clear();
|
|
665
670
|
}
|
|
671
|
+
// First index whose event id is greater than `after`. `_events` stays
|
|
672
|
+
// sorted ascending by id (append-only commits; deletions preserve
|
|
673
|
+
// order), so id-bounded scans binary-search their start instead of
|
|
674
|
+
// assuming id === index — an invariant that truncation breaks.
|
|
675
|
+
_first_index_after(after) {
|
|
676
|
+
let lo = 0;
|
|
677
|
+
let hi = this._events.length;
|
|
678
|
+
while (lo < hi) {
|
|
679
|
+
const mid = lo + hi >>> 1;
|
|
680
|
+
if (this._events[mid].id > after) hi = mid;
|
|
681
|
+
else lo = mid + 1;
|
|
682
|
+
}
|
|
683
|
+
return lo;
|
|
684
|
+
}
|
|
666
685
|
// Attach the isolated PII payload (or null) to an event before handing it to
|
|
667
686
|
// a caller. Allocation-free for events without PII — by far the common case.
|
|
668
687
|
_with_pii(e) {
|
|
@@ -715,7 +734,7 @@ var InMemoryStore = class {
|
|
|
715
734
|
await sleep();
|
|
716
735
|
let count = 0;
|
|
717
736
|
if (query?.backward) {
|
|
718
|
-
let i = (query?.before
|
|
737
|
+
let i = (query?.before !== void 0 ? this._first_index_after(query.before - 1) : this._events.length) - 1;
|
|
719
738
|
while (i >= 0) {
|
|
720
739
|
const e = this._events[i--];
|
|
721
740
|
if (query && !this.in_query(query, e)) continue;
|
|
@@ -730,7 +749,7 @@ var InMemoryStore = class {
|
|
|
730
749
|
if (query?.limit && count >= query.limit) break;
|
|
731
750
|
}
|
|
732
751
|
} else {
|
|
733
|
-
let i = (query?.after ?? -1)
|
|
752
|
+
let i = this._first_index_after(query?.after ?? -1);
|
|
734
753
|
if (query?.with_snaps && query.stream_exact && query.stream !== void 0 && query.after === void 0) {
|
|
735
754
|
for (let j = this._events.length - 1; j >= 0; j--) {
|
|
736
755
|
const e = this._events[j];
|
|
@@ -779,7 +798,7 @@ var InMemoryStore = class {
|
|
|
779
798
|
let last_non_snap_id = -1;
|
|
780
799
|
const committed = msgs.map(({ name, data, pii }) => {
|
|
781
800
|
const c = {
|
|
782
|
-
id: this.
|
|
801
|
+
id: this._next_id++,
|
|
783
802
|
stream,
|
|
784
803
|
version,
|
|
785
804
|
created: /* @__PURE__ */ new Date(),
|
|
@@ -1120,7 +1139,7 @@ var InMemoryStore = class {
|
|
|
1120
1139
|
count++;
|
|
1121
1140
|
if (count >= limit) break;
|
|
1122
1141
|
}
|
|
1123
|
-
return { maxEventId: this._events.
|
|
1142
|
+
return { maxEventId: this._events.at(-1)?.id ?? -1, count };
|
|
1124
1143
|
}
|
|
1125
1144
|
/**
|
|
1126
1145
|
* Per-stream aggregated stats — see {@link Store.query_stats}.
|
|
@@ -1201,13 +1220,41 @@ var InMemoryStore = class {
|
|
|
1201
1220
|
}
|
|
1202
1221
|
/**
|
|
1203
1222
|
* Atomically truncates streams and seeds each with a snapshot or tombstone.
|
|
1204
|
-
*
|
|
1223
|
+
* Windowed targets (`before` set) prune the prefix below the closest safe
|
|
1224
|
+
* `__snapshot__` instead — no seed, subscriptions untouched, no-op when no
|
|
1225
|
+
* snapshot qualifies.
|
|
1226
|
+
* @param targets - Streams to truncate with optional snapshot state and meta,
|
|
1227
|
+
* or a `before`/`max_id` boundary for a windowed prefix delete.
|
|
1205
1228
|
* @returns Map keyed by stream name, each entry with `deleted` count and `committed` event.
|
|
1206
1229
|
*/
|
|
1207
1230
|
async truncate(targets) {
|
|
1208
1231
|
await sleep();
|
|
1232
|
+
const result = /* @__PURE__ */ new Map();
|
|
1233
|
+
const windowed = targets.filter((t) => t.before !== void 0);
|
|
1234
|
+
if (windowed.length) {
|
|
1235
|
+
const drop = /* @__PURE__ */ new Set();
|
|
1236
|
+
for (const { stream, before, max_id } of windowed) {
|
|
1237
|
+
let boundary;
|
|
1238
|
+
for (const e of this._events) {
|
|
1239
|
+
if (e.stream === stream && e.name === SNAP_EVENT && e.created < before && (max_id === void 0 || e.id <= max_id) && (!boundary || e.id > boundary.id))
|
|
1240
|
+
boundary = e;
|
|
1241
|
+
}
|
|
1242
|
+
if (!boundary) continue;
|
|
1243
|
+
let deleted = 0;
|
|
1244
|
+
for (const e of this._events) {
|
|
1245
|
+
if (e.stream === stream && e.id < boundary.id) {
|
|
1246
|
+
drop.add(e.id);
|
|
1247
|
+
this._pii.get(stream)?.delete(e.id);
|
|
1248
|
+
deleted++;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
result.set(stream, { deleted, committed: boundary, before });
|
|
1252
|
+
}
|
|
1253
|
+
if (drop.size) this._events = this._events.filter((e) => !drop.has(e.id));
|
|
1254
|
+
}
|
|
1255
|
+
const full = targets.filter((t) => t.before === void 0);
|
|
1209
1256
|
const deleted_counts = /* @__PURE__ */ new Map();
|
|
1210
|
-
const stream_set = new Set(
|
|
1257
|
+
const stream_set = new Set(full.map((t) => t.stream));
|
|
1211
1258
|
for (const e of this._events) {
|
|
1212
1259
|
if (stream_set.has(e.stream)) {
|
|
1213
1260
|
deleted_counts.set(e.stream, (deleted_counts.get(e.stream) ?? 0) + 1);
|
|
@@ -1218,11 +1265,11 @@ var InMemoryStore = class {
|
|
|
1218
1265
|
this._streams.delete(stream);
|
|
1219
1266
|
this._stream_versions.delete(stream);
|
|
1220
1267
|
this._max_event_id_by_stream.delete(stream);
|
|
1268
|
+
this._pii.delete(stream);
|
|
1221
1269
|
}
|
|
1222
|
-
const
|
|
1223
|
-
for (const { stream, snapshot, meta } of targets) {
|
|
1270
|
+
for (const { stream, snapshot, meta } of full) {
|
|
1224
1271
|
const event = {
|
|
1225
|
-
id: this.
|
|
1272
|
+
id: this._next_id++,
|
|
1226
1273
|
stream,
|
|
1227
1274
|
version: 0,
|
|
1228
1275
|
created: /* @__PURE__ */ new Date(),
|
|
@@ -1254,25 +1301,27 @@ var InMemoryStore = class {
|
|
|
1254
1301
|
* throw inside the driver restores the snapshot, leaving the store
|
|
1255
1302
|
* byte-for-byte unchanged from the operator's perspective.
|
|
1256
1303
|
*
|
|
1257
|
-
* `id`s are reassigned `0..N-1` as events arrive (
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1304
|
+
* `id`s are reassigned `0..N-1` as events arrive (dense — the
|
|
1305
|
+
* monotonic id counter restarts at 0 for the rebuild). `created` is
|
|
1306
|
+
* preserved verbatim from the source.
|
|
1260
1307
|
*/
|
|
1261
1308
|
async restore(driver) {
|
|
1262
1309
|
await sleep();
|
|
1263
1310
|
const prev_events = this._events;
|
|
1311
|
+
const prev_next_id = this._next_id;
|
|
1264
1312
|
const prev_streams = this._streams;
|
|
1265
1313
|
const prev_stream_versions = this._stream_versions;
|
|
1266
1314
|
const prev_max_event_id_by_stream = this._max_event_id_by_stream;
|
|
1267
1315
|
const prev_max_non_snap_event_id = this._max_non_snap_event_id;
|
|
1268
1316
|
this._events = [];
|
|
1317
|
+
this._next_id = 0;
|
|
1269
1318
|
this._streams = /* @__PURE__ */ new Map();
|
|
1270
1319
|
this._stream_versions = /* @__PURE__ */ new Map();
|
|
1271
1320
|
this._max_event_id_by_stream = /* @__PURE__ */ new Map();
|
|
1272
1321
|
this._max_non_snap_event_id = -1;
|
|
1273
1322
|
try {
|
|
1274
1323
|
await driver(async (event) => {
|
|
1275
|
-
const id = this.
|
|
1324
|
+
const id = this._next_id++;
|
|
1276
1325
|
const committed = { ...event, id };
|
|
1277
1326
|
this._events.push(committed);
|
|
1278
1327
|
this._stream_versions.set(event.stream, event.version);
|
|
@@ -1284,6 +1333,7 @@ var InMemoryStore = class {
|
|
|
1284
1333
|
});
|
|
1285
1334
|
} catch (err) {
|
|
1286
1335
|
this._events = prev_events;
|
|
1336
|
+
this._next_id = prev_next_id;
|
|
1287
1337
|
this._streams = prev_streams;
|
|
1288
1338
|
this._stream_versions = prev_stream_versions;
|
|
1289
1339
|
this._max_event_id_by_stream = prev_max_event_id_by_stream;
|