@agentunion/fastaun 0.5.9 → 0.5.11
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/INDEX.md +3 -3
- package/_packed_docs/KITE_DOCS_GUIDE.md +1 -1
- 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 +102 -8
- package/_packed_docs/sdk/09-group-rpc-manual.md +18 -3
- package/_packed_docs/sdk/09-message-rpc-manual.md +34 -10
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +3 -2
- package/_packed_docs/sdk/INDEX.md +2 -1
- package/dist/agent-md.js +5 -1
- package/dist/agent-md.js.map +1 -1
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +30 -44
- package/dist/auth.js.map +1 -1
- package/dist/client/delivery.d.ts +39 -9
- package/dist/client/delivery.js +407 -73
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +6 -6
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +5 -14
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -0
- package/dist/client/rpc-pipeline.js +51 -5
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +3 -0
- package/dist/client/v2-e2ee.js +236 -59
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +84 -30
- package/dist/client.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/register-flow.js +15 -111
- package/dist/register-flow.js.map +1 -1
- package/dist/transport.d.ts +36 -3
- package/dist/transport.js +855 -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/dist/client.js
CHANGED
|
@@ -688,7 +688,7 @@ export class AUNClient {
|
|
|
688
688
|
this._dispatcher.subscribe('_raw.group.state_committed', (data) => this._onGroupStateCommitted(data));
|
|
689
689
|
// 其他事件直接透传
|
|
690
690
|
for (const evt of ['message.ack', 'storage.object_changed', 'stream/created', 'stream/closed']) {
|
|
691
|
-
this._dispatcher.subscribe(`_raw.${evt}`, (data) => this._dispatcher.
|
|
691
|
+
this._dispatcher.subscribe(`_raw.${evt}`, (data) => this._dispatcher.enqueue(evt, data));
|
|
692
692
|
}
|
|
693
693
|
// 服务端主动断开通知:记录日志并标记不重连
|
|
694
694
|
this._dispatcher.subscribe('_raw.gateway.disconnect', (data) => this._onGatewayDisconnect(data));
|
|
@@ -1068,6 +1068,62 @@ export class AUNClient {
|
|
|
1068
1068
|
await this._agentMdManager.upload(agentMd);
|
|
1069
1069
|
return true;
|
|
1070
1070
|
}
|
|
1071
|
+
async _checkIdentityAdmissionAfterConnect() {
|
|
1072
|
+
const aid = String(this._aid ?? this._currentAid?.aid ?? '').trim();
|
|
1073
|
+
if (!aid)
|
|
1074
|
+
return;
|
|
1075
|
+
try {
|
|
1076
|
+
const checked = await this._agentMdManager.check(aid);
|
|
1077
|
+
if (!checked.remote_found) {
|
|
1078
|
+
const content = this._agentMdManager.readContent(aid) || buildDefaultAgentMd(aid);
|
|
1079
|
+
await this._agentMdManager.upload(content);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
catch (exc) {
|
|
1083
|
+
this._clientLog.warn(`post-connect agent.md check failed: ${formatCaughtError(exc)}`);
|
|
1084
|
+
}
|
|
1085
|
+
const store = this._aidStore;
|
|
1086
|
+
if (!store)
|
|
1087
|
+
return;
|
|
1088
|
+
let listed;
|
|
1089
|
+
try {
|
|
1090
|
+
listed = await this.call('group.list_my', {});
|
|
1091
|
+
}
|
|
1092
|
+
catch (exc) {
|
|
1093
|
+
this._clientLog.warn(`post-connect group identity check failed: ${formatCaughtError(exc)}`);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
const result = isJsonObject(listed) ? listed : {};
|
|
1097
|
+
const groups = Array.isArray(result.groups) ? result.groups : (Array.isArray(result.items) ? result.items : []);
|
|
1098
|
+
for (const raw of groups) {
|
|
1099
|
+
if (!isJsonObject(raw))
|
|
1100
|
+
continue;
|
|
1101
|
+
const group = raw;
|
|
1102
|
+
const role = String(group.role ?? group.my_role ?? '').trim().toLowerCase();
|
|
1103
|
+
if (role !== 'owner')
|
|
1104
|
+
continue;
|
|
1105
|
+
const groupId = String(group.group_id ?? group.groupId ?? group.group_aid ?? group.groupAid ?? '').trim();
|
|
1106
|
+
const groupAid = String(group.group_aid ?? group.groupAid ?? groupId).trim();
|
|
1107
|
+
if (!groupId || !groupAid)
|
|
1108
|
+
continue;
|
|
1109
|
+
try {
|
|
1110
|
+
await this._runGroupIdentityOperation(groupId, async () => {
|
|
1111
|
+
const loaded = store.load(groupAid);
|
|
1112
|
+
if (!loaded.ok || !loaded.data?.aid?.isPrivateKeyValid()) {
|
|
1113
|
+
await this.bindGroupAid({ group_id: groupId, group_aid: groupAid }, { aidStore: store });
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
const checked = await this._agentMdManager.check(groupAid);
|
|
1117
|
+
if (!checked.remote_found) {
|
|
1118
|
+
await this._uploadGroupAgentMd(store, groupAid, {}, {});
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
catch (exc) {
|
|
1123
|
+
this._clientLog.warn(`post-connect group identity check failed: group=${groupId} err=${formatCaughtError(exc)}`);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1071
1127
|
async _runGroupIdentityOperation(groupId, operation) {
|
|
1072
1128
|
const aid = String(this._aid ?? '').trim();
|
|
1073
1129
|
const dot = aid.indexOf('.');
|
|
@@ -1943,14 +1999,14 @@ export class AUNClient {
|
|
|
1943
1999
|
}
|
|
1944
2000
|
return true;
|
|
1945
2001
|
}
|
|
1946
|
-
async _drainOrderedMessages(ns, beforeSeq, pullResponse = false, persist = true) {
|
|
1947
|
-
return this._delivery.drainOrderedMessages(ns, beforeSeq, pullResponse, persist);
|
|
2002
|
+
async _drainOrderedMessages(ns, beforeSeq, pullResponse = false, persist = true, source = 'push') {
|
|
2003
|
+
return this._delivery.drainOrderedMessages(ns, beforeSeq, pullResponse, persist, source);
|
|
1948
2004
|
}
|
|
1949
|
-
async _publishOrderedMessage(event, ns, seq, payload) {
|
|
1950
|
-
return this._delivery.publishOrderedMessage(event, ns, seq, payload);
|
|
2005
|
+
async _publishOrderedMessage(event, ns, seq, payload, source = 'push') {
|
|
2006
|
+
return this._delivery.publishOrderedMessage(event, ns, seq, payload, source);
|
|
1951
2007
|
}
|
|
1952
|
-
async _publishPulledMessage(event, ns, seq, payload, persist = true) {
|
|
1953
|
-
return this._delivery.publishPulledMessage(event, ns, seq, payload, persist);
|
|
2008
|
+
async _publishPulledMessage(event, ns, seq, payload, persist = true, source = 'pull') {
|
|
2009
|
+
return this._delivery.publishPulledMessage(event, ns, seq, payload, persist, source);
|
|
1954
2010
|
}
|
|
1955
2011
|
_markOrderedSeqDelivered(ns, seq) {
|
|
1956
2012
|
if (!ns || !Number.isFinite(seq) || !Number.isInteger(seq) || seq <= 0)
|
|
@@ -1992,7 +2048,7 @@ export class AUNClient {
|
|
|
1992
2048
|
}
|
|
1993
2049
|
else {
|
|
1994
2050
|
// data 非对象也透传给用户(兼容旧版)
|
|
1995
|
-
|
|
2051
|
+
this._dispatcher.enqueue('group.changed', data);
|
|
1996
2052
|
}
|
|
1997
2053
|
this._clientLog.debug(`_onRawGroupChanged exit: elapsed=${Date.now() - tStart}ms`);
|
|
1998
2054
|
}
|
|
@@ -2056,7 +2112,7 @@ export class AUNClient {
|
|
|
2056
2112
|
certPem = await this._fetchPeerCert(sigAid, expectedFP || undefined);
|
|
2057
2113
|
}
|
|
2058
2114
|
catch {
|
|
2059
|
-
this._dispatcher.
|
|
2115
|
+
this._dispatcher.enqueue('signature_pending', { aid: sigAid, method });
|
|
2060
2116
|
return false;
|
|
2061
2117
|
}
|
|
2062
2118
|
}
|
|
@@ -2076,19 +2132,19 @@ export class AUNClient {
|
|
|
2076
2132
|
if (!ok) {
|
|
2077
2133
|
this._clientLog.warn(`group event signature verification failed aid=${sigAid} method=${method}`);
|
|
2078
2134
|
// P1-16: 签名失败统一发布事件
|
|
2079
|
-
this._dispatcher.
|
|
2135
|
+
this._dispatcher.enqueue('signature.verification_failed', {
|
|
2080
2136
|
aid: sigAid, method, error: 'ECDSA verification failed',
|
|
2081
|
-
})
|
|
2137
|
+
});
|
|
2082
2138
|
}
|
|
2083
2139
|
return ok;
|
|
2084
2140
|
}
|
|
2085
2141
|
catch (exc) {
|
|
2086
2142
|
this._clientLog.warn(`group event signature verification error: ${formatCaughtError(exc)}`);
|
|
2087
2143
|
// P1-16: 签名失败统一发布事件
|
|
2088
|
-
this._dispatcher.
|
|
2144
|
+
this._dispatcher.enqueue('signature.verification_failed', {
|
|
2089
2145
|
aid: String(cs.aid ?? ''), method: String(cs._method ?? ''),
|
|
2090
2146
|
error: formatCaughtError(exc),
|
|
2091
|
-
})
|
|
2147
|
+
});
|
|
2092
2148
|
return false;
|
|
2093
2149
|
}
|
|
2094
2150
|
}
|
|
@@ -2485,7 +2541,7 @@ export class AUNClient {
|
|
|
2485
2541
|
}
|
|
2486
2542
|
}
|
|
2487
2543
|
else {
|
|
2488
|
-
|
|
2544
|
+
this._dispatcher.enqueue('state_change', statePayload);
|
|
2489
2545
|
}
|
|
2490
2546
|
this._assertReconnectOwner(reconnectOwner);
|
|
2491
2547
|
this._lifecycle.assertConnectionAttemptOwner(connectionOwner);
|
|
@@ -2517,6 +2573,7 @@ export class AUNClient {
|
|
|
2517
2573
|
this._clientLog.warn(`schedule post-connect P2P gap fill failed: ${formatCaughtError(exc)}`);
|
|
2518
2574
|
});
|
|
2519
2575
|
}
|
|
2576
|
+
this._safeAsync(this._checkIdentityAdmissionAfterConnect());
|
|
2520
2577
|
this._clientLog.debug(`_connectOnce exit: elapsed=${Date.now() - tStart}ms gateway=${gatewayUrl}, aid=${this._aid ?? ''}`);
|
|
2521
2578
|
}
|
|
2522
2579
|
catch (err) {
|
|
@@ -2730,7 +2787,7 @@ export class AUNClient {
|
|
|
2730
2787
|
return await this._v2E2EE.ackGroupV2(groupId, upToSeq, groupAid);
|
|
2731
2788
|
}
|
|
2732
2789
|
/** 解密单条 V2 pull 消息。缺 sender IK 时先入 pending,后台补齐后重试。 */
|
|
2733
|
-
async _decryptV2Message(msg, allowPending = true, emitUndecryptable = true, rotateKeys = true, observeAgentMd = true, deferStatus, deferKeyFetch = false) {
|
|
2790
|
+
async _decryptV2Message(msg, allowPending = true, emitUndecryptable = true, rotateKeys = true, observeAgentMd = true, deferStatus, deferKeyFetch = false, source = 'pull') {
|
|
2734
2791
|
const session = this._v2Session;
|
|
2735
2792
|
if (!session)
|
|
2736
2793
|
return null;
|
|
@@ -2823,11 +2880,12 @@ export class AUNClient {
|
|
|
2823
2880
|
_envelope_type: String(envelope.type ?? ''),
|
|
2824
2881
|
_suite: String(envelope.suite ?? ''),
|
|
2825
2882
|
_spk_id: spkId,
|
|
2883
|
+
source,
|
|
2826
2884
|
};
|
|
2827
2885
|
this._attachV2EnvelopeMetadata(event, e2eeMeta);
|
|
2828
2886
|
this._logMessageDebug('decrypt-fail', 'v2.decrypt', undecryptableEvent, event);
|
|
2829
2887
|
if (emitUndecryptable)
|
|
2830
|
-
|
|
2888
|
+
this._dispatcher.enqueue(undecryptableEvent, event);
|
|
2831
2889
|
return null;
|
|
2832
2890
|
}
|
|
2833
2891
|
this._clientLog.debug(`V2 decrypt key lookup ok: seq=${String(msg.seq ?? '')}, group=${groupIdForKeys || '<p2p>'}, ik_len=${ikPriv.byteLength}, spk_len=${spkPriv?.byteLength ?? 0}`);
|
|
@@ -2862,11 +2920,12 @@ export class AUNClient {
|
|
|
2862
2920
|
_decrypt_stage: 'sender_ik',
|
|
2863
2921
|
_envelope_type: String(envelope.type ?? ''),
|
|
2864
2922
|
_suite: String(envelope.suite ?? ''),
|
|
2923
|
+
source,
|
|
2865
2924
|
};
|
|
2866
2925
|
this._attachV2EnvelopeMetadata(event, e2eeMeta);
|
|
2867
2926
|
this._logMessageDebug('decrypt-fail', 'v2.decrypt', undecryptableEvent, event);
|
|
2868
2927
|
if (emitUndecryptable)
|
|
2869
|
-
|
|
2928
|
+
this._dispatcher.enqueue(undecryptableEvent, event);
|
|
2870
2929
|
return null;
|
|
2871
2930
|
}
|
|
2872
2931
|
let plaintext;
|
|
@@ -2891,11 +2950,12 @@ export class AUNClient {
|
|
|
2891
2950
|
_decrypt_stage: 'decrypt',
|
|
2892
2951
|
_envelope_type: String(envelope.type ?? ''),
|
|
2893
2952
|
_suite: String(envelope.suite ?? ''),
|
|
2953
|
+
source,
|
|
2894
2954
|
};
|
|
2895
2955
|
this._attachV2EnvelopeMetadata(event, e2eeMeta);
|
|
2896
2956
|
this._logMessageDebug('decrypt-fail', 'v2.decrypt', undecryptableEvent, event);
|
|
2897
2957
|
if (emitUndecryptable)
|
|
2898
|
-
|
|
2958
|
+
this._dispatcher.enqueue(undecryptableEvent, event);
|
|
2899
2959
|
return null;
|
|
2900
2960
|
}
|
|
2901
2961
|
if (plaintext === null) {
|
|
@@ -3437,7 +3497,7 @@ export class AUNClient {
|
|
|
3437
3497
|
if (this._sessionParams !== null && identity.access_token) {
|
|
3438
3498
|
this._sessionParams.access_token = identity.access_token;
|
|
3439
3499
|
}
|
|
3440
|
-
|
|
3500
|
+
this._dispatcher.enqueue('token.refreshed', {
|
|
3441
3501
|
aid: identity.aid,
|
|
3442
3502
|
expires_at: identity.access_token_expires_at,
|
|
3443
3503
|
});
|
|
@@ -3447,7 +3507,7 @@ export class AUNClient {
|
|
|
3447
3507
|
if (exc instanceof AuthError) {
|
|
3448
3508
|
if (authErrorRequiresRelogin(exc)) {
|
|
3449
3509
|
this._clientLog.warn(`token refresh requires relogin, stopping refresh loop and triggering reconnect: ${exc.message}`);
|
|
3450
|
-
|
|
3510
|
+
this._dispatcher.enqueue('token.refresh_exhausted', {
|
|
3451
3511
|
aid: this._identity?.aid ?? null,
|
|
3452
3512
|
consecutive_failures: 1,
|
|
3453
3513
|
last_error: String(exc),
|
|
@@ -3460,7 +3520,7 @@ export class AUNClient {
|
|
|
3460
3520
|
this._tokenRefreshFailures++;
|
|
3461
3521
|
if (this._tokenRefreshFailures >= 3) {
|
|
3462
3522
|
this._clientLog.warn(`token refresh failed ${this._tokenRefreshFailures} consecutive times, stopping refresh loop and triggering reconnect`);
|
|
3463
|
-
|
|
3523
|
+
this._dispatcher.enqueue('token.refresh_exhausted', {
|
|
3464
3524
|
aid: this._identity?.aid ?? null,
|
|
3465
3525
|
consecutive_failures: this._tokenRefreshFailures,
|
|
3466
3526
|
last_error: String(exc),
|
|
@@ -3472,7 +3532,7 @@ export class AUNClient {
|
|
|
3472
3532
|
this._clientLog.debug(`token refresh failed (${this._tokenRefreshFailures}/3), will retry: ${exc}`);
|
|
3473
3533
|
}
|
|
3474
3534
|
else {
|
|
3475
|
-
|
|
3535
|
+
this._dispatcher.enqueue('connection.error', { error: formatCaughtError(exc) });
|
|
3476
3536
|
}
|
|
3477
3537
|
}
|
|
3478
3538
|
scheduleNext();
|
|
@@ -3543,7 +3603,7 @@ export class AUNClient {
|
|
|
3543
3603
|
this._lastDisconnectInfo = { code, reason, detail };
|
|
3544
3604
|
// 透传给应用层订阅者
|
|
3545
3605
|
try {
|
|
3546
|
-
|
|
3606
|
+
this._dispatcher.enqueue('gateway.disconnect', {
|
|
3547
3607
|
code,
|
|
3548
3608
|
reason,
|
|
3549
3609
|
detail,
|
|
@@ -3669,13 +3729,7 @@ export class AUNClient {
|
|
|
3669
3729
|
async _publishReconnectEvent(owner, event, payload) {
|
|
3670
3730
|
if (!this._ownsReconnect(owner))
|
|
3671
3731
|
return false;
|
|
3672
|
-
this.
|
|
3673
|
-
try {
|
|
3674
|
-
await this._dispatcher.publish(event, payload);
|
|
3675
|
-
}
|
|
3676
|
-
finally {
|
|
3677
|
-
this._reconnectEventDispatchDepth -= 1;
|
|
3678
|
-
}
|
|
3732
|
+
this._dispatcher.enqueue(event, payload);
|
|
3679
3733
|
return this._ownsReconnect(owner);
|
|
3680
3734
|
}
|
|
3681
3735
|
async _cancelReconnectAndWait() {
|