@agentunion/fastaun-browser 0.5.1 → 0.5.2

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +548 -518
  2. package/_packed_docs/CHANGELOG-validators.md +134 -131
  3. package/_packed_docs/CHANGELOG.md +548 -518
  4. package/_packed_docs/INDEX.md +51 -44
  5. package/_packed_docs/KITE_DOCS_GUIDE.md +19 -16
  6. package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +169 -116
  7. package/_packed_docs/aun-perf-audit-critical-bugs.md +315 -0
  8. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +263 -261
  9. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +328 -328
  10. package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -2
  11. package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +1 -1
  12. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +39 -16
  13. package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +8 -5
  14. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +18 -19
  15. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +1 -1
  16. package/_packed_docs/protocol/08-AUN-E2EE-Group.md +293 -294
  17. package/_packed_docs/protocol/08-AUN-E2EE.md +12 -10
  18. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +85 -89
  19. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +4 -4
  20. package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +1 -1
  21. package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -177
  22. package/_packed_docs/protocol/README.md +4 -4
  23. package/_packed_docs/protocol/aun-docs-guide.md +2 -2
  24. package/_packed_docs/protocol/index.md +4 -4
  25. package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +1 -1
  26. package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +13 -13
  27. package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +9 -9
  28. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +15 -13
  29. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +26 -18
  30. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +33 -34
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +22 -17
  32. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +11 -7
  33. package/_packed_docs/sdk/09-group-rpc-manual.md +135 -114
  34. package/_packed_docs/sdk/09-message-rpc-manual.md +50 -28
  35. package/_packed_docs/sdk/09-payload-reference.md +3 -3
  36. package/_packed_docs/sdk/09-storage-rpc-manual.md +1 -1
  37. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +11 -10
  38. package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +3 -2
  39. package/_packed_docs/sdk/INDEX.md +15 -14
  40. package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +6 -2
  41. package/dist/agent-md.d.ts.map +1 -1
  42. package/dist/agent-md.js +18 -9
  43. package/dist/agent-md.js.map +1 -1
  44. package/dist/bundle.js +104 -24
  45. package/dist/client/v2-e2ee.d.ts.map +1 -1
  46. package/dist/client/v2-e2ee.js +78 -7
  47. package/dist/client/v2-e2ee.js.map +1 -1
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.js +1 -1
  50. package/package.json +1 -1
package/dist/bundle.js CHANGED
@@ -460,7 +460,7 @@ var init_indexeddb_store = __esm({
460
460
  });
461
461
 
462
462
  // src/version.ts
463
- var VERSION = "0.5.1";
463
+ var VERSION = "0.5.2";
464
464
 
465
465
  // src/types.ts
466
466
  var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
@@ -3355,7 +3355,7 @@ var AgentMdManager = class _AgentMdManager {
3355
3355
  }
3356
3356
  const etags = meta.agent_md_etags;
3357
3357
  if (!isJsonObject(etags)) return;
