@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.
@@ -13064,22 +13064,24 @@ var Receive = class {
13064
13064
  * the tokens just accepted, and the balance would still only move at the end.
13065
13065
  * Ordering is preserved: store() still precedes the ack (§5.7).
13066
13066
  */
13067
- async maybeRefresh(deps, pending, epochOf) {
13067
+ async maybeRefresh(ctx) {
13068
+ const { deps, pending, pageEpoch } = ctx;
13068
13069
  if (deps.refreshView === void 0) return;
13069
13070
  const now = deps.now?.() ?? Date.now();
13070
13071
  if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
13071
13072
  this.lastRefreshAt = now;
13072
- await flushAcks(deps, pending, epochOf);
13073
- deps.refreshView();
13073
+ if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
13074
13074
  }
13075
13075
  /** One listing pass: process each entry, flushing and refreshing as it goes. */
13076
13076
  async drainPages(ctx, basis) {
13077
- const { deps, engine, pending, stored, pageEpoch } = ctx;
13077
+ const { deps, pending, pageEpoch, claimable } = ctx;
13078
13078
  for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
13079
- const storedBefore = stored.length;
13080
- await this.processEntry(deps, engine, entry, pending, stored);
13081
- if (pending.length >= ACK_BATCH_SIZE) await flushAcks(deps, pending, pageEpoch);
13082
- if (stored.length > storedBefore) await this.maybeRefresh(deps, pending, pageEpoch);
13079
+ const claimableBefore = claimable.n;
13080
+ await this.processEntry(ctx, entry);
13081
+ if (pending.length >= ACK_BATCH_SIZE) {
13082
+ if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
13083
+ }
13084
+ if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
13083
13085
  }
13084
13086
  await flushAcks(deps, pending, pageEpoch);
13085
13087
  }
@@ -13090,11 +13092,16 @@ var Receive = class {
13090
13092
  const stored = [];
13091
13093
  const pending = [];
13092
13094
  const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
13095
+ const claimable = { n: 0 };
13096
+ const finish = () => {
13097
+ if (claimable.n > 0) deps.refreshView?.();
13098
+ return stored;
13099
+ };
13093
13100
  try {
13094
13101
  const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
13095
13102
  let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
13096
13103
  for (let pass = 0; pass < 2; pass++) {
13097
- await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
13104
+ await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
13098
13105
  const served = deps.delivery.incomingEpoch();
13099
13106
  if (basis === null || served === null || served === basis.syncEpoch) break;
13100
13107
  await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
@@ -13102,22 +13109,25 @@ var Receive = class {
13102
13109
  }
13103
13110
  } catch (err) {
13104
13111
  logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
13105
- if (isRetryableAckError(err)) return stored;
13112
+ if (isRetryableAckError(err)) return finish();
13106
13113
  await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
13107
13114
  logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
13115
+ return { progressed: false };
13108
13116
  });
13109
13117
  }
13110
- if (stored.length > 0) deps.refreshView?.();
13111
- return stored;
13118
+ return finish();
13112
13119
  }
13113
- async processEntry(deps, engine, entry, pending, stored) {
13120
+ async processEntry(ctx, entry) {
13121
+ const { deps, engine, pending, stored, claimable } = ctx;
13114
13122
  const screened = await screen(deps, engine, entry);
13115
13123
  if (screened.kind === "ack") {
13116
13124
  pending.push(screened.ack);
13125
+ if (screened.ack.disposition === "claimed") claimable.n += 1;
13117
13126
  return;
13118
13127
  }
13119
13128
  await deps.view.store(screened.record);
13120
13129
  pending.push(claimAck(entry));
13130
+ claimable.n += 1;
13121
13131
  const transfer = await announce(deps, entry, screened.record);
13122
13132
  stored.push(transfer);
13123
13133
  deps.emit("transfer:incoming", transfer);
@@ -13178,7 +13188,8 @@ async function announce(deps, entry, record) {
13178
13188
  };
13179
13189
  }
13180
13190
  async function flushAcks(deps, pending, epochOf) {
13181
- if (pending.length === 0) return;
13191
+ if (pending.length === 0) return { progressed: true };
13192
+ const before = pending.length;
13182
13193
  let lastAcked = null;
13183
13194
  try {
13184
13195
  const settled = await settleAcks(deps, pending);
@@ -13196,6 +13207,7 @@ async function flushAcks(deps, pending, epochOf) {
13196
13207
  await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
13197
13208
  }
13198
13209
  }
13210
+ return { progressed: pending.length < before };
13199
13211
  }
13200
13212
  async function settleAcks(deps, pending) {
13201
13213
  const batch = deps.delivery.ackBatch?.bind(deps.delivery);
@@ -15716,7 +15728,9 @@ var WalletApiDeliveryPort = class {
15716
15728
  await this.settleClaims(acks, settled, outcomes);
15717
15729
  await this.settleRejects(acks, settled);
15718
15730
  } catch (err) {
15719
- await this.addSeenAll(settled).catch(() => void 0);
15731
+ await this.addSeenAll(settled).catch((seenErr) => {
15732
+ logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
15733
+ });
15720
15734
  throw asRetryable(err);
15721
15735
  }
15722
15736
  await this.addSeenAll(settled);