@rotorsoft/act 1.23.4 → 1.23.6

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.cjs CHANGED
@@ -740,11 +740,12 @@ var InMemoryStream = class {
740
740
  if (this._leased_by === lease.by) {
741
741
  this._leased_by = void 0;
742
742
  this._leased_until = void 0;
743
- this._retry = -1;
744
743
  if (lease.due !== void 0) {
744
+ this._retry = lease.retry;
745
745
  this._deferred_at = lease.due;
746
746
  return void 0;
747
747
  }
748
+ this._retry = -1;
748
749
  this._at = lease.at;
749
750
  this._deferred_at = void 0;
750
751
  return {
@@ -906,7 +907,18 @@ var InMemoryStore = class {
906
907
  async query(callback, query) {
907
908
  await sleep();
908
909
  let count = 0;
910
+ let floor_index = -1;
911
+ if (query?.with_snaps && query.stream_exact && query.stream !== void 0 && query.after === void 0) {
912
+ for (let j = this._events.length - 1; j >= 0; j--) {
913
+ const e = this._events[j];
914
+ if (e.stream === query.stream && e.name === SNAP_EVENT) {
915
+ floor_index = j;
916
+ break;
917
+ }
918
+ }
919
+ }
909
920
  if (query?.backward) {
921
+ const floor_id = floor_index >= 0 ? this._events[floor_index].id : -1;
910
922
  let i = (query?.before !== void 0 ? this._first_index_after(query.before - 1) : this._events.length) - 1;
911
923
  while (i >= 0) {
912
924
  const e = this._events[i--];
@@ -914,6 +926,7 @@ var InMemoryStore = class {
914
926
  if (query?.created_before && e.created >= query.created_before)
915
927
  continue;
916
928
  if (query.after !== void 0 && e.id <= query.after) break;
929
+ if (floor_id >= 0 && e.id < floor_id) break;
917
930
  if (query.created_after && e.created <= query.created_after) continue;
918
931
  await Promise.resolve(
919
932
  callback(this._with_pii(e))
@@ -922,16 +935,7 @@ var InMemoryStore = class {
922
935
  if (query?.limit && count >= query.limit) break;
923
936
  }
924
937
  } else {
925
- let i = this._first_index_after(query?.after ?? -1);
926
- if (query?.with_snaps && query.stream_exact && query.stream !== void 0 && query.after === void 0 && query.created_before === void 0 && query.created_after === void 0) {
927
- for (let j = this._events.length - 1; j >= 0; j--) {
928
- const e = this._events[j];
929
- if (e.stream === query.stream && e.name === SNAP_EVENT) {
930
- i = j;
931
- break;
932
- }
933
- }
934
- }
938
+ let i = floor_index >= 0 ? floor_index : this._first_index_after(query?.after ?? -1);
935
939
  while (i < this._events.length) {
936
940
  const e = this._events[i++];
937
941
  if (query && !this.in_query(query, e)) continue;
@@ -3502,7 +3506,14 @@ async function load(me, target, callback, patch_fn = bare_patch) {
3502
3506
  {
3503
3507
  stream,
3504
3508
  stream_exact: true,
3505
- ...cached ? { after: cached.event_id } : { with_snaps: true, ...asOf }
3509
+ // The snapshot resume floor is a current-state optimization: it only
3510
+ // holds when the load has no window of its own. `time_travel` already
3511
+ // captures that (any `asOf` bound set), so request `with_snaps` only for
3512
+ // a non-time-travel cold load — a bounded load full-scans real events
3513
+ // under its `asOf` filter. This is the single floor-eligibility decision
3514
+ // for the whole system; the stores apply the floor whenever asked and
3515
+ // never re-derive it (RFC 1274). The warm path resumes from `after`.
3516
+ ...cached ? { after: cached.event_id } : { ...time_travel ? {} : { with_snaps: true }, ...asOf }
3506
3517
  }
3507
3518
  );
3508
3519
  const head_is_tombstone = event?.name === TOMBSTONE_EVENT;
@@ -3844,7 +3855,7 @@ function trace_cycle(logger, leased, fetched, handled, acked, blocked) {
3844
3855
  }
3845
3856
 
3846
3857
  // src/internal/drain-cycle.ts
3847
- async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_batch, lagging, leading, eventLimit, leaseMillis, is_deferred, lane) {
3858
+ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_batch, lagging, leading, eventLimit, leaseMillis, lane) {
3848
3859
  const leased = await ops.claim(
3849
3860
  lagging,
3850
3861
  leading,
@@ -3853,18 +3864,7 @@ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_bat
3853
3864
  lane
3854
3865
  );
3855
3866
  if (!leased.length) return void 0;
3856
- const active = is_deferred ? leased.filter((l) => !is_deferred(l.stream)) : leased;
3857
- if (!active.length) {
3858
- return {
3859
- leased,
3860
- fetched: [],
3861
- handled: [],
3862
- acked: [],
3863
- blocked: [],
3864
- closeable: []
3865
- };
3866
- }
3867
- const fetched = await ops.fetch(active, eventLimit);
3867
+ const fetched = await ops.fetch(leased, eventLimit);
3868
3868
  const fetch_map = /* @__PURE__ */ new Map();
3869
3869
  const fetch_window_at = fetched.reduce(
3870
3870
  (max, { at, events }) => Math.max(max, events.at(-1)?.id || at),
@@ -3883,7 +3883,7 @@ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_bat
3883
3883
  fetch_map.set(stream, { fetch: f, payloads });
3884
3884
  }
3885
3885
  const handled = await Promise.all(
3886
- active.map((lease) => {
3886
+ leased.map((lease) => {
3887
3887
  const entry = fetch_map.get(lease.stream);
3888
3888
  const at = entry.fetch.events.at(-1)?.id || fetch_window_at;
3889
3889
  const { payloads } = entry;
@@ -3896,7 +3896,7 @@ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_bat
3896
3896
  );
3897
3897
  const acked = await ops.ack(
3898
3898
  handled.flatMap(
3899
- (h) => h.defer !== void 0 ? { ...h.lease, due: h.defer } : h.handled > 0 || !h.error ? { ...h.lease, at: h.acked_at } : []
3899
+ (h) => h.defer !== void 0 ? { ...h.lease, due: h.defer, retry: -1 } : h.handled > 0 || !h.error ? { ...h.lease, at: h.acked_at } : h.next_attempt_at !== void 0 ? { ...h.lease, due: h.next_attempt_at } : []
3900
3900
  )
3901
3901
  );
3902
3902
  const blocked = await ops.block(
@@ -4019,7 +4019,6 @@ var DrainController = class {
4019
4019
  leading,
4020
4020
  eventLimit,
4021
4021
  leaseMillis,
4022
- this._defer.size > 0 ? this._defer.is_deferred : void 0,
4023
4022
  this._deps.lane
4024
4023
  );
4025
4024
  this._deps.breaker.passed();