3358
- for (const key of ["requester", "peer", "receiver", "target", "to", "sender", "from"]) {
3358
+ for (const key of ["requester", "peer", "group", "receiver", "target", "to", "sender", "from"]) {
3359
3359
  const item = etags[key];
3360
3360
  if (!isJsonObject(item)) continue;
3361
3361
  await this.observeMeta(
@@ -3370,19 +3370,34 @@ var AgentMdManager = class _AgentMdManager {
3370
3370
  if (!isJsonObject(envelope)) return;
3371
3371
  if (!isJsonObject(envelope.agent_md)) return;
3372
3372
  const agentMd = envelope.agent_md;
3373
- if (!isJsonObject(agentMd.sender)) return;
3374
- const sender = agentMd.sender;
3375
- let senderAid = String(sender.aid ?? "").trim();
3376
- if (!senderAid) {
3377
- const aad = isJsonObject(envelope.aad) ? envelope.aad : {};
3378
- senderAid = String(aad.from ?? envelope.from ?? "").trim();
3379
- }
3380
- await this.observeMeta(
3381
- senderAid,
3382
- String(sender.etag ?? "").trim(),
3383
- String(sender.last_modified ?? sender.lastModified ?? "").trim(),
3384
- "envelope"
3385
- );
3373
+ if (isJsonObject(agentMd.sender)) {
3374
+ const sender = agentMd.sender;
3375
+ let senderAid = String(sender.aid ?? "").trim();
3376
+ if (!senderAid) {
3377
+ const aad = isJsonObject(envelope.aad) ? envelope.aad : {};
3378
+ senderAid = String(aad.from ?? envelope.from ?? "").trim();
3379
+ }
3380
+ await this.observeMeta(
3381
+ senderAid,
3382
+ String(sender.etag ?? "").trim(),
3383
+ String(sender.last_modified ?? sender.lastModified ?? "").trim(),
3384
+ "envelope.sender"
3385
+ );
3386
+ }
3387
+ if (isJsonObject(agentMd.group)) {
3388
+ const group = agentMd.group;
3389
+ let groupAid = String(group.aid ?? "").trim();
3390
+ if (!groupAid) {
3391
+ const aad = isJsonObject(envelope.aad) ? envelope.aad : {};
3392
+ groupAid = String(envelope.group_aid ?? envelope.group_id ?? aad.group_aid ?? aad.group_id ?? "").trim();
3393
+ }
3394
+ await this.observeMeta(
3395
+ groupAid,
3396
+ String(group.etag ?? "").trim(),
3397
+ String(group.last_modified ?? group.lastModified ?? "").trim(),
3398
+ "envelope.group"
3399
+ );
3400
+ }
3386
3401
  }
3387
3402
  eventSnapshot() {
3388
3403
  if (!this._localAgentMdEtag && !this._remoteAgentMdEtag) return null;
@@ -16433,6 +16448,17 @@ var MEMBERSHIP_ACTIONS = /* @__PURE__ */ new Set([
16433
16448
  "invite_code_used"
16434
16449
  ]);
16435
16450
  var JOIN_ACTIONS = /* @__PURE__ */ new Set(["member_added", "joined", "join_approved", "invite_code_used"]);
16451
+ function v2PullTailDelayMs(msgCount, pageLimit) {
16452
+ const count = Math.trunc(Number(msgCount || 0));
16453
+ const limit = Math.trunc(Number(pageLimit || 0));
16454
+ if (count <= 0 || limit > 0 && count >= limit) return 0;
16455
+ return Math.min(500, Math.max(5, 1e3 / (count + 1)));
16456
+ }
16457
+ function v2Sleep(ms) {
16458
+ return new Promise((resolve) => {
16459
+ globalThis.setTimeout(resolve, ms);
16460
+ });
16461
+ }
16436
16462
  function exactArrayBuffer(bytes) {
16437
16463
  return bytes.slice().buffer;
16438
16464
  }
@@ -17066,14 +17092,21 @@ var V2E2EECoordinator = class {
17066
17092
  let nextAfterSeq = opts?.force ? afterSeq : afterSeq || (ns ? client._seqTracker.getContiguousSeq(ns) : 0);
17067
17093
  let pageCount = 0;
17068
17094
  let lastAutoAckSeq = 0;
17095
+ let pendingAckSeq = 0;
17069
17096
  const maxPages = 100;
17070
17097
  while (pageCount < maxPages) {
17071
17098
  pageCount += 1;
17099
+ const ackUpToSeq = pendingAckSeq;
17072
17100
  const result = await client._callRawV2Rpc("message.v2.pull", {
17073
17101
  after_seq: nextAfterSeq,
17074
17102
  limit,
17075
- ...opts?.force ? { force: true } : {}
17103
+ ...opts?.force ? { force: true } : {},
17104
+ ...ackUpToSeq > 0 ? { ack_up_to_seq: ackUpToSeq } : {}
17076
17105
  });
17106
+ if (ackUpToSeq > 0) {
17107
+ pendingAckSeq = 0;
17108
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackUpToSeq);
17109
+ }
17077
17110
  const pageMessages = Array.isArray(result?.messages) ? result.messages : [];
17078
17111
  const messages = pageMessages.filter((msg) => {
17079
17112
  const seq = Number(msg.seq ?? 0);
@@ -17151,16 +17184,33 @@ var V2E2EECoordinator = class {
17151
17184
  }
17152
17185
  const ackNeeded = pageMessages.length > 0 && ackSeq > 0 && ackSeq > lastAutoAckSeq && (contigAdvanced || hasServerAckSeq && ackSeq > serverAckSeq);
17153
17186
  if (ackNeeded) {
17154
- await this.ackV2(ackSeq);
17155
- lastAutoAckSeq = ackSeq;
17187
+ const nextAfter2 = Math.max(pageMaxSeq, nextAfterSeq);
17188
+ const canContinuePage2 = messages.length > 0 && nextAfter2 > nextAfterSeq;
17189
+ if (canContinuePage2) {
17190
+ pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
17191
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
17192
+ } else {
17193
+ await this.ackV2(ackSeq);
17194
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
17195
+ }
17156
17196
  }
17157
17197
  }
17158
17198
  const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
17159
- if (messages.length === 0 || nextAfter <= nextAfterSeq) break;
17199
+ const rawCount = messages.length;
17200
+ const canContinuePage = rawCount > 0 && nextAfter > nextAfterSeq;
17201
+ const fullPage = canContinuePage && limit > 0 && rawCount >= limit;
17202
+ const shouldContinue = canContinuePage && (fullPage || pendingAckSeq > 0);
17203
+ if (!shouldContinue) break;
17204
+ const tailDelayMs = v2PullTailDelayMs(rawCount, limit);
17205
+ if (tailDelayMs > 0) await v2Sleep(tailDelayMs);
17160
17206
  nextAfterSeq = nextAfter;
17161
17207
  }
17162
17208
  if (pageCount >= maxPages) {
17163
17209
  client._clientLog.warn(`message.v2.pull reached max_pages=${maxPages} after_seq=${nextAfterSeq}`);
17210
+ if (pendingAckSeq > 0) {
17211
+ await this.ackV2(pendingAckSeq);
17212
+ pendingAckSeq = 0;
17213
+ }
17164
17214
  }
17165
17215
  return decrypted;
17166
17216
  }
@@ -17277,17 +17327,29 @@ var V2E2EECoordinator = class {
17277
17327
  const ownsCursor = opts?.ownsCursor !== false;
17278
17328
  let nextAfterSeq = opts?.explicitAfterSeq ? afterSeq : afterSeq || client._seqTracker.getContiguousSeq(ns);
17279
17329
  let pageCount = 0;
17330
+ let lastAutoAckSeq = 0;
17331
+ let pendingAckSeq = 0;
17280
17332
  const maxPages = 100;
17281
17333
  while (pageCount < maxPages) {
17282
17334
  pageCount += 1;
17335
+ const ackUpToSeq = ownsCursor ? pendingAckSeq : 0;
17283
17336
  const result = await client._callRawV2Rpc("group.v2.pull", {
17284
17337
  group_id: wireGroupId,
17285
17338
  group_aid: gid,
17286
17339
  after_seq: nextAfterSeq,
17287
17340
  limit,
17288
- ...cursorParams
17341
+ ...cursorParams,
17342
+ ...ackUpToSeq > 0 ? { ack_up_to_seq: ackUpToSeq } : {}
17343
+ });
17344
+ if (ackUpToSeq > 0) {
17345
+ pendingAckSeq = 0;
17346
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackUpToSeq);
17347
+ }
17348
+ const pageMessages = Array.isArray(result?.messages) ? result.messages : [];
17349
+ const messages = pageMessages.filter((msg) => {
17350
+ const seq = Number(msg.seq ?? 0);
17351
+ return Number.isFinite(seq) && seq > nextAfterSeq;
17289
17352
  });
17290
- const messages = Array.isArray(result?.messages) ? result.messages : [];
17291
17353
  const seqs = messages.map((msg) => Number(msg.seq ?? 0)).filter((seq) => Number.isFinite(seq) && seq > 0);
17292
17354
  const pageContigBefore = client._seqTracker.getContiguousSeq(ns);
17293
17355
  const pageMaxSeq = seqs.length > 0 ? Math.max(...seqs) : nextAfterSeq;
@@ -17370,17 +17432,35 @@ var V2E2EECoordinator = class {
17370
17432
  client._persistSeq(ns);
17371
17433
  }
17372
17434
  const hasServerCursor = cursor !== null && Object.prototype.hasOwnProperty.call(cursor, "current_seq");
17373
- const ackNeeded = messages.length > 0 && ackSeq > 0 && ownsCursor && (contigAdvanced || hasServerCursor && ackSeq > cursorCurrentSeq);
17435
+ const ackNeeded = pageMessages.length > 0 && ackSeq > 0 && ackSeq > lastAutoAckSeq && ownsCursor && (contigAdvanced || hasServerCursor && ackSeq > cursorCurrentSeq);
17374
17436
  if (ackNeeded) {
17375
- await this.ackGroupV2(gid, ackSeq);
17437
+ const nextAfter2 = Math.max(pageMaxSeq, nextAfterSeq);
17438
+ const canContinuePage2 = messages.length > 0 && nextAfter2 > nextAfterSeq && ownsCursor;
17439
+ if (canContinuePage2) {
17440
+ pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
17441
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
17442
+ } else {
17443
+ await this.ackGroupV2(gid, ackSeq);
17444
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
17445
+ }
17376
17446
  }
17377
17447
  const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
17378
17448
  if (!ownsCursor) break;
17379
- if (messages.length === 0 || nextAfter <= nextAfterSeq || result.has_more === false) break;
17449
+ const rawCount = messages.length;
17450
+ const canContinuePage = rawCount > 0 && nextAfter > nextAfterSeq;
17451
+ const fullPage = canContinuePage && limit > 0 && rawCount >= limit;
17452
+ const shouldContinue = canContinuePage && (fullPage || pendingAckSeq > 0);
17453
+ if (!shouldContinue) break;
17454
+ const tailDelayMs = v2PullTailDelayMs(rawCount, limit);
17455
+ if (tailDelayMs > 0) await v2Sleep(tailDelayMs);
17380
17456
  nextAfterSeq = nextAfter;
17381
17457
  }
17382
17458
  if (pageCount >= maxPages) {
17383
17459
  client._clientLog.warn(`group.v2.pull reached max_pages=${maxPages} group=${gid} after_seq=${nextAfterSeq}`);
17460
+ if (pendingAckSeq > 0) {
17461
+ await this.ackGroupV2(gid, pendingAckSeq);
17462
+ pendingAckSeq = 0;
17463
+ }
17384
17464
  }
17385
17465
  return decrypted;
17386
17466
  }
@@ -1 +1 @@
1
- {"version":3,"file":"v2-e2ee.d.ts","sourceRoot":"","sources":["../../src/client/v2-e2ee.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"v2-e2ee.d.ts","sourceRoot":"","sources":["../../src/client/v2-e2ee.ts"],"names":[],"mappings":"AAWA,OAAO,EAAiC,KAAK,UAAU,EAAkB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7H,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,cAAc,CAAC;AAE9D,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAyOlE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqF;IACpH,OAAO,CAAC,uBAAuB,CAA8C;IAC7E,OAAO,CAAC,gCAAgC,CAAS;IACjD,OAAO,CAAC,6BAA6B,CAAuB;gBAEhD,OAAO,EAAE,aAAa;IAIlC,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,KAAK,cAAc,GAMzB;IAED,sBAAsB,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI7F,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAIhE,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK5C,mBAAmB,IAAI,IAAI;IAK3B,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAcjE,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,mBAAmB;IAMrB,WAAW,CAAC,IAAI,EAAE;QAAE,cAAc,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnE,OAAO,CAAC,oCAAoC;IAW5C,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,0BAA0B;YAmCpB,kBAAkB;IA6B1B,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAwFpC,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAmB7E,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAmBzE,6CAA6C,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAU9D,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAsBtH,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAQhF,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAIzF,uBAAuB,CAAC,IAAI,EAAE;QAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI;IAkBR,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ/E,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqEjH,MAAM,CACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC/H,OAAO,CAAC,OAAO,CAAC;IAyDb,MAAM,CAAC,QAAQ,SAAI,EAAE,KAAK,SAAK,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAoJhF,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+BzC,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC/H,OAAO,CAAC,OAAO,CAAC;IAyEb,mBAAmB,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,SAAI,EACZ,KAAK,SAAK,EACV,IAAI,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACxH,OAAO,CAAC,OAAO,EAAE,CAAC;IAsKf,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW/D,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IA0EnE,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAyEjE,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAiE7D,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAoE/D,2BAA2B,CAAC,IAAI,EAAE;QACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAoE3C,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAanF,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAK7D,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAcrD,4BAA4B,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAO3G,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA2B3F,2BAA2B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAiClH,mCAAmC,CACvC,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,OAAO,CAAC;IAWb,2BAA2B,CAC/B,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,EAC1B,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,OAAO,CAAC;IAWb,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAK5E,kBAAkB,CAAC,IAAI,EAAE;QAC7B,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA2H9B,oBAAoB,CAAC,IAAI,EAAE;QAC/B,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA8IpC,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAgBxF"}
@@ -21,6 +21,18 @@ const MEMBERSHIP_ACTIONS = new Set([
21
21
  'invite_code_used',
22
22
  ]);
23
23
  const JOIN_ACTIONS = new Set(['member_added', 'joined', 'join_approved', 'invite_code_used']);
24
+ function v2PullTailDelayMs(msgCount, pageLimit) {
25
+ const count = Math.trunc(Number(msgCount || 0));
26
+ const limit = Math.trunc(Number(pageLimit || 0));
27
+ if (count <= 0 || (limit > 0 && count >= limit))
28
+ return 0;
29
+ return Math.min(500, Math.max(5, 1000 / (count + 1)));
30
+ }
31
+ function v2Sleep(ms) {
32
+ return new Promise((resolve) => {
33
+ globalThis.setTimeout(resolve, ms);
34
+ });
35
+ }
24
36
  function exactArrayBuffer(bytes) {
25
37
  return bytes.slice().buffer;
26
38
  }
@@ -705,14 +717,21 @@ export class V2E2EECoordinator {
705
717
  let nextAfterSeq = opts?.force ? afterSeq : (afterSeq || (ns ? client._seqTracker.getContiguousSeq(ns) : 0));
706
718
  let pageCount = 0;
707
719
  let lastAutoAckSeq = 0;
720
+ let pendingAckSeq = 0;
708
721
  const maxPages = 100;
709
722
  while (pageCount < maxPages) {
710
723
  pageCount += 1;
724
+ const ackUpToSeq = pendingAckSeq;
711
725
  const result = await client._callRawV2Rpc('message.v2.pull', {
712
726
  after_seq: nextAfterSeq,
713
727
  limit,
714
728
  ...(opts?.force ? { force: true } : {}),
729
+ ...(ackUpToSeq > 0 ? { ack_up_to_seq: ackUpToSeq } : {}),
715
730
  });
731
+ if (ackUpToSeq > 0) {
732
+ pendingAckSeq = 0;
733
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackUpToSeq);
734
+ }
716
735
  const pageMessages = (Array.isArray(result?.messages) ? result.messages : []);
717
736
  const messages = pageMessages.filter((msg) => {
718
737
  const seq = Number(msg.seq ?? 0);
@@ -804,17 +823,36 @@ export class V2E2EECoordinator {
804
823
  && ackSeq > lastAutoAckSeq
805
824
  && (contigAdvanced || (hasServerAckSeq && ackSeq > serverAckSeq));
806
825
  if (ackNeeded) {
807
- await this.ackV2(ackSeq);
808
- lastAutoAckSeq = ackSeq;
826
+ const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
827
+ const canContinuePage = messages.length > 0 && nextAfter > nextAfterSeq;
828
+ if (canContinuePage) {
829
+ pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
830
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
831
+ }
832
+ else {
833
+ await this.ackV2(ackSeq);
834
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
835
+ }
809
836
  }
810
837
  }
811
838
  const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
812
- if (messages.length === 0 || nextAfter <= nextAfterSeq)
839
+ const rawCount = messages.length;
840
+ const canContinuePage = rawCount > 0 && nextAfter > nextAfterSeq;
841
+ const fullPage = canContinuePage && limit > 0 && rawCount >= limit;
842
+ const shouldContinue = canContinuePage && (fullPage || pendingAckSeq > 0);
843
+ if (!shouldContinue)
813
844
  break;
845
+ const tailDelayMs = v2PullTailDelayMs(rawCount, limit);
846
+ if (tailDelayMs > 0)
847
+ await v2Sleep(tailDelayMs);
814
848
  nextAfterSeq = nextAfter;
815
849
  }
816
850
  if (pageCount >= maxPages) {
817
851
  client._clientLog.warn(`message.v2.pull reached max_pages=${maxPages} after_seq=${nextAfterSeq}`);
852
+ if (pendingAckSeq > 0) {
853
+ await this.ackV2(pendingAckSeq);
854
+ pendingAckSeq = 0;
855
+ }
818
856
  }
819
857
  return decrypted;
820
858
  }
@@ -941,17 +979,29 @@ export class V2E2EECoordinator {
941
979
  const ownsCursor = opts?.ownsCursor !== false;
942
980
  let nextAfterSeq = opts?.explicitAfterSeq ? afterSeq : (afterSeq || client._seqTracker.getContiguousSeq(ns));
943
981
  let pageCount = 0;
982
+ let lastAutoAckSeq = 0;
983
+ let pendingAckSeq = 0;
944
984
  const maxPages = 100;
945
985
  while (pageCount < maxPages) {
946
986
  pageCount += 1;
987
+ const ackUpToSeq = ownsCursor ? pendingAckSeq : 0;
947
988
  const result = await client._callRawV2Rpc('group.v2.pull', {
948
989
  group_id: wireGroupId,
949
990
  group_aid: gid,
950
991
  after_seq: nextAfterSeq,
951
992
  limit,
952
993
  ...cursorParams,
994
+ ...(ackUpToSeq > 0 ? { ack_up_to_seq: ackUpToSeq } : {}),
995
+ });
996
+ if (ackUpToSeq > 0) {
997
+ pendingAckSeq = 0;
998
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackUpToSeq);
999
+ }
1000
+ const pageMessages = (Array.isArray(result?.messages) ? result.messages : []);
1001
+ const messages = pageMessages.filter((msg) => {
1002
+ const seq = Number(msg.seq ?? 0);
1003
+ return Number.isFinite(seq) && seq > nextAfterSeq;
953
1004
  });
954
- const messages = (Array.isArray(result?.messages) ? result.messages : []);
955
1005
  const seqs = messages
956
1006
  .map((msg) => Number(msg.seq ?? 0))
957
1007
  .filter((seq) => Number.isFinite(seq) && seq > 0);
@@ -1040,22 +1090,43 @@ export class V2E2EECoordinator {
1040
1090
  client._persistSeq(ns);
1041
1091
  }
1042
1092
  const hasServerCursor = cursor !== null && Object.prototype.hasOwnProperty.call(cursor, 'current_seq');
1043
- const ackNeeded = messages.length > 0
1093
+ const ackNeeded = pageMessages.length > 0
1044
1094
  && ackSeq > 0
1095
+ && ackSeq > lastAutoAckSeq
1045
1096
  && ownsCursor
1046
1097
  && (contigAdvanced || (hasServerCursor && ackSeq > cursorCurrentSeq));
1047
1098
  if (ackNeeded) {
1048
- await this.ackGroupV2(gid, ackSeq);
1099
+ const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
1100
+ const canContinuePage = messages.length > 0 && nextAfter > nextAfterSeq && ownsCursor;
1101
+ if (canContinuePage) {
1102
+ pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
1103
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
1104
+ }
1105
+ else {
1106
+ await this.ackGroupV2(gid, ackSeq);
1107
+ lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
1108
+ }
1049
1109
  }
1050
1110
  const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
1051
1111
  if (!ownsCursor)
1052
1112
  break;
1053
- if (messages.length === 0 || nextAfter <= nextAfterSeq || result.has_more === false)
1113
+ const rawCount = messages.length;
1114
+ const canContinuePage = rawCount > 0 && nextAfter > nextAfterSeq;
1115
+ const fullPage = canContinuePage && limit > 0 && rawCount >= limit;
1116
+ const shouldContinue = canContinuePage && (fullPage || pendingAckSeq > 0);
1117
+ if (!shouldContinue)
1054
1118
  break;
1119
+ const tailDelayMs = v2PullTailDelayMs(rawCount, limit);
1120
+ if (tailDelayMs > 0)
1121
+ await v2Sleep(tailDelayMs);
1055
1122
  nextAfterSeq = nextAfter;
1056
1123
  }
1057
1124
  if (pageCount >= maxPages) {
1058
1125
  client._clientLog.warn(`group.v2.pull reached max_pages=${maxPages} group=${gid} after_seq=${nextAfterSeq}`);
1126
+ if (pendingAckSeq > 0) {
1127
+ await this.ackGroupV2(gid, pendingAckSeq);
1128
+ pendingAckSeq = 0;
1129
+ }
1059
1130
  }
1060
1131
  return decrypted;
1061
1132
  }