@unicitylabs/sphere-sdk 0.14.11-dev.8 → 0.14.11

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.
@@ -12978,22 +12978,24 @@ var Receive = class {
12978
12978
  * the tokens just accepted, and the balance would still only move at the end.
12979
12979
  * Ordering is preserved: store() still precedes the ack (§5.7).
12980
12980
  */
12981
- async maybeRefresh(deps, pending, epochOf) {
12981
+ async maybeRefresh(ctx) {
12982
+ const { deps, pending, pageEpoch } = ctx;
12982
12983
  if (deps.refreshView === void 0) return;
12983
12984
  const now = deps.now?.() ?? Date.now();
12984
12985
  if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
12985
12986
  this.lastRefreshAt = now;
12986
- await flushAcks(deps, pending, epochOf);
12987
- deps.refreshView();
12987
+ if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
12988
12988
  }
12989
12989
  /** One listing pass: process each entry, flushing and refreshing as it goes. */
12990
12990
  async drainPages(ctx, basis) {
12991
- const { deps, engine, pending, stored, pageEpoch } = ctx;
12991
+ const { deps, pending, pageEpoch, claimable } = ctx;
12992
12992
  for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
12993
- const storedBefore = stored.length;
12994
- await this.processEntry(deps, engine, entry, pending, stored);
12995
- if (pending.length >= ACK_BATCH_SIZE) await flushAcks(deps, pending, pageEpoch);
12996
- if (stored.length > storedBefore) await this.maybeRefresh(deps, pending, pageEpoch);
12993
+ const claimableBefore = claimable.n;
12994
+ await this.processEntry(ctx, entry);
12995
+ if (pending.length >= ACK_BATCH_SIZE) {
12996
+ if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
12997
+ }
12998
+ if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
12997
12999
  }
12998
13000
  await flushAcks(deps, pending, pageEpoch);
12999
13001
  }
@@ -13004,11 +13006,16 @@ var Receive = class {
13004
13006
  const stored = [];
13005
13007
  const pending = [];
13006
13008
  const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
13009
+ const claimable = { n: 0 };
13010
+ const finish = () => {
13011
+ if (claimable.n > 0) deps.refreshView?.();
13012
+ return stored;
13013
+ };
13007
13014
  try {
13008
13015
  const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
13009
13016
  let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
13010
13017
  for (let pass = 0; pass < 2; pass++) {
13011
- await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
13018
+ await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
13012
13019
  const served = deps.delivery.incomingEpoch();
13013
13020
  if (basis === null || served === null || served === basis.syncEpoch) break;
13014
13021
  await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
@@ -13016,22 +13023,25 @@ var Receive = class {
13016
13023
  }
13017
13024
  } catch (err) {
13018
13025
  logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
13019
- if (isRetryableAckError(err)) return stored;
13026
+ if (isRetryableAckError(err)) return finish();
13020
13027
  await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
13021
13028
  logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
13029
+ return { progressed: false };
13022
13030
  });
13023
13031
  }
13024
- if (stored.length > 0) deps.refreshView?.();
13025
- return stored;
13032
+ return finish();
13026
13033
  }
13027
- async processEntry(deps, engine, entry, pending, stored) {
13034
+ async processEntry(ctx, entry) {
13035
+ const { deps, engine, pending, stored, claimable } = ctx;
13028
13036
  const screened = await screen(deps, engine, entry);
13029
13037
  if (screened.kind === "ack") {
13030
13038
  pending.push(screened.ack);
13039
+ if (screened.ack.disposition === "claimed") claimable.n += 1;
13031
13040
  return;
13032
13041
  }
13033
13042
  await deps.view.store(screened.record);
13034
13043
  pending.push(claimAck(entry));
13044
+ claimable.n += 1;
13035
13045
  const transfer = await announce(deps, entry, screened.record);
13036
13046
  stored.push(transfer);
13037
13047
  deps.emit("transfer:incoming", transfer);
@@ -13092,7 +13102,8 @@ async function announce(deps, entry, record) {
13092
13102
  };
13093
13103
  }
13094
13104
  async function flushAcks(deps, pending, epochOf) {
13095
- if (pending.length === 0) return;
13105
+ if (pending.length === 0) return { progressed: true };
13106
+ const before = pending.length;
13096
13107
  let lastAcked = null;
13097
13108
  try {
13098
13109
  const settled = await settleAcks(deps, pending);
@@ -13110,6 +13121,7 @@ async function flushAcks(deps, pending, epochOf) {
13110
13121
  await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
13111
13122
  }
13112
13123
  }
13124
+ return { progressed: pending.length < before };
13113
13125
  }
13114
13126
  async function settleAcks(deps, pending) {
13115
13127
  const batch = deps.delivery.ackBatch?.bind(deps.delivery);
@@ -15630,7 +15642,9 @@ var WalletApiDeliveryPort = class {
15630
15642
  await this.settleClaims(acks, settled, outcomes);
15631
15643
  await this.settleRejects(acks, settled);
15632
15644
  } catch (err) {
15633
- await this.addSeenAll(settled).catch(() => void 0);
15645
+ await this.addSeenAll(settled).catch((seenErr) => {
15646
+ logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
15647
+ });
15634
15648
  throw asRetryable(err);
15635
15649
  }
15636
15650
  await this.addSeenAll(settled);