@agentunion/fastaun 0.4.13 → 0.5.1
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/CHANGELOG.md +547 -393
- package/_packed_docs/CHANGELOG-validators.md +144 -0
- package/_packed_docs/CHANGELOG.md +547 -393
- package/_packed_docs/INDEX.md +159 -84
- package/_packed_docs/KITE_DOCS_GUIDE.md +48 -31
- package/_packed_docs/agent.md/SCHEMA.md +2 -0
- package/_packed_docs/agent.md/examples/codeagent-claudecode.md +2 -0
- package/_packed_docs/agent.md/examples/human-developer.md +2 -0
- package/_packed_docs/agent.md/examples/openclaw-lobster.md +2 -0
- package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +2 -0
- 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 +2 -0
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +266 -686
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
- package/_packed_docs/design/2026-05-22-aun-rpc-trace-enhancement.md +2 -0
- package/_packed_docs/design/AUNClient/346/213/206/345/210/206/351/207/215/346/236/204/346/211/247/350/241/214/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/design/E2EE_V2/347/256/200/345/214/226/344/270/2721DH/345/212/240Per-AID_Wrap/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/design//350/267/250/350/257/255/350/250/200/345/256/271/345/231/250E2E/346/265/213/350/257/225/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -0
- 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 +2 -0
- 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 +2 -0
- package/_packed_docs/protocol/02-/350/257/201/344/271/246/344/270/216/344/277/241/344/273/273/344/275/223/347/263/273.md +2 -0
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +2 -0
- package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +2 -0
- 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 +2 -0
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +296 -900
- package/_packed_docs/protocol/08-AUN-E2EE.md +2 -0
- package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +2 -0
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +66 -173
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +55 -0
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +2 -0
- package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +2 -0
- 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 +2 -0
- 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
- package/_packed_docs/protocol/README.md +4 -1
- package/_packed_docs/protocol/agent.md/SCHEMA.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/human-developer.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +2 -0
- package/_packed_docs/protocol/aun-docs-guide.md +2 -0
- package/_packed_docs/protocol/index.md +10 -3
- package/_packed_docs/protocol//350/215/211/346/241/210-agent.md/347/255/276/345/220/215/345/215/217/350/256/256.md +2 -0
- 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 +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225C-/347/247/201/351/222/245/347/256/241/347/220/206/344/270/216/350/272/253/344/273/275/346/201/242/345/244/215.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225D-Root_CA_/346/262/273/347/220/206/346/234/272/345/210/266.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225E-Root_CA_/345/207/206/345/205/245/346/265/201/347/250/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225F-Issuer_CA_/347/224/263/350/257/267/346/265/201/347/250/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225G-AID_/345/255/244/345/204/277/351/242/204/351/230/262/344/270/216/346/225/221/346/217/264/346/234/272/345/210/266.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225H-Identity/346/234/215/345/212/241/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225I-/350/267/250/345/237/237/346/266/210/346/201/257/350/267/257/347/224/261/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225K-Agent_Web/345/217/221/347/216/260/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225N-/345/210/206/345/270/203/345/274/217Trace/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +2 -0
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +2 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +2 -0
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -252
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +219 -177
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +4 -1
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +2 -0
- package/_packed_docs/sdk/09-collab-rpc-manual.md +581 -0
- package/_packed_docs/sdk/09-custody-api-manual.md +2 -0
- package/_packed_docs/sdk/09-group-rpc-manual.md +301 -634
- package/_packed_docs/sdk/09-message-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-payload-reference.md +2 -0
- package/_packed_docs/sdk/09-proxy-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-storage-rpc-manual.md +984 -274
- package/_packed_docs/sdk/09-stream-rpc-manual.md +2 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +36 -23
- 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 +2 -0
- package/_packed_docs/sdk/INDEX.md +47 -30
- package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/sdk/README.md +17 -15
- package/dist/aid-store.d.ts +25 -0
- package/dist/aid-store.js +80 -0
- package/dist/aid-store.js.map +1 -1
- package/dist/client/delivery.d.ts +11 -0
- package/dist/client/delivery.js +208 -25
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +33 -11
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +1 -0
- package/dist/client/rpc-pipeline.js +177 -65
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +6 -1
- package/dist/client/v2-e2ee.js +199 -130
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +37 -1
- package/dist/client.js +491 -44
- package/dist/client.js.map +1 -1
- package/dist/collab/client.d.ts +46 -0
- package/dist/collab/client.js +136 -0
- package/dist/collab/client.js.map +1 -0
- package/dist/collab/errors.d.ts +15 -0
- package/dist/collab/errors.js +60 -0
- package/dist/collab/errors.js.map +1 -0
- package/dist/collab/index.d.ts +3 -0
- package/dist/collab/index.js +4 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/types.d.ts +110 -0
- package/dist/collab/types.js +2 -0
- package/dist/collab/types.js.map +1 -0
- package/dist/crypto.d.ts +2 -0
- package/dist/crypto.js +6 -0
- package/dist/crypto.js.map +1 -1
- package/dist/errors.d.ts +0 -12
- package/dist/errors.js +9 -25
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +94 -0
- package/dist/facades.js +255 -0
- package/dist/facades.js.map +1 -0
- package/dist/group-fs.d.ts +122 -0
- package/dist/group-fs.js +467 -0
- package/dist/group-fs.js.map +1 -0
- package/dist/group-id.d.ts +9 -12
- package/dist/group-id.js +41 -63
- package/dist/group-id.js.map +1 -1
- package/dist/group-resources.d.ts +31 -0
- package/dist/group-resources.js +84 -0
- package/dist/group-resources.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/aid-db.d.ts +1 -0
- package/dist/keystore/aid-db.js +43 -43
- package/dist/keystore/aid-db.js.map +1 -1
- package/dist/keystore/local-identity-store.d.ts +16 -0
- package/dist/keystore/local-identity-store.js +190 -18
- package/dist/keystore/local-identity-store.js.map +1 -1
- package/dist/keystore/local-token-store.d.ts +0 -13
- package/dist/keystore/local-token-store.js +0 -105
- package/dist/keystore/local-token-store.js.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -1
- package/dist/register-flow.d.ts +1 -0
- package/dist/register-flow.js +3 -0
- package/dist/register-flow.js.map +1 -1
- package/dist/service-proxy.d.ts +1 -0
- package/dist/service-proxy.js +17 -4
- package/dist/service-proxy.js.map +1 -1
- package/dist/storage/errors.d.ts +27 -0
- package/dist/storage/errors.js +65 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/lowlevel.d.ts +321 -0
- package/dist/storage/lowlevel.js +475 -0
- package/dist/storage/lowlevel.js.map +1 -0
- package/dist/storage/types.d.ts +57 -0
- package/dist/storage/types.js +116 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/vfs.d.ts +166 -0
- package/dist/storage/vfs.js +524 -0
- package/dist/storage/vfs.js.map +1 -0
- package/dist/tools/cross-sdk-agent.js +708 -1
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +5 -0
- package/dist/transport.js +124 -21
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +38 -0
- package/dist/v2/session/session.d.ts +2 -0
- package/dist/v2/session/session.js +53 -23
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts +1 -1
- package/dist/v2/state/commitment.js +4 -2
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/validators.d.ts +32 -0
- package/dist/validators.js +128 -0
- package/dist/validators.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/client/delivery.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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;
|
|
7
8
|
const APP_MESSAGE_ENVELOPE_KEYS = [
|
|
8
9
|
'module_id', 'message_type', 'type', 'kind', 'version',
|
|
9
10
|
'from', 'from_aid', 'sender_aid', 'to', 'to_aid', 'group_id',
|
|
@@ -95,7 +96,8 @@ export class MessageDeliveryEngine {
|
|
|
95
96
|
const eventPayload = payload;
|
|
96
97
|
client._groupState?.handleGroupChangedV2Membership?.(eventPayload);
|
|
97
98
|
if (eventPayload.action === 'dissolved') {
|
|
98
|
-
const
|
|
99
|
+
const rawGroupId = eventPayload.group_aid ?? eventPayload.group_id ?? '';
|
|
100
|
+
const groupId = normalizeGroupId(String(rawGroupId)) || String(rawGroupId).trim();
|
|
99
101
|
if (groupId)
|
|
100
102
|
client._cleanupDissolvedGroup?.(groupId);
|
|
101
103
|
}
|
|
@@ -495,7 +497,7 @@ export class MessageDeliveryEngine {
|
|
|
495
497
|
.catch((e) => { client._clientLog.debug(`group recall auto-ack failed: group=${groupId} ${formatDeliveryError(e)}`); });
|
|
496
498
|
}
|
|
497
499
|
if (contig !== contigBefore)
|
|
498
|
-
this.
|
|
500
|
+
this.persistSeq(ns);
|
|
499
501
|
}
|
|
500
502
|
publishAppEvent(event, payload, source = 'direct') {
|
|
501
503
|
const client = this.runtime.client;
|
|
@@ -565,6 +567,8 @@ export class MessageDeliveryEngine {
|
|
|
565
567
|
}
|
|
566
568
|
logMessageDebug(stage, source, event, message, opts = {}) {
|
|
567
569
|
const client = this.runtime.client;
|
|
570
|
+
if (client._isMessageDebugEnabled?.() === false)
|
|
571
|
+
return;
|
|
568
572
|
const record = {
|
|
569
573
|
stage,
|
|
570
574
|
source,
|
|
@@ -666,7 +670,7 @@ export class MessageDeliveryEngine {
|
|
|
666
670
|
.catch((e) => { client._clientLog.debug(`P2P auto-ack failed: ${formatDeliveryError(e)}`); });
|
|
667
671
|
}
|
|
668
672
|
if (contigAfter !== contigBefore)
|
|
669
|
-
this.
|
|
673
|
+
this.persistSeq(ns);
|
|
670
674
|
if (encryptedPush)
|
|
671
675
|
return;
|
|
672
676
|
}
|
|
@@ -743,7 +747,7 @@ export class MessageDeliveryEngine {
|
|
|
743
747
|
.catch((e) => { client._clientLog.debug(`group recall auto-ack failed: group=${groupId} ${formatDeliveryError(e)}`); });
|
|
744
748
|
}
|
|
745
749
|
if (contigAfter !== contigBefore)
|
|
746
|
-
this.
|
|
750
|
+
this.persistSeq(ns);
|
|
747
751
|
void published;
|
|
748
752
|
return;
|
|
749
753
|
}
|
|
@@ -766,7 +770,7 @@ export class MessageDeliveryEngine {
|
|
|
766
770
|
.catch((e) => { client._clientLog.debug(`group message auto-ack failed: group=${groupId} ${formatDeliveryError(e)}`); });
|
|
767
771
|
}
|
|
768
772
|
if (contigAfter !== contigBefore)
|
|
769
|
-
this.
|
|
773
|
+
this.persistSeq(ns);
|
|
770
774
|
if (encryptedPush)
|
|
771
775
|
return;
|
|
772
776
|
}
|
|
@@ -822,7 +826,7 @@ export class MessageDeliveryEngine {
|
|
|
822
826
|
this.prunePushedSeqs(ns);
|
|
823
827
|
if (client._seqTracker.getContiguousSeq(ns) !== afterSeq) {
|
|
824
828
|
await this.drainOrderedMessages(ns, undefined, true);
|
|
825
|
-
this.
|
|
829
|
+
this.persistSeq(ns);
|
|
826
830
|
}
|
|
827
831
|
const contig = client._seqTracker.getContiguousSeq(ns);
|
|
828
832
|
if (contig > 0 && contig !== afterSeq) {
|
|
@@ -836,9 +840,6 @@ export class MessageDeliveryEngine {
|
|
|
836
840
|
finally {
|
|
837
841
|
client._gapFillDone.delete(dedupKey);
|
|
838
842
|
client._releasePullGate(ns, token);
|
|
839
|
-
if (filled > 0 && client._seqTracker.getContiguousSeq(ns) > afterSeq) {
|
|
840
|
-
void this.fillP2pGap();
|
|
841
|
-
}
|
|
842
843
|
}
|
|
843
844
|
}
|
|
844
845
|
async fillGroupGap(groupId) {
|
|
@@ -865,7 +866,7 @@ export class MessageDeliveryEngine {
|
|
|
865
866
|
this.prunePushedSeqs(ns);
|
|
866
867
|
if (client._seqTracker.getContiguousSeq(ns) !== afterSeq) {
|
|
867
868
|
await this.drainOrderedMessages(ns, undefined, true);
|
|
868
|
-
this.
|
|
869
|
+
this.persistSeq(ns);
|
|
869
870
|
}
|
|
870
871
|
client._clientLog.debug(`group message gap fill done: group=${groupId}, after_seq=${afterSeq}, filled=${filled}`);
|
|
871
872
|
}
|
|
@@ -910,6 +911,7 @@ export class MessageDeliveryEngine {
|
|
|
910
911
|
device_id: client._deviceId,
|
|
911
912
|
limit: 50,
|
|
912
913
|
_pull_gate_locked: true,
|
|
914
|
+
_rpc_background: true,
|
|
913
915
|
});
|
|
914
916
|
if (!isJsonObject(result))
|
|
915
917
|
return;
|
|
@@ -962,7 +964,7 @@ export class MessageDeliveryEngine {
|
|
|
962
964
|
const ackContig = client._seqTracker.getContiguousSeq(ns);
|
|
963
965
|
await this.drainOrderedMessages(ns);
|
|
964
966
|
if (ackContig !== pageContigBefore && !hasDissolvedEvent) {
|
|
965
|
-
this.
|
|
967
|
+
this.persistSeq(ns);
|
|
966
968
|
}
|
|
967
969
|
if (eventObjects.length > 0 && ackContig > 0 && ackContig !== pageContigBefore) {
|
|
968
970
|
const ackSeq = this.clampAckSeq('group.ack_events', 'event_seq', ns, ackContig);
|
|
@@ -998,6 +1000,7 @@ export class MessageDeliveryEngine {
|
|
|
998
1000
|
}
|
|
999
1001
|
async handleGroupChangedEventSeq(data, groupId) {
|
|
1000
1002
|
const client = this.runtime.client;
|
|
1003
|
+
groupId = normalizeGroupId(groupId) || String(groupId ?? '').trim();
|
|
1001
1004
|
let needPull = false;
|
|
1002
1005
|
const rawEventSeq = data.event_seq;
|
|
1003
1006
|
const eventSeq = Number(rawEventSeq);
|
|
@@ -1017,6 +1020,7 @@ export class MessageDeliveryEngine {
|
|
|
1017
1020
|
const contigBefore = client._seqTracker.getContiguousSeq(ns);
|
|
1018
1021
|
if (eventSeq <= contigBefore || client._pushedSeqs.get(ns)?.has(eventSeq)) {
|
|
1019
1022
|
client._clientLog.debug(`group.changed skipped duplicate/stale: group=${groupId}, event_seq=${eventSeq}, contiguous=${contigBefore}`);
|
|
1023
|
+
this.fireGroupEventAck(groupId, Math.min(eventSeq, contigBefore > 0 ? contigBefore : eventSeq), 'covered push');
|
|
1020
1024
|
return;
|
|
1021
1025
|
}
|
|
1022
1026
|
this.enqueueOrderedMessage(ns, 'group.changed', eventSeq, data);
|
|
@@ -1025,7 +1029,7 @@ export class MessageDeliveryEngine {
|
|
|
1025
1029
|
await this.drainOrderedMessages(ns);
|
|
1026
1030
|
if (ackContig > 0 && ackContig !== contigBefore) {
|
|
1027
1031
|
if (data.action !== 'dissolved')
|
|
1028
|
-
this.
|
|
1032
|
+
this.persistSeq(ns);
|
|
1029
1033
|
const ackSeq = this.clampAckSeq('group.ack_events', 'event_seq', ns, ackContig);
|
|
1030
1034
|
client._transport.call('group.ack_events', {
|
|
1031
1035
|
group_id: groupId,
|
|
@@ -1042,6 +1046,53 @@ export class MessageDeliveryEngine {
|
|
|
1042
1046
|
});
|
|
1043
1047
|
}
|
|
1044
1048
|
}
|
|
1049
|
+
fireGroupEventAck(groupId, eventSeq, reason) {
|
|
1050
|
+
const client = this.runtime.client;
|
|
1051
|
+
const gid = normalizeGroupId(groupId) || String(groupId ?? '').trim();
|
|
1052
|
+
if (!gid)
|
|
1053
|
+
return;
|
|
1054
|
+
const ns = `group_event:${gid}`;
|
|
1055
|
+
const ackSeq = this.clampAckSeq('group.ack_events', 'event_seq', ns, Number(eventSeq) || 0);
|
|
1056
|
+
if (ackSeq <= 0)
|
|
1057
|
+
return;
|
|
1058
|
+
const params = {
|
|
1059
|
+
group_id: gid,
|
|
1060
|
+
event_seq: ackSeq,
|
|
1061
|
+
device_id: client._deviceId,
|
|
1062
|
+
slot_id: client._slotId,
|
|
1063
|
+
_rpc_background: true,
|
|
1064
|
+
};
|
|
1065
|
+
try {
|
|
1066
|
+
Promise.resolve(client.call('group.ack_events', params)).catch((e) => {
|
|
1067
|
+
client._clientLog.debug(`group event ${reason} ack failed: group=${gid} ${formatDeliveryError(e)}`);
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
catch (e) {
|
|
1071
|
+
client._clientLog.debug(`group event ${reason} ack failed: group=${gid} ${formatDeliveryError(e)}`);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
fireGroupV2Ack(groupId, upToSeq, reason) {
|
|
1075
|
+
const client = this.runtime.client;
|
|
1076
|
+
const gid = normalizeGroupId(groupId) || String(groupId ?? '').trim();
|
|
1077
|
+
if (!gid)
|
|
1078
|
+
return;
|
|
1079
|
+
const ns = `group:${gid}`;
|
|
1080
|
+
const ackSeq = this.clampAckSeq('group.v2.ack', 'up_to_seq', ns, Number(upToSeq) || 0);
|
|
1081
|
+
if (ackSeq <= 0)
|
|
1082
|
+
return;
|
|
1083
|
+
try {
|
|
1084
|
+
Promise.resolve(client.call('group.v2.ack', {
|
|
1085
|
+
group_id: gid,
|
|
1086
|
+
up_to_seq: ackSeq,
|
|
1087
|
+
_rpc_background: true,
|
|
1088
|
+
})).catch((e) => {
|
|
1089
|
+
client._clientLog.debug(`group.v2 ${reason} ack failed: group=${gid} ${formatDeliveryError(e)}`);
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
catch (e) {
|
|
1093
|
+
client._clientLog.debug(`group.v2 ${reason} ack failed: group=${gid} ${formatDeliveryError(e)}`);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1045
1096
|
isSelfJoinGroupChanged(data) {
|
|
1046
1097
|
const action = String(data.action ?? '').trim();
|
|
1047
1098
|
if (!['member_added', 'joined', 'join_approved', 'invite_code_used'].includes(action))
|
|
@@ -1083,7 +1134,7 @@ export class MessageDeliveryEngine {
|
|
|
1083
1134
|
const newContig = client._seqTracker.getContiguousSeq(ns);
|
|
1084
1135
|
const needPull = pushSeq > newContig && !published;
|
|
1085
1136
|
if (newContig !== contigBefore) {
|
|
1086
|
-
|
|
1137
|
+
this.persistSeq(ns);
|
|
1087
1138
|
}
|
|
1088
1139
|
if (newContig > 0 && newContig !== contigBefore) {
|
|
1089
1140
|
const ackSeq = this.clampAckSeq('message.v2.ack', 'up_to_seq', ns, newContig);
|
|
@@ -1155,7 +1206,7 @@ export class MessageDeliveryEngine {
|
|
|
1155
1206
|
this.runtime.delivery.setOnlineUnreadHintDrainActive(true);
|
|
1156
1207
|
try {
|
|
1157
1208
|
while (client._onlineUnreadHintQueue.size > 0) {
|
|
1158
|
-
if (client.state !==
|
|
1209
|
+
if (client.state !== ConnectionState.READY)
|
|
1159
1210
|
return;
|
|
1160
1211
|
if (client._sessionOptions?.background_sync === false)
|
|
1161
1212
|
return;
|
|
@@ -1208,8 +1259,9 @@ export class MessageDeliveryEngine {
|
|
|
1208
1259
|
client._seqTracker.updateMaxSeen(ns, seq);
|
|
1209
1260
|
const contigBefore = client._seqTracker.getContiguousSeq(ns);
|
|
1210
1261
|
client._clientLog.debug(`_onRawGroupV2MessageCreated enter: group=${groupId}, seq=${seq}, contiguous=${contigBefore}, max_seen=${client._seqTracker.getMaxSeenSeq(ns)}`);
|
|
1211
|
-
if (contigBefore === seq) {
|
|
1262
|
+
if (contigBefore === seq || (eventKind === 'group.online_unread_hint' && contigBefore > seq)) {
|
|
1212
1263
|
client._clientLog.debug(`_onRawGroupV2MessageCreated duplicate push already covered: group=${groupId} seq=${seq}`);
|
|
1264
|
+
this.fireGroupV2Ack(groupId, seq, 'covered push');
|
|
1213
1265
|
return;
|
|
1214
1266
|
}
|
|
1215
1267
|
const afterSeq = client._repairPushContiguousBound(ns, seq, false, '_raw.group.v2.message_created');
|
|
@@ -1327,23 +1379,132 @@ export class MessageDeliveryEngine {
|
|
|
1327
1379
|
}
|
|
1328
1380
|
saveSeqTrackerState() {
|
|
1329
1381
|
const client = this.runtime.client;
|
|
1330
|
-
|
|
1382
|
+
const context = this.currentSeqTrackerContext();
|
|
1383
|
+
if (!context) {
|
|
1384
|
+
this.flushSeqTrackerPending();
|
|
1331
1385
|
return;
|
|
1386
|
+
}
|
|
1332
1387
|
const state = client._seqTracker.exportState();
|
|
1333
|
-
|
|
1388
|
+
const pending = this.seqTrackerPending();
|
|
1389
|
+
if (pending.size > 0 && client._seqTrackerPendingPersistContext === context) {
|
|
1390
|
+
const liveNamespaces = new Set(Object.keys(state));
|
|
1391
|
+
for (const ns of [...pending.keys()]) {
|
|
1392
|
+
if (!liveNamespaces.has(ns))
|
|
1393
|
+
pending.delete(ns);
|
|
1394
|
+
}
|
|
1395
|
+
if (pending.size === 0)
|
|
1396
|
+
client._seqTrackerPendingPersistContext = null;
|
|
1397
|
+
}
|
|
1398
|
+
if (Object.keys(state).length > 0)
|
|
1399
|
+
this.mergeSeqTrackerPending(context, state);
|
|
1400
|
+
this.flushSeqTrackerPending();
|
|
1401
|
+
}
|
|
1402
|
+
persistSeq(ns, forceSeq) {
|
|
1403
|
+
const client = this.runtime.client;
|
|
1404
|
+
const context = this.currentSeqTrackerContext();
|
|
1405
|
+
if (!context) {
|
|
1406
|
+
this.flushSeqTrackerPending();
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
const seq = forceSeq ?? client._seqTracker.getContiguousSeq(ns);
|
|
1410
|
+
if (!ns || !Number.isFinite(seq) || seq <= 0)
|
|
1411
|
+
return;
|
|
1412
|
+
if (forceSeq !== undefined) {
|
|
1413
|
+
client._seqTracker.forceContiguousSeq(ns, seq);
|
|
1414
|
+
}
|
|
1415
|
+
this.mergeSeqTrackerPending(context, { [ns]: seq });
|
|
1416
|
+
this.scheduleSeqTrackerFlush();
|
|
1417
|
+
}
|
|
1418
|
+
flushSeqTrackerPending() {
|
|
1419
|
+
const client = this.runtime.client;
|
|
1420
|
+
this.cancelSeqTrackerFlushTimer();
|
|
1421
|
+
const context = client._seqTrackerPendingPersistContext;
|
|
1422
|
+
const pending = this.seqTrackerPending();
|
|
1423
|
+
if (!context || pending.size === 0) {
|
|
1424
|
+
client._seqTrackerPendingPersistContext = null;
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
const [aid, deviceId, slotId] = JSON.parse(context);
|
|
1428
|
+
const state = Object.fromEntries(pending.entries());
|
|
1429
|
+
pending.clear();
|
|
1430
|
+
client._seqTrackerPendingPersistContext = null;
|
|
1431
|
+
this.writeSeqTrackerState(aid, deviceId, slotId, state);
|
|
1432
|
+
}
|
|
1433
|
+
dropSeqTrackerPending(ns) {
|
|
1434
|
+
const client = this.runtime.client;
|
|
1435
|
+
const pending = this.seqTrackerPending();
|
|
1436
|
+
pending.delete(ns);
|
|
1437
|
+
if (pending.size === 0) {
|
|
1438
|
+
client._seqTrackerPendingPersistContext = null;
|
|
1439
|
+
this.cancelSeqTrackerFlushTimer();
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
currentSeqTrackerContext() {
|
|
1443
|
+
const client = this.runtime.client;
|
|
1444
|
+
if (!client._aid)
|
|
1445
|
+
return null;
|
|
1446
|
+
return JSON.stringify([client._aid, client._deviceId, client._slotId]);
|
|
1447
|
+
}
|
|
1448
|
+
seqTrackerPending() {
|
|
1449
|
+
const client = this.runtime.client;
|
|
1450
|
+
if (!(client._seqTrackerPendingPersist instanceof Map)) {
|
|
1451
|
+
client._seqTrackerPendingPersist = new Map();
|
|
1452
|
+
}
|
|
1453
|
+
return client._seqTrackerPendingPersist;
|
|
1454
|
+
}
|
|
1455
|
+
mergeSeqTrackerPending(context, state) {
|
|
1456
|
+
const client = this.runtime.client;
|
|
1457
|
+
const pending = this.seqTrackerPending();
|
|
1458
|
+
const pendingContext = client._seqTrackerPendingPersistContext;
|
|
1459
|
+
if (pendingContext && pendingContext !== context && pending.size > 0) {
|
|
1460
|
+
this.flushSeqTrackerPending();
|
|
1461
|
+
}
|
|
1462
|
+
client._seqTrackerPendingPersistContext = context;
|
|
1463
|
+
for (const [ns, seq] of Object.entries(state)) {
|
|
1464
|
+
const seqNum = Number(seq);
|
|
1465
|
+
if (ns && Number.isFinite(seqNum) && seqNum > 0) {
|
|
1466
|
+
pending.set(ns, seqNum);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
scheduleSeqTrackerFlush() {
|
|
1471
|
+
const client = this.runtime.client;
|
|
1472
|
+
const pending = this.seqTrackerPending();
|
|
1473
|
+
if (pending.size === 0)
|
|
1474
|
+
return;
|
|
1475
|
+
if (client._seqTrackerFlushTimer)
|
|
1476
|
+
return;
|
|
1477
|
+
client._seqTrackerFlushTimer = setTimeout(() => {
|
|
1478
|
+
client._seqTrackerFlushTimer = null;
|
|
1479
|
+
this.flushSeqTrackerPending();
|
|
1480
|
+
}, SEQ_TRACKER_PERSIST_FLUSH_DELAY_MS);
|
|
1481
|
+
}
|
|
1482
|
+
cancelSeqTrackerFlushTimer() {
|
|
1483
|
+
const client = this.runtime.client;
|
|
1484
|
+
if (client._seqTrackerFlushTimer) {
|
|
1485
|
+
clearTimeout(client._seqTrackerFlushTimer);
|
|
1486
|
+
client._seqTrackerFlushTimer = null;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
writeSeqTrackerState(aid, deviceId, slotId, state) {
|
|
1490
|
+
const client = this.runtime.client;
|
|
1491
|
+
if (!aid || Object.keys(state).length === 0)
|
|
1334
1492
|
return;
|
|
1335
1493
|
try {
|
|
1336
1494
|
const saveFn = client._tokenStore.saveSeq;
|
|
1337
1495
|
if (typeof saveFn === 'function') {
|
|
1338
1496
|
for (const [ns, seq] of Object.entries(state)) {
|
|
1339
|
-
saveFn.call(client._tokenStore,
|
|
1497
|
+
saveFn.call(client._tokenStore, aid, deviceId, slotId, ns, seq);
|
|
1340
1498
|
}
|
|
1341
1499
|
return;
|
|
1342
1500
|
}
|
|
1343
1501
|
const updater = client._tokenStore.updateInstanceState;
|
|
1344
1502
|
if (typeof updater === 'function') {
|
|
1345
|
-
updater.call(client._tokenStore,
|
|
1346
|
-
metadata.seq_tracker_state
|
|
1503
|
+
updater.call(client._tokenStore, aid, deviceId, slotId, (metadata) => {
|
|
1504
|
+
const existing = isJsonObject(metadata.seq_tracker_state)
|
|
1505
|
+
? { ...metadata.seq_tracker_state }
|
|
1506
|
+
: {};
|
|
1507
|
+
metadata.seq_tracker_state = { ...existing, ...state };
|
|
1347
1508
|
return metadata;
|
|
1348
1509
|
});
|
|
1349
1510
|
}
|
|
@@ -1353,9 +1514,9 @@ export class MessageDeliveryEngine {
|
|
|
1353
1514
|
client._clientLog.warn(`save SeqTracker state failed: ${error}`);
|
|
1354
1515
|
client._dispatcher.publish('seq_tracker.persist_error', {
|
|
1355
1516
|
phase: 'save',
|
|
1356
|
-
aid
|
|
1357
|
-
device_id:
|
|
1358
|
-
slot_id:
|
|
1517
|
+
aid,
|
|
1518
|
+
device_id: deviceId,
|
|
1519
|
+
slot_id: slotId,
|
|
1359
1520
|
error: String(error),
|
|
1360
1521
|
}).catch(() => { });
|
|
1361
1522
|
}
|
|
@@ -1365,6 +1526,7 @@ export class MessageDeliveryEngine {
|
|
|
1365
1526
|
if (!client._aid || !ns)
|
|
1366
1527
|
return;
|
|
1367
1528
|
const seq = client._seqTracker.getContiguousSeq(ns);
|
|
1529
|
+
this.dropSeqTrackerPending(ns);
|
|
1368
1530
|
try {
|
|
1369
1531
|
if (seq > 0 && typeof client._tokenStore.saveSeq === 'function') {
|
|
1370
1532
|
client._tokenStore.saveSeq(client._aid, client._deviceId, client._slotId, ns, seq);
|
|
@@ -1375,6 +1537,18 @@ export class MessageDeliveryEngine {
|
|
|
1375
1537
|
deleteSeq.call(client._tokenStore, client._aid, client._deviceId, client._slotId, ns);
|
|
1376
1538
|
return;
|
|
1377
1539
|
}
|
|
1540
|
+
const updater = client._tokenStore.updateInstanceState;
|
|
1541
|
+
if (seq <= 0 && typeof updater === 'function') {
|
|
1542
|
+
updater.call(client._tokenStore, client._aid, client._deviceId, client._slotId, (metadata) => {
|
|
1543
|
+
if (isJsonObject(metadata.seq_tracker_state)) {
|
|
1544
|
+
const next = { ...metadata.seq_tracker_state };
|
|
1545
|
+
delete next[ns];
|
|
1546
|
+
metadata.seq_tracker_state = next;
|
|
1547
|
+
}
|
|
1548
|
+
return metadata;
|
|
1549
|
+
});
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1378
1552
|
if (seq > 0) {
|
|
1379
1553
|
this.saveSeqTrackerState();
|
|
1380
1554
|
}
|
|
@@ -1434,6 +1608,7 @@ export class MessageDeliveryEngine {
|
|
|
1434
1608
|
const queue = client._pendingOrderedMsgs.get(ns);
|
|
1435
1609
|
if (!queue || queue.size === 0)
|
|
1436
1610
|
return;
|
|
1611
|
+
let delivered = false;
|
|
1437
1612
|
while (true) {
|
|
1438
1613
|
const contig = client._seqTracker.getContiguousSeq(ns);
|
|
1439
1614
|
const ready = [...queue.keys()]
|
|
@@ -1462,10 +1637,14 @@ export class MessageDeliveryEngine {
|
|
|
1462
1637
|
await this.publishOrderedQueueItem(ns, item.event, seq, item.payload, 'ordered-drain', pullResponse);
|
|
1463
1638
|
this.markPublishedSeq(ns, seq);
|
|
1464
1639
|
client._markOrderedSeqDelivered(ns, seq);
|
|
1640
|
+
delivered = true;
|
|
1465
1641
|
client._clientLog.debug(`publish ordered drain delivered: ns=${ns}, seq=${seq}, event=${item.event}`);
|
|
1466
1642
|
}
|
|
1467
|
-
if (queue.size === 0)
|
|
1643
|
+
if (queue.size === 0) {
|
|
1468
1644
|
client._pendingOrderedMsgs.delete(ns);
|
|
1645
|
+
if (delivered)
|
|
1646
|
+
this.saveSeqTrackerState();
|
|
1647
|
+
}
|
|
1469
1648
|
}
|
|
1470
1649
|
async publishOrderedMessage(event, ns, seq, payload) {
|
|
1471
1650
|
const client = this.runtime.client;
|
|
@@ -1511,6 +1690,8 @@ export class MessageDeliveryEngine {
|
|
|
1511
1690
|
client._markOrderedSeqDelivered(ns, seqNum);
|
|
1512
1691
|
client._clientLog.debug(`publish ordered delivered: event=${event}, ns=${ns}, seq=${seqNum}`);
|
|
1513
1692
|
await this.drainOrderedMessages(ns);
|
|
1693
|
+
if (!client._pendingOrderedMsgs.get(ns))
|
|
1694
|
+
this.saveSeqTrackerState();
|
|
1514
1695
|
return true;
|
|
1515
1696
|
}
|
|
1516
1697
|
async publishOrderedGroupRecall(ns, seq, message) {
|
|
@@ -1530,6 +1711,8 @@ export class MessageDeliveryEngine {
|
|
|
1530
1711
|
this.markPublishedSeq(ns, seqNum);
|
|
1531
1712
|
client._markOrderedSeqDelivered?.(ns, seqNum);
|
|
1532
1713
|
await this.drainOrderedMessages(ns);
|
|
1714
|
+
if (!client._pendingOrderedMsgs.get(ns))
|
|
1715
|
+
this.saveSeqTrackerState();
|
|
1533
1716
|
return true;
|
|
1534
1717
|
}
|
|
1535
1718
|
async publishPulledMessage(event, ns, seq, payload) {
|