@rotorsoft/act 1.8.0 → 1.9.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/index.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  sleep,
20
20
  store,
21
21
  validate
22
- } from "./chunk-I4L224TZ.js";
22
+ } from "./chunk-F4S2JOPN.js";
23
23
  import {
24
24
  ActorSchema,
25
25
  CausationEventSchema,
@@ -4460,11 +4460,24 @@ var InMemoryStore = class {
4460
4460
  _maxEventIdByStream = /* @__PURE__ */ new Map();
4461
4461
  // global max non-snapshot event id — fast pre-check for source-less streams in claim()
4462
4462
  _maxNonSnapEventId = -1;
4463
+ // stream → (event_id → cloned sensitive payload). Two-level so `forget_pii`
4464
+ // is O(1) — drop the inner Map for the stream and the wipe is done — mirroring
4465
+ // the `DELETE WHERE stream = ?` scope that durable adapters get from their
4466
+ // stream index. Entries exist only for events committed with a non-null
4467
+ // `pii` field; absence means "no PII" (returned as `null` on load).
4468
+ _pii = /* @__PURE__ */ new Map();
4463
4469
  _resetIndexes() {
4464
4470
  this._events.length = 0;
4465
4471
  this._streamVersions.clear();
4466
4472
  this._maxEventIdByStream.clear();
4467
4473
  this._maxNonSnapEventId = -1;
4474
+ this._pii.clear();
4475
+ }
4476
+ // Attach the isolated PII payload (or null) to an event before handing it to
4477
+ // a caller. Allocation-free for events without PII — by far the common case.
4478
+ _withPii(e) {
4479
+ const pii = this._pii.get(e.stream)?.get(e.id);
4480
+ return pii ? { ...e, pii } : e;
4468
4481
  }
4469
4482
  /**
4470
4483
  * Dispose of the store and clear all events.
@@ -4520,7 +4533,9 @@ var InMemoryStore = class {
4520
4533
  continue;
4521
4534
  if (query.after && e.id <= query.after) break;
4522
4535
  if (query.created_after && e.created <= query.created_after) break;
4523
- await Promise.resolve(callback(e));
4536
+ await Promise.resolve(
4537
+ callback(this._withPii(e))
4538
+ );
4524
4539
  count++;
4525
4540
  if (query?.limit && count >= query.limit) break;
4526
4541
  }
@@ -4532,7 +4547,9 @@ var InMemoryStore = class {
4532
4547
  if (query?.created_after && e.created <= query.created_after) continue;
4533
4548
  if (query?.before && e.id >= query.before) break;
4534
4549
  if (query?.created_before && e.created >= query.created_before) break;
4535
- await Promise.resolve(callback(e));
4550
+ await Promise.resolve(
4551
+ callback(this._withPii(e))
4552
+ );
4536
4553
  count++;
4537
4554
  if (query?.limit && count >= query.limit) break;
4538
4555
  }
@@ -4561,7 +4578,7 @@ var InMemoryStore = class {
4561
4578
  }
4562
4579
  let version = currentVersion + 1;
4563
4580
  let lastNonSnapId = -1;
4564
- const committed = msgs.map(({ name, data }) => {
4581
+ const committed = msgs.map(({ name, data, pii }) => {
4565
4582
  const c = {
4566
4583
  id: this._events.length,
4567
4584
  stream,
@@ -4572,9 +4589,17 @@ var InMemoryStore = class {
4572
4589
  meta
4573
4590
  };
4574
4591
  this._events.push(c);
4592
+ if (pii != null) {
4593
+ let perStream = this._pii.get(stream);
4594
+ if (!perStream) {
4595
+ perStream = /* @__PURE__ */ new Map();
4596
+ this._pii.set(stream, perStream);
4597
+ }
4598
+ perStream.set(c.id, structuredClone(pii));
4599
+ }
4575
4600
  if (name !== SNAP_EVENT) lastNonSnapId = c.id;
4576
4601
  version++;
4577
- return c;
4602
+ return this._withPii(c);
4578
4603
  });
4579
4604
  this._streamVersions.set(stream, version - 1);
4580
4605
  if (lastNonSnapId >= 0) {
@@ -4755,6 +4780,21 @@ var InMemoryStore = class {
4755
4780
  * @param input - Stream names or a filter selecting the streams to unblock.
4756
4781
  * @returns Count of streams that were actually flipped (were blocked).
4757
4782
  */
4783
+ /**
4784
+ * Wipe the sensitive-data payload for every event on the stream — see
4785
+ * {@link Store.forget_pii}. O(1) drop of the stream's inner Map; the size of
4786
+ * that Map is the count of events that had PII. Idempotent: a second call
4787
+ * finds no inner Map and returns `0`.
4788
+ *
4789
+ * @param stream - Target stream.
4790
+ * @returns Count of events whose isolated PII payload was deleted.
4791
+ */
4792
+ async forget_pii(stream) {
4793
+ await sleep();
4794
+ const count = this._pii.get(stream)?.size ?? 0;
4795
+ this._pii.delete(stream);
4796
+ return count;
4797
+ }
4758
4798
  async unblock(input) {
4759
4799
  await sleep();
4760
4800
  let count = 0;