@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.
Files changed (43) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/_packed_docs/CHANGELOG.md +64 -0
  3. package/_packed_docs/INDEX.md +3 -3
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +1 -1
  5. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +6 -5
  6. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +102 -8
  7. package/_packed_docs/sdk/09-group-rpc-manual.md +18 -3
  8. package/_packed_docs/sdk/09-message-rpc-manual.md +34 -10
  9. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +3 -2
  10. package/_packed_docs/sdk/INDEX.md +2 -1
  11. package/dist/agent-md.js +5 -1
  12. package/dist/agent-md.js.map +1 -1
  13. package/dist/auth.d.ts +2 -1
  14. package/dist/auth.js +30 -44
  15. package/dist/auth.js.map +1 -1
  16. package/dist/client/delivery.d.ts +39 -9
  17. package/dist/client/delivery.js +407 -73
  18. package/dist/client/delivery.js.map +1 -1
  19. package/dist/client/group-state.js +6 -6
  20. package/dist/client/group-state.js.map +1 -1
  21. package/dist/client/lifecycle.js +5 -14
  22. package/dist/client/lifecycle.js.map +1 -1
  23. package/dist/client/rpc-pipeline.d.ts +4 -0
  24. package/dist/client/rpc-pipeline.js +51 -5
  25. package/dist/client/rpc-pipeline.js.map +1 -1
  26. package/dist/client/v2-e2ee.d.ts +3 -0
  27. package/dist/client/v2-e2ee.js +236 -59
  28. package/dist/client/v2-e2ee.js.map +1 -1
  29. package/dist/client.d.ts +1 -0
  30. package/dist/client.js +84 -30
  31. package/dist/client.js.map +1 -1
  32. package/dist/events.d.ts +23 -8
  33. package/dist/events.js +120 -26
  34. package/dist/events.js.map +1 -1
  35. package/dist/register-flow.js +15 -111
  36. package/dist/register-flow.js.map +1 -1
  37. package/dist/transport.d.ts +36 -3
  38. package/dist/transport.js +855 -33
  39. package/dist/transport.js.map +1 -1
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.js +1 -1
  42. package/dist/version.js.map +1 -1
  43. 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.publish(evt, data));
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
- await this._dispatcher.publish('group.changed', data);
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.publish('signature_pending', { aid: sigAid, method }).catch(() => { });
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.publish('signature.verification_failed', {
2135
+ this._dispatcher.enqueue('signature.verification_failed', {
2080
2136
  aid: sigAid, method, error: 'ECDSA verification failed',
2081
- }).catch(() => { });
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.publish('signature.verification_failed', {
2144
+ this._dispatcher.enqueue('signature.verification_failed', {
2089
2145
  aid: String(cs.aid ?? ''), method: String(cs._method ?? ''),
2090
2146
  error: formatCaughtError(exc),
2091
- }).catch(() => { });
2147
+ });
2092
2148
  return false;
2093
2149
  }
2094
2150
  }
@@ -2485,7 +2541,7 @@ export class AUNClient {
2485
2541
  }
2486
2542
  }
2487
2543
  else {
2488
- await this._dispatcher.publish('state_change', statePayload);
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
- await this._dispatcher.publish(undecryptableEvent, event);
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
- await this._dispatcher.publish(undecryptableEvent, event);
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
- await this._dispatcher.publish(undecryptableEvent, event);
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
- await this._dispatcher.publish('token.refreshed', {
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
- await this._dispatcher.publish('token.refresh_exhausted', {
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
- await this._dispatcher.publish('token.refresh_exhausted', {
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
- await this._dispatcher.publish('connection.error', { error: formatCaughtError(exc) });
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
- await this._dispatcher.publish('gateway.disconnect', {
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._reconnectEventDispatchDepth += 1;
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() {