@agentunion/fastaun-browser 0.5.0 → 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 (140) hide show
  1. package/CHANGELOG.md +550 -464
  2. package/_packed_docs/CHANGELOG-validators.md +147 -0
  3. package/_packed_docs/CHANGELOG.md +550 -464
  4. package/_packed_docs/INDEX.md +201 -177
  5. package/_packed_docs/KITE_DOCS_GUIDE.md +38 -32
  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 -260
  9. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
  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 +139 -746
  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 +117 -171
  19. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +6 -0
  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 -0
  22. package/_packed_docs/protocol/README.md +5 -4
  23. package/_packed_docs/protocol/aun-docs-guide.md +2 -2
  24. package/_packed_docs/protocol/index.md +12 -7
  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 +35 -284
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +473 -442
  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-collab-rpc-manual.md +581 -550
  34. package/_packed_docs/sdk/09-group-rpc-manual.md +367 -433
  35. package/_packed_docs/sdk/09-message-rpc-manual.md +50 -28
  36. package/_packed_docs/sdk/09-payload-reference.md +3 -3
  37. package/_packed_docs/sdk/09-storage-rpc-manual.md +57 -20
  38. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +18 -17
  39. 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
  40. package/_packed_docs/sdk/INDEX.md +25 -24
  41. package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +6 -2
  42. package/dist/agent-md.d.ts.map +1 -1
  43. package/dist/agent-md.js +18 -9
  44. package/dist/agent-md.js.map +1 -1
  45. package/dist/bundle.js +1661 -1180
  46. package/dist/client/delivery.d.ts +13 -2
  47. package/dist/client/delivery.d.ts.map +1 -1
  48. package/dist/client/delivery.js +251 -46
  49. package/dist/client/delivery.js.map +1 -1
  50. package/dist/client/group-state.d.ts.map +1 -1
  51. package/dist/client/group-state.js +36 -14
  52. package/dist/client/group-state.js.map +1 -1
  53. package/dist/client/lifecycle.js +2 -2
  54. package/dist/client/lifecycle.js.map +1 -1
  55. package/dist/client/rpc-pipeline.d.ts +1 -0
  56. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  57. package/dist/client/rpc-pipeline.js +166 -50
  58. package/dist/client/rpc-pipeline.js.map +1 -1
  59. package/dist/client/v2-e2ee.d.ts +14 -1
  60. package/dist/client/v2-e2ee.d.ts.map +1 -1
  61. package/dist/client/v2-e2ee.js +376 -126
  62. package/dist/client/v2-e2ee.js.map +1 -1
  63. package/dist/client.d.ts +5 -4
  64. package/dist/client.d.ts.map +1 -1
  65. package/dist/client.js +187 -46
  66. package/dist/client.js.map +1 -1
  67. package/dist/collab/client.d.ts +8 -0
  68. package/dist/collab/client.d.ts.map +1 -1
  69. package/dist/collab/client.js +12 -0
  70. package/dist/collab/client.js.map +1 -1
  71. package/dist/errors.d.ts +0 -20
  72. package/dist/errors.d.ts.map +1 -1
  73. package/dist/errors.js +8 -51
  74. package/dist/errors.js.map +1 -1
  75. package/dist/facades.d.ts +9 -4
  76. package/dist/facades.d.ts.map +1 -1
  77. package/dist/facades.js +192 -31
  78. package/dist/facades.js.map +1 -1
  79. package/dist/group-fs.d.ts +17 -0
  80. package/dist/group-fs.d.ts.map +1 -1
  81. package/dist/group-fs.js +54 -11
  82. package/dist/group-fs.js.map +1 -1
  83. package/dist/group-id.d.ts +9 -12
  84. package/dist/group-id.d.ts.map +1 -1
  85. package/dist/group-id.js +41 -63
  86. package/dist/group-id.js.map +1 -1
  87. package/dist/index.d.ts +4 -2
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +4 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/keystore/index.d.ts +2 -54
  92. package/dist/keystore/index.d.ts.map +1 -1
  93. package/dist/keystore/indexeddb-identity-store.d.ts +3 -0
  94. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  95. package/dist/keystore/indexeddb-identity-store.js +65 -0
  96. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  97. package/dist/keystore/indexeddb-shared.d.ts +3 -17
  98. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  99. package/dist/keystore/indexeddb-shared.js +4 -47
  100. package/dist/keystore/indexeddb-shared.js.map +1 -1
  101. package/dist/keystore/indexeddb-token-store.d.ts +1 -64
  102. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  103. package/dist/keystore/indexeddb-token-store.js +45 -774
  104. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  105. package/dist/logger.d.ts +2 -0
  106. package/dist/logger.d.ts.map +1 -1
  107. package/dist/logger.js +4 -0
  108. package/dist/logger.js.map +1 -1
  109. package/dist/storage/lowlevel.d.ts +9 -1
  110. package/dist/storage/lowlevel.d.ts.map +1 -1
  111. package/dist/storage/lowlevel.js +12 -1
  112. package/dist/storage/lowlevel.js.map +1 -1
  113. package/dist/storage/vfs.d.ts +22 -0
  114. package/dist/storage/vfs.d.ts.map +1 -1
  115. package/dist/storage/vfs.js +54 -0
  116. package/dist/storage/vfs.js.map +1 -1
  117. package/dist/tools/cross-sdk-agent.js +336 -49
  118. package/dist/tools/cross-sdk-agent.js.map +1 -1
  119. package/dist/transport.d.ts +2 -0
  120. package/dist/transport.d.ts.map +1 -1
  121. package/dist/transport.js +96 -3
  122. package/dist/transport.js.map +1 -1
  123. package/dist/types.d.ts +39 -56
  124. package/dist/types.d.ts.map +1 -1
  125. package/dist/v2/session/session.d.ts +2 -0
  126. package/dist/v2/session/session.d.ts.map +1 -1
  127. package/dist/v2/session/session.js +58 -22
  128. package/dist/v2/session/session.js.map +1 -1
  129. package/dist/v2/state/commitment.d.ts +1 -1
  130. package/dist/v2/state/commitment.d.ts.map +1 -1
  131. package/dist/v2/state/commitment.js +5 -3
  132. package/dist/v2/state/commitment.js.map +1 -1
  133. package/dist/validators.d.ts +35 -0
  134. package/dist/validators.d.ts.map +1 -0
  135. package/dist/validators.js +127 -0
  136. package/dist/validators.js.map +1 -0
  137. package/dist/version.d.ts +1 -1
  138. package/dist/version.js +1 -1
  139. package/package.json +1 -1
  140. package/_packed_docs/collab-gateway-boundary-test-report.md +0 -164
