@agentunion/fastaun 0.5.8 → 0.5.10
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 +64 -0
- package/_packed_docs/CHANGELOG.md +64 -0
- package/_packed_docs/agent.md/examples//347/276/244/347/273/204-/345/274/200/345/217/221/345/233/242/351/230/237.md +21 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +6 -5
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +43 -8
- package/_packed_docs/sdk/09-group-rpc-manual.md +18 -3
- package/_packed_docs/sdk/09-message-rpc-manual.md +34 -10
- package/dist/agent-md-schema.js +3 -0
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.js +5 -1
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.js +1 -3
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.d.ts +5 -2
- package/dist/auth.js +64 -27
- package/dist/auth.js.map +1 -1
- package/dist/client/delivery.d.ts +25 -5
- package/dist/client/delivery.js +355 -70
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +8 -8
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +25 -22
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +12 -0
- package/dist/client/rpc-pipeline.js +182 -32
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +1 -0
- package/dist/client/v2-e2ee.js +55 -21
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.js +108 -38
- package/dist/client.js.map +1 -1
- package/dist/discovery.d.ts +1 -0
- package/dist/discovery.js +3 -0
- package/dist/discovery.js.map +1 -1
- package/dist/events.d.ts +23 -8
- package/dist/events.js +120 -26
- package/dist/events.js.map +1 -1
- package/dist/facades.js +7 -3
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/net.d.ts +3 -0
- package/dist/net.js +13 -0
- package/dist/net.js.map +1 -1
- package/dist/register-flow.js +15 -111
- package/dist/register-flow.js.map +1 -1
- package/dist/transport.d.ts +32 -3
- package/dist/transport.js +758 -33
- package/dist/transport.js.map +1 -1
- 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/_packed_docs//345/217/221/345/270/203/346/212/245/345/221/212-0.5.6.md +0 -260
package/dist/client/v2-e2ee.js
CHANGED
|
@@ -298,6 +298,10 @@ export class V2E2EECoordinator {
|
|
|
298
298
|
this.pendingForwardCursors.clear();
|
|
299
299
|
this.pendingForwardAcks.clear();
|
|
300
300
|
}
|
|
301
|
+
hasPendingSenderIKWork() {
|
|
302
|
+
return this.senderIKSyncFetches.size > 0
|
|
303
|
+
|| Boolean(this.client._v2SenderIKFetching?.size);
|
|
304
|
+
}
|
|
301
305
|
pendingForwardCursor(ns, localAck) {
|
|
302
306
|
if (!ns)
|
|
303
307
|
return 0;
|
|
@@ -648,6 +652,7 @@ export class V2E2EECoordinator {
|
|
|
648
652
|
finally {
|
|
649
653
|
if (this.senderIKSyncFetches.get(fetchKey) === task)
|
|
650
654
|
this.senderIKSyncFetches.delete(fetchKey);
|
|
655
|
+
client._rpcPipeline?.requestPullDrainedCheck?.();
|
|
651
656
|
}
|
|
652
657
|
}
|
|
653
658
|
scheduleSenderIKPending(args) {
|
|
@@ -679,6 +684,10 @@ export class V2E2EECoordinator {
|
|
|
679
684
|
}
|
|
680
685
|
async resolveSenderIKPending(fromAid, senderDeviceId, groupId, fetchKey) {
|
|
681
686
|
const client = this.client;
|
|
687
|
+
const generation = Number(client._v2RuntimeGeneration ?? 0);
|
|
688
|
+
const pending = client._v2SenderIKPending;
|
|
689
|
+
const fetching = client._v2SenderIKFetching;
|
|
690
|
+
const generationIsCurrent = () => Number(client._v2RuntimeGeneration ?? 0) === generation;
|
|
682
691
|
try {
|
|
683
692
|
const session = client._v2Session;
|
|
684
693
|
if (session && fromAid) {
|
|
@@ -718,7 +727,9 @@ export class V2E2EECoordinator {
|
|
|
718
727
|
await this.getV2SenderPubDer(fromAid, senderDeviceId);
|
|
719
728
|
}
|
|
720
729
|
}
|
|
721
|
-
|
|
730
|
+
if (!generationIsCurrent())
|
|
731
|
+
return;
|
|
732
|
+
const pendingItems = [...pending.entries()].filter(([, entry]) => entry.fromAid === fromAid && entry.senderDeviceId === senderDeviceId && entry.groupId === groupId);
|
|
722
733
|
for (const [key, entry] of pendingItems) {
|
|
723
734
|
let plaintext = null;
|
|
724
735
|
const retryStatus = {};
|
|
@@ -727,9 +738,12 @@ export class V2E2EECoordinator {
|
|
|
727
738
|
}
|
|
728
739
|
catch (exc) {
|
|
729
740
|
client._clientLog.warn(`V2 sender IK pending retry raised: key=${key} err=${formatE2EEError(exc)}`);
|
|
730
|
-
|
|
741
|
+
if (generationIsCurrent())
|
|
742
|
+
pending.delete(key);
|
|
731
743
|
continue;
|
|
732
744
|
}
|
|
745
|
+
if (!generationIsCurrent())
|
|
746
|
+
return;
|
|
733
747
|
if (plaintext === null) {
|
|
734
748
|
if (retryStatus.deferred) {
|
|
735
749
|
client._clientLog.warn(`V2 pending retry still missing key material: key=${key}`);
|
|
@@ -741,10 +755,16 @@ export class V2E2EECoordinator {
|
|
|
741
755
|
const safeEvent = this.safeUndecryptablePushEvent(entry.msg, isGroup);
|
|
742
756
|
safeEvent._decrypt_error = 'sender IK pending retry failed';
|
|
743
757
|
safeEvent._decrypt_stage = 'sender_ik_pending_retry';
|
|
744
|
-
|
|
758
|
+
try {
|
|
759
|
+
await client._publishAppEvent(eventName, safeEvent, 'pending_retry');
|
|
760
|
+
}
|
|
761
|
+
finally {
|
|
762
|
+
if (generationIsCurrent())
|
|
763
|
+
pending.delete(key);
|
|
764
|
+
}
|
|
745
765
|
continue;
|
|
746
766
|
}
|
|
747
|
-
|
|
767
|
+
pending.delete(key);
|
|
748
768
|
const seq = Number(entry.msg.seq ?? 0);
|
|
749
769
|
if (entry.groupId) {
|
|
750
770
|
plaintext = normalizeGroupMentionMode(plaintext, entry.msg, entry.msg.envelope_json);
|
|
@@ -758,7 +778,10 @@ export class V2E2EECoordinator {
|
|
|
758
778
|
}
|
|
759
779
|
}
|
|
760
780
|
finally {
|
|
761
|
-
client._v2SenderIKFetching
|
|
781
|
+
if (generationIsCurrent() && client._v2SenderIKFetching === fetching) {
|
|
782
|
+
fetching.delete(fetchKey);
|
|
783
|
+
client._rpcPipeline?.requestPullDrainedCheck?.();
|
|
784
|
+
}
|
|
762
785
|
}
|
|
763
786
|
}
|
|
764
787
|
async buildV2P2PEnvelope(opts) {
|
|
@@ -924,9 +947,10 @@ export class V2E2EECoordinator {
|
|
|
924
947
|
throw new ValidationError("message.send requires 'to'");
|
|
925
948
|
if (!isJsonObject(payload))
|
|
926
949
|
throw new ValidationError('message.send payload must be a dict for V2 encryption');
|
|
950
|
+
const messageId = String(opts?.messageId ?? '').trim() || `m-${crypto.randomUUID().replace(/-/g, '')}`;
|
|
927
951
|
client._logMessageDebug('send-plaintext', 'message.send.v2', 'message.send', {
|
|
928
952
|
to: toAid,
|
|
929
|
-
message_id:
|
|
953
|
+
message_id: messageId,
|
|
930
954
|
payload,
|
|
931
955
|
}, { payloadOverride: payload });
|
|
932
956
|
const attempt = async (useCache) => {
|
|
@@ -934,7 +958,7 @@ export class V2E2EECoordinator {
|
|
|
934
958
|
const envelope = await client._buildV2P2PEnvelope({
|
|
935
959
|
to: toAid,
|
|
936
960
|
payload,
|
|
937
|
-
messageId
|
|
961
|
+
messageId,
|
|
938
962
|
timestamp: opts?.timestamp,
|
|
939
963
|
protectedHeaders: opts?.protectedHeaders,
|
|
940
964
|
context: opts?.context,
|
|
@@ -943,6 +967,7 @@ export class V2E2EECoordinator {
|
|
|
943
967
|
const result = await client.call('message.send', {
|
|
944
968
|
to: toAid,
|
|
945
969
|
payload: envelope,
|
|
970
|
+
message_id: messageId,
|
|
946
971
|
encrypt: false,
|
|
947
972
|
_skip_send_result_envelope: true,
|
|
948
973
|
});
|
|
@@ -954,7 +979,7 @@ export class V2E2EECoordinator {
|
|
|
954
979
|
return client._delivery.attachSendResultEnvelope('message.send', {
|
|
955
980
|
to: toAid,
|
|
956
981
|
payload,
|
|
957
|
-
message_id:
|
|
982
|
+
message_id: messageId,
|
|
958
983
|
timestamp: opts?.timestamp,
|
|
959
984
|
protected_headers: opts?.protectedHeaders,
|
|
960
985
|
context: opts?.context,
|
|
@@ -969,7 +994,7 @@ export class V2E2EECoordinator {
|
|
|
969
994
|
return client._delivery.attachSendResultEnvelope('message.send', {
|
|
970
995
|
to: toAid,
|
|
971
996
|
payload,
|
|
972
|
-
message_id:
|
|
997
|
+
message_id: messageId,
|
|
973
998
|
timestamp: opts?.timestamp,
|
|
974
999
|
protected_headers: opts?.protectedHeaders,
|
|
975
1000
|
context: opts?.context,
|
|
@@ -1022,7 +1047,7 @@ export class V2E2EECoordinator {
|
|
|
1022
1047
|
if (publish) {
|
|
1023
1048
|
const event = client._delivery.p2pAppEventForMessage(plaintext);
|
|
1024
1049
|
if (orderedPublish) {
|
|
1025
|
-
await client._delivery.publishOrderedMessage(event.event, client._aid ? `p2p:${client._aid}` : '', seq, event.payload);
|
|
1050
|
+
await client._delivery.publishOrderedMessage(event.event, client._aid ? `p2p:${client._aid}` : '', seq, event.payload, source);
|
|
1026
1051
|
}
|
|
1027
1052
|
else {
|
|
1028
1053
|
await client._publishAppEvent(event.event, event.payload, source);
|
|
@@ -1079,7 +1104,7 @@ export class V2E2EECoordinator {
|
|
|
1079
1104
|
}
|
|
1080
1105
|
if (publish) {
|
|
1081
1106
|
if (orderedPublish) {
|
|
1082
|
-
await client._delivery.publishOrderedMessage('group.message_created', `group:${groupId}`, seq, plaintext);
|
|
1107
|
+
await client._delivery.publishOrderedMessage('group.message_created', `group:${groupId}`, seq, plaintext, source);
|
|
1083
1108
|
}
|
|
1084
1109
|
else {
|
|
1085
1110
|
await client._publishAppEvent('group.message_created', plaintext, source);
|
|
@@ -1227,6 +1252,7 @@ export class V2E2EECoordinator {
|
|
|
1227
1252
|
pageMaxSeq = Math.max(...seqs);
|
|
1228
1253
|
}
|
|
1229
1254
|
const deferredKeyFetches = new Map();
|
|
1255
|
+
let blockedSeq = 0;
|
|
1230
1256
|
for (const msg of messages) {
|
|
1231
1257
|
const seq = Number(msg.seq ?? 0);
|
|
1232
1258
|
if (!Number.isFinite(seq) || seq <= 0)
|
|
@@ -1275,6 +1301,9 @@ export class V2E2EECoordinator {
|
|
|
1275
1301
|
}
|
|
1276
1302
|
const deferStatus = {};
|
|
1277
1303
|
const plaintext = await client._decryptV2Message(msg, true, true, true, true, deferStatus, true);
|
|
1304
|
+
if (deferStatus.deferred) {
|
|
1305
|
+
blockedSeq = blockedSeq > 0 ? Math.min(blockedSeq, seq) : seq;
|
|
1306
|
+
}
|
|
1278
1307
|
if (deferStatus.deferred && deferStatus.fromAid) {
|
|
1279
1308
|
const key = `${deferStatus.fromAid}\u0000${deferStatus.senderDeviceId ?? ''}\u0000${deferStatus.groupId ?? ''}`;
|
|
1280
1309
|
deferredKeyFetches.set(key, {
|
|
@@ -1301,7 +1330,7 @@ export class V2E2EECoordinator {
|
|
|
1301
1330
|
const serverAckSeq = parsedServerAckSeq ?? 0;
|
|
1302
1331
|
const retentionFloor = Math.max(0, Number(result.retention_floor_seq ?? 0));
|
|
1303
1332
|
if (ns) {
|
|
1304
|
-
const commitTarget = Math.max(pageContigBefore, Number.isFinite(retentionFloor) ? retentionFloor : 0, pageCount === 1 ? deferredServerCursor : 0, seqs.length > 0 ? pageMaxSeq : pageContigBefore);
|
|
1333
|
+
const commitTarget = Math.max(pageContigBefore, Number.isFinite(retentionFloor) ? retentionFloor : 0, pageCount === 1 ? deferredServerCursor : 0, blockedSeq > 0 ? blockedSeq - 1 : (seqs.length > 0 ? pageMaxSeq : pageContigBefore));
|
|
1305
1334
|
let ackSeq = pageContigBefore;
|
|
1306
1335
|
let contigAdvanced = false;
|
|
1307
1336
|
try {
|
|
@@ -1333,7 +1362,7 @@ export class V2E2EECoordinator {
|
|
|
1333
1362
|
throw exc;
|
|
1334
1363
|
}
|
|
1335
1364
|
if (contigAdvanced)
|
|
1336
|
-
await client._drainOrderedMessages(ns, undefined, false, false);
|
|
1365
|
+
await client._drainOrderedMessages(ns, undefined, false, false, 'pull');
|
|
1337
1366
|
for (const fetch of deferredKeyFetches.values()) {
|
|
1338
1367
|
this.scheduleSenderIKFetch(fetch.fromAid, fetch.senderDeviceId, fetch.groupId);
|
|
1339
1368
|
}
|
|
@@ -1352,7 +1381,7 @@ export class V2E2EECoordinator {
|
|
|
1352
1381
|
if (ackNeeded) {
|
|
1353
1382
|
this.recordForwardAck(ns, ackSeq);
|
|
1354
1383
|
const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
|
|
1355
|
-
const canContinuePage = messages.length > 0 && nextAfter > nextAfterSeq;
|
|
1384
|
+
const canContinuePage = blockedSeq <= 0 && messages.length > 0 && nextAfter > nextAfterSeq;
|
|
1356
1385
|
if (canContinuePage) {
|
|
1357
1386
|
pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
|
|
1358
1387
|
lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
|
|
@@ -1483,9 +1512,10 @@ export class V2E2EECoordinator {
|
|
|
1483
1512
|
const groupAid = String(opts?.groupAid ?? '').trim();
|
|
1484
1513
|
if (!isJsonObject(payload))
|
|
1485
1514
|
throw new ValidationError('group.send payload must be a dict for V2 encryption');
|
|
1515
|
+
const messageId = String(opts?.messageId ?? '').trim() || `m-${crypto.randomUUID().replace(/-/g, '')}`;
|
|
1486
1516
|
client._logMessageDebug('send-plaintext', 'group.send.v2', 'group.send', withExplicitGroupAid({
|
|
1487
1517
|
group_id: gid,
|
|
1488
|
-
message_id:
|
|
1518
|
+
message_id: messageId,
|
|
1489
1519
|
payload,
|
|
1490
1520
|
}, groupAid), { payloadOverride: payload });
|
|
1491
1521
|
const attempt = async (useCache) => {
|
|
@@ -1493,7 +1523,7 @@ export class V2E2EECoordinator {
|
|
|
1493
1523
|
const envelope = await client._buildV2GroupEnvelope({
|
|
1494
1524
|
groupId: gid,
|
|
1495
1525
|
payload,
|
|
1496
|
-
messageId
|
|
1526
|
+
messageId,
|
|
1497
1527
|
timestamp: opts?.timestamp,
|
|
1498
1528
|
protectedHeaders: opts?.protectedHeaders,
|
|
1499
1529
|
context: opts?.context,
|
|
@@ -1525,7 +1555,7 @@ export class V2E2EECoordinator {
|
|
|
1525
1555
|
return client._delivery.attachSendResultEnvelope('group.send', withExplicitGroupAid({
|
|
1526
1556
|
group_id: gid,
|
|
1527
1557
|
payload,
|
|
1528
|
-
message_id:
|
|
1558
|
+
message_id: messageId,
|
|
1529
1559
|
timestamp: opts?.timestamp,
|
|
1530
1560
|
protected_headers: opts?.protectedHeaders,
|
|
1531
1561
|
context: opts?.context,
|
|
@@ -1541,7 +1571,7 @@ export class V2E2EECoordinator {
|
|
|
1541
1571
|
return client._delivery.attachSendResultEnvelope('group.send', withExplicitGroupAid({
|
|
1542
1572
|
group_id: gid,
|
|
1543
1573
|
payload,
|
|
1544
|
-
message_id:
|
|
1574
|
+
message_id: messageId,
|
|
1545
1575
|
timestamp: opts?.timestamp,
|
|
1546
1576
|
protected_headers: opts?.protectedHeaders,
|
|
1547
1577
|
context: opts?.context,
|
|
@@ -1885,6 +1915,7 @@ export class V2E2EECoordinator {
|
|
|
1885
1915
|
pageMaxSeq = Math.max(...seqs);
|
|
1886
1916
|
}
|
|
1887
1917
|
const deferredKeyFetches = new Map();
|
|
1918
|
+
let blockedSeq = 0;
|
|
1888
1919
|
for (const msg of messages) {
|
|
1889
1920
|
const seq = Number(msg.seq ?? 0);
|
|
1890
1921
|
if (!Number.isFinite(seq) || seq <= 0)
|
|
@@ -1954,6 +1985,9 @@ export class V2E2EECoordinator {
|
|
|
1954
1985
|
}
|
|
1955
1986
|
const deferStatus = {};
|
|
1956
1987
|
let plaintext = await client._decryptV2Message(msg, true, true, true, true, deferStatus, true);
|
|
1988
|
+
if (deferStatus.deferred) {
|
|
1989
|
+
blockedSeq = blockedSeq > 0 ? Math.min(blockedSeq, seq) : seq;
|
|
1990
|
+
}
|
|
1957
1991
|
if (deferStatus.deferred && deferStatus.fromAid) {
|
|
1958
1992
|
const key = `${deferStatus.fromAid}\u0000${deferStatus.senderDeviceId ?? ''}\u0000${deferStatus.groupId ?? ''}`;
|
|
1959
1993
|
deferredKeyFetches.set(key, {
|
|
@@ -1979,7 +2013,7 @@ export class V2E2EECoordinator {
|
|
|
1979
2013
|
const retentionFloor = Math.max(client._pullRetentionFloor(result, 'retention_floor_message_seq', 'retention_floor_message_seq'));
|
|
1980
2014
|
const visibilityFloor = Math.max(0, Math.max(0, Number(result.earliest_available_message_seq ?? 1) - 1), Number(cursor?.join_seq ?? 0));
|
|
1981
2015
|
const effectiveFloor = Math.max(retentionFloor, visibilityFloor);
|
|
1982
|
-
const commitTarget = Math.max(pageContigBefore, effectiveFloor, ownsCursor && pageCount === 1 ? deferredServerCursor : 0, seqs.length > 0 ? pageMaxSeq : pageContigBefore);
|
|
2016
|
+
const commitTarget = Math.max(pageContigBefore, effectiveFloor, ownsCursor && pageCount === 1 ? deferredServerCursor : 0, blockedSeq > 0 ? blockedSeq - 1 : (seqs.length > 0 ? pageMaxSeq : pageContigBefore));
|
|
1983
2017
|
let ackSeq = pageContigBefore;
|
|
1984
2018
|
let contigAdvanced = false;
|
|
1985
2019
|
if (ownsCursor) {
|
|
@@ -2012,7 +2046,7 @@ export class V2E2EECoordinator {
|
|
|
2012
2046
|
throw exc;
|
|
2013
2047
|
}
|
|
2014
2048
|
if (contigAdvanced)
|
|
2015
|
-
await client._drainOrderedMessages(ns, undefined, false, false);
|
|
2049
|
+
await client._drainOrderedMessages(ns, undefined, false, false, 'pull');
|
|
2016
2050
|
}
|
|
2017
2051
|
for (const fetch of deferredKeyFetches.values()) {
|
|
2018
2052
|
this.scheduleSenderIKFetch(fetch.fromAid, fetch.senderDeviceId, fetch.groupId);
|
|
@@ -2033,7 +2067,7 @@ export class V2E2EECoordinator {
|
|
|
2033
2067
|
if (ackNeeded) {
|
|
2034
2068
|
this.recordForwardAck(ns, ackSeq);
|
|
2035
2069
|
const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
|
|
2036
|
-
const canContinuePage = messages.length > 0 && nextAfter > nextAfterSeq && ownsCursor;
|
|
2070
|
+
const canContinuePage = blockedSeq <= 0 && messages.length > 0 && nextAfter > nextAfterSeq && ownsCursor;
|
|
2037
2071
|
if (canContinuePage) {
|
|
2038
2072
|
pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
|
|
2039
2073
|
lastAutoAckSeq = Math.max(lastAutoAckSeq, ackSeq);
|