@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.
package/dist/index.js CHANGED
@@ -12994,22 +12994,24 @@ var Receive = class {
12994
12994
  * the tokens just accepted, and the balance would still only move at the end.
12995
12995
  * Ordering is preserved: store() still precedes the ack (§5.7).
12996
12996
  */
12997
- async maybeRefresh(deps, pending, epochOf) {
12997
+ async maybeRefresh(ctx) {
12998
+ const { deps, pending, pageEpoch } = ctx;
12998
12999
  if (deps.refreshView === void 0) return;
12999
13000
  const now = deps.now?.() ?? Date.now();
13000
13001
  if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
13001
13002
  this.lastRefreshAt = now;
13002
- await flushAcks(deps, pending, epochOf);
13003
- deps.refreshView();
13003
+ if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
13004
13004
  }
13005
13005
  /** One listing pass: process each entry, flushing and refreshing as it goes. */
13006
13006
  async drainPages(ctx, basis) {
13007
- const { deps, engine, pending, stored, pageEpoch } = ctx;
13007
+ const { deps, pending, pageEpoch, claimable } = ctx;
13008
13008
  for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
13009
- const storedBefore = stored.length;
13010
- await this.processEntry(deps, engine, entry, pending, stored);
13011
- if (pending.length >= ACK_BATCH_SIZE) await flushAcks(deps, pending, pageEpoch);
13012
- if (stored.length > storedBefore) await this.maybeRefresh(deps, pending, pageEpoch);
13009
+ const claimableBefore = claimable.n;
13010
+ await this.processEntry(ctx, entry);
13011
+ if (pending.length >= ACK_BATCH_SIZE) {
13012
+ if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
13013
+ }
13014
+ if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
13013
13015
  }
13014
13016
  await flushAcks(deps, pending, pageEpoch);
13015
13017
  }
@@ -13020,11 +13022,16 @@ var Receive = class {
13020
13022
  const stored = [];
13021
13023
  const pending = [];
13022
13024
  const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
13025
+ const claimable = { n: 0 };
13026
+ const finish = () => {
13027
+ if (claimable.n > 0) deps.refreshView?.();
13028
+ return stored;
13029
+ };
13023
13030
  try {
13024
13031
  const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
13025
13032
  let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
13026
13033
  for (let pass = 0; pass < 2; pass++) {
13027
- await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
13034
+ await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
13028
13035
  const served = deps.delivery.incomingEpoch();
13029
13036
  if (basis === null || served === null || served === basis.syncEpoch) break;
13030
13037
  await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
@@ -13032,22 +13039,25 @@ var Receive = class {
13032
13039
  }
13033
13040
  } catch (err) {
13034
13041
  logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
13035
- if (isRetryableAckError(err)) return stored;
13042
+ if (isRetryableAckError(err)) return finish();
13036
13043
  await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
13037
13044
  logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
13045
+ return { progressed: false };
13038
13046
  });
13039
13047
  }
13040
- if (stored.length > 0) deps.refreshView?.();
13041
- return stored;
13048
+ return finish();
13042
13049
  }
13043
- async processEntry(deps, engine, entry, pending, stored) {
13050
+ async processEntry(ctx, entry) {
13051
+ const { deps, engine, pending, stored, claimable } = ctx;
13044
13052
  const screened = await screen(deps, engine, entry);
13045
13053
  if (screened.kind === "ack") {
13046
13054
  pending.push(screened.ack);
13055
+ if (screened.ack.disposition === "claimed") claimable.n += 1;
13047
13056
  return;
13048
13057
  }
13049
13058
  await deps.view.store(screened.record);
13050
13059
  pending.push(claimAck(entry));
13060
+ claimable.n += 1;
13051
13061
  const transfer = await announce(deps, entry, screened.record);
13052
13062
  stored.push(transfer);
13053
13063
  deps.emit("transfer:incoming", transfer);
@@ -13108,7 +13118,8 @@ async function announce(deps, entry, record) {
13108
13118
  };
13109
13119
  }
13110
13120
  async function flushAcks(deps, pending, epochOf) {
13111
- if (pending.length === 0) return;
13121
+ if (pending.length === 0) return { progressed: true };
13122
+ const before = pending.length;
13112
13123
  let lastAcked = null;
13113
13124
  try {
13114
13125
  const settled = await settleAcks(deps, pending);
@@ -13126,6 +13137,7 @@ async function flushAcks(deps, pending, epochOf) {
13126
13137
  await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
13127
13138
  }
13128
13139
  }
13140
+ return { progressed: pending.length < before };
13129
13141
  }
13130
13142
  async function settleAcks(deps, pending) {
13131
13143
  const batch = deps.delivery.ackBatch?.bind(deps.delivery);
@@ -15646,7 +15658,9 @@ var WalletApiDeliveryPort = class {
15646
15658
  await this.settleClaims(acks, settled, outcomes);
15647
15659
  await this.settleRejects(acks, settled);
15648
15660
  } catch (err) {
15649
- await this.addSeenAll(settled).catch(() => void 0);
15661
+ await this.addSeenAll(settled).catch((seenErr) => {
15662
+ logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
15663
+ });
15650
15664
  throw asRetryable(err);
15651
15665
  }
15652
15666
  await this.addSeenAll(settled);