@agentunion/fastaun 0.5.36 → 0.5.37

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.
@@ -16,6 +16,7 @@ export declare class MessageDeliveryEngine {
16
16
  private readonly forwardAckJobs;
17
17
  private readonly forwardAckTasks;
18
18
  scheduleForwardAck(ns: string, seq: number, send: (seq: number) => Promise<void>): void;
19
+ confirmForwardAck(ns: string, seq: number): void;
19
20
  drainForwardAcks(): Promise<void> | undefined;
20
21
  private waitForwardAcks;
21
22
  private realtimeTailHeads;
@@ -122,13 +122,39 @@ export class MessageDeliveryEngine {
122
122
  }
123
123
  return;
124
124
  }
125
- const job = { seq, scope: current, send };
125
+ const job = { seq, confirmed: 0, scope: current, send };
126
126
  this.forwardAckJobs.set(ns, job);
127
127
  const isCurrent = () => this.forwardAckJobs.get(ns) === job && job.scope.every((value, i) => value === scope()[i]);
128
128
  const task = (async () => {
129
+ const checkedPulls = new Set();
129
130
  let failures = 0;
130
131
  while (isCurrent()) {
132
+ if (job.confirmed >= job.seq)
133
+ return;
134
+ const nextPull = client._rpcPipeline?.queuedForwardPull?.(ns);
135
+ if (nextPull && !checkedPulls.has(nextPull)) {
136
+ checkedPulls.add(nextPull);
137
+ try {
138
+ const result = await nextPull;
139
+ if (!isCurrent())
140
+ return;
141
+ const response = result;
142
+ const peer = ns.startsWith('p2p.peer.v1/');
143
+ const bound = !peer || response?.cursor_scope === 'peer'
144
+ && typeof response.sender_aid === 'string' && this.peerNamespace(response.sender_aid) === ns;
145
+ const actual = !bound ? 0 : ns.startsWith('group:')
146
+ ? this.resolveGroupPullAckSeq(result, job.seq) : this.resolveP2PPullAckSeq(result, job.seq);
147
+ if (actual > 0) {
148
+ client._v2E2EE?.clearForwardAck?.(ns, actual);
149
+ job.confirmed = Math.max(job.confirmed, actual);
150
+ }
151
+ }
152
+ catch { }
153
+ continue;
154
+ }
131
155
  const pending = job.seq;
156
+ if (job.confirmed >= pending)
157
+ return;
132
158
  try {
133
159
  await job.send(pending);
134
160
  failures = 0;
@@ -152,6 +178,11 @@ export class MessageDeliveryEngine {
152
178
  });
153
179
  this.forwardAckTasks.add(task);
154
180
  }
181
+ confirmForwardAck(ns, seq) {
182
+ const job = this.forwardAckJobs.get(ns);
183
+ if (job)
184
+ job.confirmed = Math.max(job.confirmed, seq);
185
+ }
155
186
  drainForwardAcks() {
156
187
  if (!this.forwardAckTasks.size)
157
188
  return;
@@ -639,6 +670,7 @@ export class MessageDeliveryEngine {
639
670
  if (!namespace.startsWith('p2p.peer.v1/') || !Number.isSafeInteger(sequence) || sequence < 0)
640
671
  return;
641
672
  this.peerServerConfirmedAcks.set(namespace, Math.max(this.peerServerConfirmedAcks.get(namespace) ?? 0, sequence));
673
+ this.confirmForwardAck(namespace, sequence);
642
674
  this.runtime.client._rpcPipeline?.confirmBackgroundAck?.(namespace, sequence);
643
675
  }
644
676
  rememberCommittedSeqState(namespace) {
@@ -829,7 +861,7 @@ export class MessageDeliveryEngine {
829
861
  return tail;
830
862
  }
831
863
  if (!budget.remaining) {
832
- this.schedulePeerRecovery(peer, Number(tail.head_seq ?? 0), true);
864
+ this.schedulePeerRecovery(peer, Number(tail.head_seq ?? 0), tail.volatile_has_more === true);
833
865
  return { ...tail, complete: false };
834
866
  }
835
867
  forwardNeed = this.peerForwardNeeds.get(ns);
@@ -855,7 +887,7 @@ export class MessageDeliveryEngine {
855
887
  const complete = this.canClosePeerTail(ns, result, pushVersion, catalogVersion);
856
888
  if (!complete) {
857
889
  this.peerForwardNeeds.set(ns, {});
858
- this.schedulePeerRecovery(peer, Number(result.head_seq ?? 0), true);
890
+ this.schedulePeerRecovery(peer, Number(result.head_seq ?? 0), result.volatile_has_more === true);
859
891
  }
860
892
  else if (this.peerForwardNeeds.get(ns) === forwardNeed)
861
893
  this.peerForwardNeeds.delete(ns);
@@ -987,9 +1019,16 @@ export class MessageDeliveryEngine {
987
1019
  this.peerForwardNeeds.set(namespace, {});
988
1020
  return;
989
1021
  }
990
- if (volatile && client._syncChannelCoordinator?.needsSplit?.()
991
- && (this.peerRecoveryTasks.has(sender) || this.oversizedPulls.has(namespace)))
1022
+ if (volatile && client._syncChannelCoordinator?.needsSplit?.()) {
992
1023
  this.schedulePeerVolatileRecovery(sender);
1024
+ const ack = this.peerCommittedAck(namespace);
1025
+ const state = this.syncState(namespace);
1026
+ if (this.initializedPeers.has(namespace) && Number.isSafeInteger(head) && head > 0 && head <= ack
1027
+ && state.head <= ack && client._seqTracker.getMaxSeenSeq(namespace) <= ack
1028
+ && (this.peerServerConfirmedAcks.get(namespace) ?? 0) >= ack
1029
+ && !this.peerForwardNeeds.has(namespace) && !this.peerRecoveryNeeds.has(sender))
1030
+ return;
1031
+ }
993
1032
  if (this.oversizedPulls.has(namespace))
994
1033
  return;
995
1034
  const need = this.peerRecoveryNeeds.get(sender) ?? { head: 0, volatile: false, pending: false };
@@ -1842,7 +1881,7 @@ export class MessageDeliveryEngine {
1842
1881
  return [...namespaces];
1843
1882
  }
1844
1883
  hasAnyPendingPull() {
1845
- return this.peerCatalogDirty || [...this.peerRecoveryNeeds.values()].some((need) => !need.paused) || this.peerRecoveryTasks.size > 0 || Boolean(this.peerCatalogTask)
1884
+ return this.forwardAckTasks.size > 0 || this.peerCatalogDirty || [...this.peerRecoveryNeeds.values()].some((need) => !need.paused) || this.peerRecoveryTasks.size > 0 || Boolean(this.peerCatalogTask)
1846
1885
  || Boolean(this.peerVolatileTask) || this.peerVolatileNeeds.size > 0
1847
1886
  || [...(this.pendingGroupPullUpper?.values() ?? [])].some((seq) => seq > 0)
1848
1887
  || [...this.backgroundPullNeeds.values()].some((need) => need.retryAt !== Infinity)