@@ -40,7 +40,9 @@ export declare class MessageDeliveryEngine {
40
40
  onRawGroupMessageCreated(data: EventPayload): void;
41
41
  processAndPublishGroupMessage(data: EventPayload): Promise<void>;
42
42
  autoPullGroupMessages(notification: Message): Promise<void>;
43
- fillP2pGap(): Promise<void>;
43
+ private scheduleP2pGapRetry;
44
+ fillP2pGap(retryAttempt?: number): Promise<void>;
45
+ private fillP2pGapWithPlainPull;
44
46
  fillGroupGap(groupId: string): Promise<void>;
45
47
  fillGroupEventGap(groupId: string): Promise<void>;
46
48
  handleGroupChangedEventSeq(data: JsonObject, groupId: string): Promise<void>;
@@ -51,7 +53,16 @@ export declare class MessageDeliveryEngine {
51
53
  onV2PushNotification(data: EventPayload): Promise<void>;
52
54
  restoreSeqTrackerState(): Promise<void>;
53
55
  migrateSeqStateGroupIds(state: Record<string, number>): Promise<Record<string, number>>;
54
- saveSeqTrackerState(): void;
56
+ saveSeqTrackerState(): Promise<void>;
57
+ persistSeq(ns: string, forceSeq?: number): void;
58
+ flushSeqTrackerPending(): Promise<void>;
59
+ private dropSeqTrackerPending;
60
+ private currentSeqTrackerContext;
61
+ private seqTrackerPending;
62
+ private mergeSeqTrackerPending;
63
+ private scheduleSeqTrackerFlush;
64
+ private cancelSeqTrackerFlushTimer;
65
+ private writeSeqTrackerState;
55
66
  persistRepairedSeq(ns: string): void;
56
67
  clampAckSeq(method: string, field: string, ns: string, seq: number): number;
57
68
  clampAckParams(method: string, params: RpcParams): RpcParams;
@@ -1 +1 @@
1
- {"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/client/delivery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/client/delivery.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,13 @@
1
1
  import { slotIsolationKey } from '../config.js';
2
2
  import { normalizeGroupId } from '../group-id.js';
3
- import { isJsonObject } from '../types.js';
3
+ import { ConnectionState, isJsonObject } from '../types.js';
4
4
  const PUSHED_SEQS_LIMIT = 50_000;
5
5
  const PENDING_ORDERED_LIMIT = 50_000;
6
6
  const GROUP_RECALL_SEEN_LIMIT = 10_000;
7
+ const SEQ_TRACKER_PERSIST_FLUSH_DELAY_MS = 200;
8
+ const P2P_GAP_FILL_RETRY_LIMIT = 12;
9
+ const P2P_GAP_FILL_RETRY_BASE_MS = 1000;
10
+ const P2P_GAP_FILL_RETRY_MAX_MS = 5000;
7
11
  const APP_MESSAGE_ENVELOPE_KEYS = [
8
12
  'module_id', 'message_type', 'type', 'kind', 'version',
9
13
  'from', 'from_aid', 'sender_aid', 'to', 'to_aid', 'group_id',
@@ -24,6 +28,33 @@ const APP_GROUP_EVENT_ENVELOPE_KEYS = [
24
28
  function formatDeliveryError(error) {
25
29
  return error instanceof Error ? error : String(error);
26
30
  }
31
+ function isTransientGapFillError(error) {
32
+ const text = (error instanceof Error ? error.message : String(error)).toLowerCase();
33
+ return text.includes('no_service')
34
+ || text.includes('service plane unavailable')
35
+ || text.includes('transport not connected')
36
+ || text.includes('transport closed')
37
+ || text.includes('websocket closed')
38
+ || text.includes('websocket is not open')
39
+ || text.includes('connection closed')
40
+ || text.includes('socket closed');
41
+ }
42
+ function p2pAppEventFromPlainPullMessage(message) {
43
+ const payload = message.payload;
44
+ const payloadType = isJsonObject(payload)
45
+ ? String(payload.type ?? '').trim()
46
+ : '';
47
+ if (payloadType === 'message.recalled' || payloadType === 'message.recall' || message.type === 'message.recalled') {
48
+ return {
49
+ event: 'message.recalled',
50
+ payload: {
51
+ ...message,
52
+ ...(isJsonObject(payload) ? payload : {}),
53
+ },
54
+ };
55
+ }
56
+ return { event: 'message.received', payload: message };
57
+ }
27
58
  export class MessageDeliveryEngine {
28
59
  runtime;
29
60
  constructor(runtime) {
@@ -111,7 +142,8 @@ export class MessageDeliveryEngine {
111
142
  const eventPayload = payload;
112
143
  client._groupState?.handleGroupChangedV2Membership?.(eventPayload);
113
144
  if (eventPayload.action === 'dissolved') {
114
- const groupId = normalizeGroupId(String(eventPayload.group_id ?? '')) || String(eventPayload.group_id ?? '').trim();
145
+ const rawGroupId = eventPayload.group_aid ?? eventPayload.group_id ?? '';
146
+ const groupId = normalizeGroupId(String(rawGroupId)) || String(rawGroupId).trim();
115
147
  if (groupId)
116
148
  client._cleanupDissolvedGroup?.(groupId);
117
149
  }
@@ -510,7 +542,7 @@ export class MessageDeliveryEngine {
510
542
  }).catch((e) => { client._clientLog.warn('group recall auto-ack failed: group=' + groupId, e); });
511
543
  }
512
544
  if (contig !== contigBefore)
513
- this.saveSeqTrackerState();
545
+ this.persistSeq(ns);
514
546
  }
515
547
  async publishAppEvent(event, payload) {
516
548
  const client = this.runtime.client;
@@ -597,7 +629,7 @@ export class MessageDeliveryEngine {
597
629
  }).catch((e) => { client._clientLog.warn(`P2P auto-ack failed:${String(e)}`); });
598
630
  }
599
631
  if (contigAfter !== contigBefore)
600
- this.saveSeqTrackerState();
632
+ this.persistSeq(ns);
601
633
  if (encryptedPush)
602
634
  return;
603
635
  }
@@ -675,7 +707,7 @@ export class MessageDeliveryEngine {
675
707
  }).catch((e) => { client._clientLog.warn('group recall auto-ack failed: group=' + groupId, e); });
676
708
  }
677
709
  if (contigAfter !== contigBefore)
678
- this.saveSeqTrackerState();
710
+ this.persistSeq(ns);
679
711
  return;
680
712
  }
681
713
  const published = encryptedPush
@@ -698,7 +730,7 @@ export class MessageDeliveryEngine {
698
730
  }).catch((e) => { client._clientLog.warn('group message auto-ack failed: group=' + groupId, e); });
699
731
  }
700
732
  if (contigAfter !== contigBefore)
701
- this.saveSeqTrackerState();
733
+ this.persistSeq(ns);
702
734
  if (encryptedPush)
703
735
  return;
704
736
  }
@@ -785,9 +817,26 @@ export class MessageDeliveryEngine {
785
817
  }
786
818
  await client._publishAppEvent('group.message_created', notification);
787
819
  }
788
- async fillP2pGap() {
820
+ scheduleP2pGapRetry(ns, retryAttempt) {
789
821
  const client = this.runtime.client;
790
- if (client._state !== 'connected' || client._closing)
822
+ if (retryAttempt > P2P_GAP_FILL_RETRY_LIMIT)
823
+ return;
824
+ const retryKey = `p2p_pull_retry:${ns}`;
825
+ if (client._gapFillDone.has(retryKey))
826
+ return;
827
+ const delayMs = Math.min(P2P_GAP_FILL_RETRY_BASE_MS * retryAttempt, P2P_GAP_FILL_RETRY_MAX_MS);
828
+ client._gapFillDone.add(retryKey);
829
+ client._clientLog.debug(`P2P message gap-fill retry scheduled: ns=${ns} attempt=${retryAttempt} delay_ms=${delayMs}`);
830
+ globalThis.setTimeout(() => {
831
+ client._gapFillDone.delete(retryKey);
832
+ if (client.state !== ConnectionState.READY || client._closing)
833
+ return;
834
+ client._safeAsync(this.fillP2pGap(retryAttempt));
835
+ }, delayMs);
836
+ }
837
+ async fillP2pGap(retryAttempt = 0) {
838
+ const client = this.runtime.client;
839
+ if (client.state !== ConnectionState.READY || client._closing)
791
840
  return;
792
841
  if (!client._aid)
793
842
  return;
@@ -805,19 +854,59 @@ export class MessageDeliveryEngine {
805
854
  this.prunePushedSeqs(ns);
806
855
  }
807
856
  catch (exc) {
808
- client._clientLog.warn(`P2P message gap-fill failed:${String(formatDeliveryError(exc))}`);
857
+ const transient = isTransientGapFillError(exc);
858
+ if (transient) {
859
+ try {
860
+ filled = await this.fillP2pGapWithPlainPull(ns, afterSeq);
861
+ this.prunePushedSeqs(ns);
862
+ client._clientLog.warn(`P2P message gap-fill V2 unavailable, used plain pull fallback:${String(formatDeliveryError(exc))}`);
863
+ }
864
+ catch (fallbackExc) {
865
+ client._clientLog.warn(`P2P message gap-fill plain fallback failed:${String(formatDeliveryError(fallbackExc))}`);
866
+ this.scheduleP2pGapRetry(ns, retryAttempt + 1);
867
+ }
868
+ }
869
+ else {
870
+ client._clientLog.warn(`P2P message gap-fill failed:${String(formatDeliveryError(exc))}`);
871
+ }
809
872
  }
810
873
  finally {
811
874
  client._gapFillDone.delete(dedupKey);
812
875
  this.runtime.delivery.setGapFillActive(false);
813
- if (filled > 0 && client._seqTracker.getContiguousSeq(ns) > afterSeq) {
814
- client._safeAsync(this.fillP2pGap());
876
+ }
877
+ }
878
+ async fillP2pGapWithPlainPull(ns, afterSeq) {
879
+ const client = this.runtime.client;
880
+ const params = {
881
+ after_seq: afterSeq,
882
+ limit: 50,
883
+ device_id: client._deviceId,
884
+ slot_id: client._slotId,
885
+ _rpc_background: true,
886
+ };
887
+ const raw = await client._transport.call('message.pull', params, undefined, undefined, true);
888
+ const result = typeof client._rpcPipeline?.postprocessResult === 'function'
889
+ ? await client._rpcPipeline.postprocessResult('message.pull', params, raw)
890
+ : raw;
891
+ const messages = (isJsonObject(result) && Array.isArray(result.messages))
892
+ ? result.messages
893
+ : [];
894
+ let published = 0;
895
+ for (const item of messages) {
896
+ if (!isJsonObject(item))
897
+ continue;
898
+ const msg = item;
899
+ const seq = Number(msg.seq ?? 0);
900
+ const appEvent = p2pAppEventFromPlainPullMessage(msg);
901
+ if (await this.publishPulledMessage(appEvent.event, ns, seq, appEvent.payload)) {
902
+ published += 1;
815
903
  }
816
904
  }
905
+ return published;
817
906
  }
818
907
  async fillGroupGap(groupId) {
819
908
  const client = this.runtime.client;
820
- if (client._state !== 'connected' || client._closing)
909
+ if (client.state !== ConnectionState.READY || client._closing)
821
910
  return;
822
911
  groupId = normalizeGroupId(groupId) || String(groupId ?? '').trim();
823
912
  if (!groupId)
@@ -848,7 +937,10 @@ export class MessageDeliveryEngine {
848
937
  }
849
938
  async fillGroupEventGap(groupId) {
850
939
  const client = this.runtime.client;
851
- if (client._state !== 'connected' || client._closing)
940
+ if (client.state !== ConnectionState.READY || client._closing)
941
+ return;
942
+ groupId = normalizeGroupId(groupId) || String(groupId ?? '').trim();
943
+ if (!groupId)
852
944
  return;
853
945
  const ns = `group_event:${groupId}`;
854
946
  const afterSeq = client._seqTracker.getContiguousSeq(ns);
@@ -918,7 +1010,7 @@ export class MessageDeliveryEngine {
918
1010
  const ackContig = client._seqTracker.getContiguousSeq(ns);
919
1011
  await this.drainOrderedMessages(ns);
920
1012
  if (ackContig !== pageContigBefore && !hasDissolvedEvent) {
921
- this.saveSeqTrackerState();
1013
+ this.persistSeq(ns);
922
1014
  }
923
1015
  if (eventObjects.length > 0 && ackContig > 0 && ackContig !== pageContigBefore) {
924
1016
  const ackSeq = this.clampAckSeq('group.ack_events', 'event_seq', ns, ackContig);
@@ -949,6 +1041,7 @@ export class MessageDeliveryEngine {
949
1041
  }
950
1042
  async handleGroupChangedEventSeq(data, groupId) {
951
1043
  const client = this.runtime.client;
1044
+ groupId = normalizeGroupId(groupId) || String(groupId ?? '').trim();
952
1045
  let needPull = false;
953
1046
  const rawEventSeq = data.event_seq;
954
1047
  const eventSeq = Number(rawEventSeq);
@@ -983,7 +1076,7 @@ export class MessageDeliveryEngine {
983
1076
  await this.drainOrderedMessages(ns);
984
1077
  if (ackContig > 0 && ackContig !== contigBefore) {
985
1078
  if (data.action !== 'dissolved')
986
- this.saveSeqTrackerState();
1079
+ this.persistSeq(ns);
987
1080
  const ackSeq = this.clampAckSeq('group.ack_events', 'event_seq', ns, ackContig);
988
1081
  client._transport.call('group.ack_events', {
989
1082
  group_id: groupId,
@@ -1033,7 +1126,7 @@ export class MessageDeliveryEngine {
1033
1126
  this.runtime.delivery.setOnlineUnreadHintDrainActive(true);
1034
1127
  try {
1035
1128
  while (client._onlineUnreadHintQueue.size > 0) {
1036
- if (client.state !== 'ready')
1129
+ if (client.state !== ConnectionState.READY)
1037
1130
  return;
1038
1131
  if (client._sessionOptions?.background_sync === false)
1039
1132
  return;
@@ -1147,7 +1240,7 @@ export class MessageDeliveryEngine {
1147
1240
  const published = await client._publishOrderedMessage('message.received', ns, pushSeq, decrypted);
1148
1241
  const newContig = client._seqTracker.getContiguousSeq(ns);
1149
1242
  if (newContig !== contigBefore) {
1150
- client._saveSeqTrackerState();
1243
+ this.persistSeq(ns);
1151
1244
  }
1152
1245
  if (newContig > 0 && newContig !== contigBefore) {
1153
1246
  const ackSeq = this.clampAckSeq('message.v2.ack', 'up_to_seq', ns, newContig);
@@ -1309,50 +1402,141 @@ export class MessageDeliveryEngine {
1309
1402
  }
1310
1403
  return newState;
1311
1404
  }
1312
- saveSeqTrackerState() {
1405
+ async saveSeqTrackerState() {
1313
1406
  const client = this.runtime.client;
1314
- if (!client._aid)
1407
+ const context = this.currentSeqTrackerContext();
1408
+ if (!context) {
1409
+ await this.flushSeqTrackerPending();
1315
1410
  return;
1411
+ }
1316
1412
  const state = client._seqTracker.exportState();
1317
- if (Object.keys(state).length === 0)
1413
+ const pending = this.seqTrackerPending();
1414
+ if (pending.size > 0 && client._seqTrackerPendingPersistContext === context) {
1415
+ const liveNamespaces = new Set(Object.keys(state));
1416
+ for (const ns of [...pending.keys()]) {
1417
+ if (!liveNamespaces.has(ns))
1418
+ pending.delete(ns);
1419
+ }
1420
+ if (pending.size === 0)
1421
+ client._seqTrackerPendingPersistContext = null;
1422
+ }
1423
+ if (Object.keys(state).length > 0)
1424
+ this.mergeSeqTrackerPending(context, state);
1425
+ await this.flushSeqTrackerPending();
1426
+ }
1427
+ persistSeq(ns, forceSeq) {
1428
+ const client = this.runtime.client;
1429
+ const context = this.currentSeqTrackerContext();
1430
+ if (!context) {
1431
+ void this.flushSeqTrackerPending();
1432
+ return;
1433
+ }
1434
+ const seq = forceSeq ?? client._seqTracker.getContiguousSeq(ns);
1435
+ if (!ns || !Number.isFinite(seq) || seq <= 0)
1436
+ return;
1437
+ if (forceSeq !== undefined) {
1438
+ client._seqTracker.forceContiguousSeq(ns, seq);
1439
+ }
1440
+ this.mergeSeqTrackerPending(context, { [ns]: seq });
1441
+ this.scheduleSeqTrackerFlush();
1442
+ }
1443
+ async flushSeqTrackerPending() {
1444
+ const client = this.runtime.client;
1445
+ this.cancelSeqTrackerFlushTimer();
1446
+ const context = client._seqTrackerPendingPersistContext;
1447
+ const pending = this.seqTrackerPending();
1448
+ if (!context || pending.size === 0) {
1449
+ client._seqTrackerPendingPersistContext = null;
1450
+ return;
1451
+ }
1452
+ const [aid, deviceId, slotId] = JSON.parse(context);
1453
+ const state = Object.fromEntries(pending.entries());
1454
+ pending.clear();
1455
+ client._seqTrackerPendingPersistContext = null;
1456
+ await this.writeSeqTrackerState(aid, deviceId, slotId, state);
1457
+ }
1458
+ dropSeqTrackerPending(ns) {
1459
+ const client = this.runtime.client;
1460
+ const pending = this.seqTrackerPending();
1461
+ pending.delete(ns);
1462
+ if (pending.size === 0) {
1463
+ client._seqTrackerPendingPersistContext = null;
1464
+ this.cancelSeqTrackerFlushTimer();
1465
+ }
1466
+ }
1467
+ currentSeqTrackerContext() {
1468
+ const client = this.runtime.client;
1469
+ if (!client._aid)
1470
+ return null;
1471
+ return JSON.stringify([client._aid, client._deviceId, client._slotId]);
1472
+ }
1473
+ seqTrackerPending() {
1474
+ const client = this.runtime.client;
1475
+ if (!(client._seqTrackerPendingPersist instanceof Map)) {
1476
+ client._seqTrackerPendingPersist = new Map();
1477
+ }
1478
+ return client._seqTrackerPendingPersist;
1479
+ }
1480
+ mergeSeqTrackerPending(context, state) {
1481
+ const client = this.runtime.client;
1482
+ const pending = this.seqTrackerPending();
1483
+ const pendingContext = client._seqTrackerPendingPersistContext;
1484
+ if (pendingContext && pendingContext !== context && pending.size > 0) {
1485
+ void this.flushSeqTrackerPending();
1486
+ }
1487
+ client._seqTrackerPendingPersistContext = context;
1488
+ for (const [ns, seq] of Object.entries(state)) {
1489
+ const seqNum = Number(seq);
1490
+ if (ns && Number.isFinite(seqNum) && seqNum > 0) {
1491
+ pending.set(ns, seqNum);
1492
+ }
1493
+ }
1494
+ }
1495
+ scheduleSeqTrackerFlush() {
1496
+ const client = this.runtime.client;
1497
+ const pending = this.seqTrackerPending();
1498
+ if (pending.size === 0)
1499
+ return;
1500
+ if (client._seqTrackerFlushTimer)
1501
+ return;
1502
+ client._seqTrackerFlushTimer = setTimeout(() => {
1503
+ client._seqTrackerFlushTimer = null;
1504
+ void this.flushSeqTrackerPending();
1505
+ }, SEQ_TRACKER_PERSIST_FLUSH_DELAY_MS);
1506
+ }
1507
+ cancelSeqTrackerFlushTimer() {
1508
+ const client = this.runtime.client;
1509
+ if (client._seqTrackerFlushTimer) {
1510
+ clearTimeout(client._seqTrackerFlushTimer);
1511
+ client._seqTrackerFlushTimer = null;
1512
+ }
1513
+ }
1514
+ async writeSeqTrackerState(aid, deviceId, slotId, state) {
1515
+ const client = this.runtime.client;
1516
+ if (!aid || Object.keys(state).length === 0)
1318
1517
  return;
1319
1518
  try {
1320
1519
  const saveFn = client._tokenStore.saveSeq?.bind(client._tokenStore);
1321
1520
  if (typeof saveFn === 'function') {
1322
- for (const [ns, seq] of Object.entries(state)) {
1323
- saveFn(client._aid, client._deviceId, client._slotId, ns, seq).catch((exc) => {
1324
- client._dispatcher.publish('seq_tracker.persist_error', {
1325
- phase: 'save',
1326
- aid: client._aid,
1327
- device_id: client._deviceId,
1328
- slot_id: client._slotId,
1329
- error: String(exc),
1330
- }).catch(() => { });
1331
- });
1332
- }
1521
+ await Promise.all(Object.entries(state).map(([ns, seq]) => saveFn(aid, deviceId, slotId, ns, seq)));
1333
1522
  return;
1334
1523
  }
1335
1524
  if (typeof client._tokenStore.updateInstanceState === 'function') {
1336
- client._tokenStore.updateInstanceState(client._aid, client._deviceId, client._slotId, (current) => {
1337
- current.seq_tracker_state = state;
1525
+ await client._tokenStore.updateInstanceState(aid, deviceId, slotId, (current) => {
1526
+ const existing = isJsonObject(current.seq_tracker_state)
1527
+ ? { ...current.seq_tracker_state }
1528
+ : {};
1529
+ current.seq_tracker_state = { ...existing, ...state };
1338
1530
  return current;
1339
- }).catch((exc) => {
1340
- client._dispatcher.publish('seq_tracker.persist_error', {
1341
- phase: 'save',
1342
- aid: client._aid,
1343
- device_id: client._deviceId,
1344
- slot_id: client._slotId,
1345
- error: String(exc),
1346
- }).catch(() => { });
1347
1531
  });
1348
1532
  }
1349
1533
  }
1350
1534
  catch (exc) {
1351
1535
  client._dispatcher.publish('seq_tracker.persist_error', {
1352
1536
  phase: 'save',
1353
- aid: client._aid,
1354
- device_id: client._deviceId,
1355
- slot_id: client._slotId,
1537
+ aid,
1538
+ device_id: deviceId,
1539
+ slot_id: slotId,
1356
1540
  error: String(exc),
1357
1541
  }).catch(() => { });
1358
1542
  }
@@ -1362,6 +1546,7 @@ export class MessageDeliveryEngine {
1362
1546
  if (!client._aid || !ns)
1363
1547
  return;
1364
1548
  const seq = client._seqTracker.getContiguousSeq(ns);
1549
+ this.dropSeqTrackerPending(ns);
1365
1550
  try {
1366
1551
  if (seq > 0 && typeof client._tokenStore.saveSeq === 'function') {
1367
1552
  client._tokenStore.saveSeq(client._aid, client._deviceId, client._slotId, ns, seq).catch((exc) => {
@@ -1376,8 +1561,21 @@ export class MessageDeliveryEngine {
1376
1561
  });
1377
1562
  return;
1378
1563
  }
1564
+ if (seq <= 0 && typeof client._tokenStore.updateInstanceState === 'function') {
1565
+ Promise.resolve(client._tokenStore.updateInstanceState(client._aid, client._deviceId, client._slotId, (current) => {
1566
+ if (isJsonObject(current.seq_tracker_state)) {
1567
+ const next = { ...current.seq_tracker_state };
1568
+ delete next[ns];
1569
+ current.seq_tracker_state = next;
1570
+ }
1571
+ return current;
1572
+ })).catch((exc) => {
1573
+ client._clientLog.debug(`delete repaired seq failed: ns=${ns} err=${formatDeliveryError(exc)}`);
1574
+ });
1575
+ return;
1576
+ }
1379
1577
  if (seq > 0) {
1380
- this.saveSeqTrackerState();
1578
+ void this.saveSeqTrackerState();
1381
1579
  }
1382
1580
  }
1383
1581
  catch (exc) {
@@ -1439,6 +1637,7 @@ export class MessageDeliveryEngine {
1439
1637
  const ready = [...queue.keys()]
1440
1638
  .filter((seq) => seq <= contig && (beforeSeq === undefined || seq < beforeSeq))
1441
1639
  .sort((a, b) => a - b);
1640
+ let delivered = false;
1442
1641
  for (const seq of ready) {
1443
1642
  const item = queue.get(seq);
1444
1643
  queue.delete(seq);
@@ -1446,9 +1645,13 @@ export class MessageDeliveryEngine {
1446
1645
  continue;
1447
1646
  await this.publishOrderedQueueItem(ns, item.event, seq, item.payload);
1448
1647
  this.markPublishedSeq(ns, seq);
1648
+ delivered = true;
1449
1649
  }
1450
- if (queue.size === 0)
1650
+ if (queue.size === 0) {
1451
1651
  client._pendingOrderedMsgs.delete(ns);
1652
+ if (delivered)
1653
+ await this.saveSeqTrackerState();
1654
+ }
1452
1655
  }
1453
1656
  async publishOrderedMessage(event, ns, seq, payload) {
1454
1657
  const client = this.runtime.client;
@@ -1479,6 +1682,8 @@ export class MessageDeliveryEngine {
1479
1682
  await this.publishOrderedQueueItem(ns, event, seqNum, payload);
1480
1683
  this.markPublishedSeq(ns, seqNum);
1481
1684
  await this.drainOrderedMessages(ns);
1685
+ if (!client._pendingOrderedMsgs.get(ns))
1686
+ await this.saveSeqTrackerState();
1482
1687
  return true;
1483
1688
  }
1484
1689
  async publishPulledMessage(event, ns, seq, payload) {