@agentunion/fastaun 0.5.31 → 0.5.32
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 +39 -1
- package/_packed_docs/CHANGELOG.md +39 -1
- package/_packed_docs/sdk/0.5.32-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +350 -0
- package/_packed_docs/sdk/0.5.32-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +319 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +12 -5
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +459 -0
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/274/200/345/217/221/347/247/273/346/244/215/346/214/207/345/215/227.md +554 -0
- package/_packed_docs/sdk/INDEX.md +27 -5
- package/_packed_docs/sdk//345/255/220AID/344/277/256/346/224/271agent.md/351/200/232/347/237/245Owner/345/234/272/346/231/257/346/214/207/345/215/227.md +234 -0
- package/dist/client/control-messages.d.ts +22 -6
- package/dist/client/control-messages.js +208 -146
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.d.ts +3 -0
- package/dist/client/delivery.js +67 -3
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts +3 -0
- package/dist/client/group-state.js +48 -14
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +3 -2
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +9 -3
- package/dist/client/rpc-pipeline.js +53 -22
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +13 -1
- package/dist/client/v2-e2ee.js +32 -19
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +6 -1
- package/dist/client.js +57 -21
- package/dist/client.js.map +1 -1
- package/dist/group-fs.js +1 -1
- package/dist/group-fs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ownership-workflow.js +3 -3
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/pubsub/binding.d.ts +54 -0
- package/dist/pubsub/binding.js +343 -0
- package/dist/pubsub/binding.js.map +1 -0
- package/dist/pubsub/channel.d.ts +45 -0
- package/dist/pubsub/channel.js +137 -0
- package/dist/pubsub/channel.js.map +1 -0
- package/dist/pubsub/client.d.ts +93 -0
- package/dist/pubsub/client.js +318 -0
- package/dist/pubsub/client.js.map +1 -0
- package/dist/pubsub/credentials.d.ts +51 -0
- package/dist/pubsub/credentials.js +360 -0
- package/dist/pubsub/credentials.js.map +1 -0
- package/dist/pubsub/errors.d.ts +5 -0
- package/dist/pubsub/errors.js +6 -0
- package/dist/pubsub/errors.js.map +1 -0
- package/dist/pubsub/index.d.ts +48 -0
- package/dist/pubsub/index.js +152 -0
- package/dist/pubsub/index.js.map +1 -0
- package/dist/pubsub/scheduler.d.ts +58 -0
- package/dist/pubsub/scheduler.js +249 -0
- package/dist/pubsub/scheduler.js.map +1 -0
- package/dist/pubsub/service.d.ts +100 -0
- package/dist/pubsub/service.js +650 -0
- package/dist/pubsub/service.js.map +1 -0
- package/dist/pubsub/types.d.ts +119 -0
- package/dist/pubsub/types.js +2 -0
- package/dist/pubsub/types.js.map +1 -0
- package/dist/storage/lowlevel.js +44 -7
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/read-cache.d.ts +7 -3
- package/dist/storage/read-cache.js +137 -18
- package/dist/storage/read-cache.js.map +1 -1
- package/dist/storage/vfs.d.ts +1 -0
- package/dist/storage/vfs.js +11 -1
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +1 -1
- package/dist/tools/pubsub-actor.d.ts +27 -0
- package/dist/tools/pubsub-actor.js +260 -0
- package/dist/tools/pubsub-actor.js.map +1 -0
- package/dist/transport.d.ts +25 -1
- package/dist/transport.js +175 -10
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { AIDStore } from './aid-store.js';
|
|
14
14
|
import { type Subscription, type EventHandler } from './events.js';
|
|
15
|
+
import { type RpcCallOptions } from './client/rpc-pipeline.js';
|
|
15
16
|
import { type RiskStateEvent } from './risk-control.js';
|
|
16
17
|
import { CollabClient } from './collab/client.js';
|
|
17
18
|
import { DebugFacade, CredentialFacade, OrgFacade, GroupFacade, MailFacade, MessageFacade, StreamFacade } from './facades.js';
|
|
19
|
+
import { EventService } from './pubsub/index.js';
|
|
18
20
|
import { StorageVFS } from './storage/vfs.js';
|
|
19
21
|
import { type JsonObject, type JsonValue, type RpcParams, type RpcResult, ConnectionState } from './types.js';
|
|
20
22
|
import { AID } from './aid.js';
|
|
@@ -102,6 +104,7 @@ export declare class AUNClient {
|
|
|
102
104
|
private _credentialRenewalTimer;
|
|
103
105
|
private _credentialRenewalAbort;
|
|
104
106
|
private _credentialRenewalScan;
|
|
107
|
+
private _credentialRenewalBackground;
|
|
105
108
|
private _nextCredentialRevocationSyncAt;
|
|
106
109
|
private _getCredentialRenewal;
|
|
107
110
|
_assertCredentialNotRevoked(credential: JsonObject, proofChain?: JsonObject[]): () => void;
|
|
@@ -266,6 +269,7 @@ export declare class AUNClient {
|
|
|
266
269
|
private _storage?;
|
|
267
270
|
private _collab?;
|
|
268
271
|
private _message?;
|
|
272
|
+
private _eventServiceFacade?;
|
|
269
273
|
private _debug?;
|
|
270
274
|
private _mail?;
|
|
271
275
|
private _group?;
|
|
@@ -284,6 +288,7 @@ export declare class AUNClient {
|
|
|
284
288
|
/** AUN Collab 入口 */
|
|
285
289
|
get collab(): CollabClient;
|
|
286
290
|
get debug(): DebugFacade;
|
|
291
|
+
get EventService(): EventService;
|
|
287
292
|
/** Message facade 入口 */
|
|
288
293
|
get message(): MessageFacade;
|
|
289
294
|
/** Group facade 入口 */
|
|
@@ -400,7 +405,7 @@ export declare class AUNClient {
|
|
|
400
405
|
* 发送 JSON-RPC 调用。
|
|
401
406
|
* 自动处理内部方法限制、E2EE 加解密、客户端签名等。
|
|
402
407
|
*/
|
|
403
|
-
call(method: string, params?: RpcParams): Promise<RpcResult>;
|
|
408
|
+
call(method: string, params?: RpcParams, options?: RpcCallOptions): Promise<RpcResult>;
|
|
404
409
|
private _entityOwnershipGuard;
|
|
405
410
|
private _prepareEntityOwnershipLifecycle;
|
|
406
411
|
private _checkEntityOwnershipOnAccess;
|
package/dist/client.js
CHANGED
|
@@ -42,6 +42,7 @@ import { RiskController } from './risk-control.js';
|
|
|
42
42
|
import { ControlMessageCoordinator, messageClassOf } from './client/control-messages.js';
|
|
43
43
|
import { CollabClient } from './collab/client.js';
|
|
44
44
|
import { DebugFacade, CredentialFacade, OrgFacade, GroupFacade, MailFacade, MessageFacade, StreamFacade } from './facades.js';
|
|
45
|
+
import { EventService } from './pubsub/index.js';
|
|
45
46
|
import { StorageVFS } from './storage/vfs.js';
|
|
46
47
|
import { V2E2EECoordinator } from './client/v2-e2ee.js';
|
|
47
48
|
import { GroupStateCoordinator } from './client/group-state.js';
|
|
@@ -591,6 +592,7 @@ export class AUNClient {
|
|
|
591
592
|
_credentialRenewalTimer = null;
|
|
592
593
|
_credentialRenewalAbort = null;
|
|
593
594
|
_credentialRenewalScan = Promise.resolve();
|
|
595
|
+
_credentialRenewalBackground = false;
|
|
594
596
|
_nextCredentialRevocationSyncAt = 0;
|
|
595
597
|
_getCredentialRenewal() {
|
|
596
598
|
return this._credentialRenewal ??= new CredentialRenewal({
|
|
@@ -625,6 +627,8 @@ export class AUNClient {
|
|
|
625
627
|
certificate: (aid, fingerprint, signedAt) => signedAt === undefined
|
|
626
628
|
? this._fetchServiceEventCertificate(aid, fingerprint) : this._fetchPeerCert(aid, fingerprint, undefined, signedAt),
|
|
627
629
|
call: (method, params, onSent) => {
|
|
630
|
+
if (this._credentialRenewalBackground && params._rpc_background === undefined && params._rpc_background_kind === undefined)
|
|
631
|
+
params = { ...params, _rpc_background: true };
|
|
628
632
|
if (!onSent)
|
|
629
633
|
return this._rpcPipeline.call(method, params);
|
|
630
634
|
const version = this._serviceEventIdentityVersion, aid = this._aid;
|
|
@@ -634,7 +638,7 @@ export class AUNClient {
|
|
|
634
638
|
await onSent();
|
|
635
639
|
});
|
|
636
640
|
},
|
|
637
|
-
send: (to, payload) => this.call('message.send', { to, encrypt: true, payload }),
|
|
641
|
+
send: (to, payload) => this.call('message.send', { to, encrypt: true, payload, ...(this._credentialRenewalBackground ? { _rpc_background: true } : {}) }),
|
|
638
642
|
});
|
|
639
643
|
}
|
|
640
644
|
_assertCredentialNotRevoked(credential, proofChain) {
|
|
@@ -710,10 +714,18 @@ export class AUNClient {
|
|
|
710
714
|
const task = this._credentialRenewalScan.then(async () => {
|
|
711
715
|
if (!current())
|
|
712
716
|
return;
|
|
717
|
+
if (this._transport._rateLimitRemainingMs() > 0)
|
|
718
|
+
return;
|
|
713
719
|
const syncRevocations = this._sessionOptions.connection_kind !== 'short' && Date.now() >= this._nextCredentialRevocationSyncAt;
|
|
714
720
|
if (syncRevocations)
|
|
715
721
|
this._nextCredentialRevocationSyncAt = Date.now() + 3_600_000;
|
|
716
|
-
|
|
722
|
+
this._credentialRenewalBackground = true;
|
|
723
|
+
try {
|
|
724
|
+
await this._resumeCredentialRenewalAfterConnect(guard, syncRevocations);
|
|
725
|
+
}
|
|
726
|
+
finally {
|
|
727
|
+
this._credentialRenewalBackground = false;
|
|
728
|
+
}
|
|
717
729
|
});
|
|
718
730
|
this._credentialRenewalScan = task.catch(() => { });
|
|
719
731
|
await this._safeAsync(task);
|
|
@@ -1035,6 +1047,7 @@ export class AUNClient {
|
|
|
1035
1047
|
_storage;
|
|
1036
1048
|
_collab;
|
|
1037
1049
|
_message;
|
|
1050
|
+
_eventServiceFacade;
|
|
1038
1051
|
_debug;
|
|
1039
1052
|
_mail;
|
|
1040
1053
|
_group;
|
|
@@ -1275,6 +1288,11 @@ export class AUNClient {
|
|
|
1275
1288
|
});
|
|
1276
1289
|
return this._debug;
|
|
1277
1290
|
}
|
|
1291
|
+
get EventService() {
|
|
1292
|
+
if (!this._eventServiceFacade)
|
|
1293
|
+
this._eventServiceFacade = new EventService(this);
|
|
1294
|
+
return this._eventServiceFacade;
|
|
1295
|
+
}
|
|
1278
1296
|
/** Message facade 入口 */
|
|
1279
1297
|
get message() {
|
|
1280
1298
|
if (!this._message)
|
|
@@ -1330,8 +1348,8 @@ export class AUNClient {
|
|
|
1330
1348
|
}
|
|
1331
1349
|
async _localOwnershipOperation(sub, next) {
|
|
1332
1350
|
const sources = [this, sub, ...(next ? [next] : [])];
|
|
1333
|
-
if (sources.some((source, index) => !(source instanceof AUNClient) || !source._currentAid?.isPrivateKeyValid() || !source._currentAid.isCertValid() || !source._currentAid.privateKeyPem || source._currentAid.aid !== source._aid || (index === 1 ? source.getType()
|
|
1334
|
-
throw ownershipFailure('forbidden', 'local ownership requires a distinct
|
|
1351
|
+
if (sources.some((source, index) => !(source instanceof AUNClient) || !source._currentAid?.isPrivateKeyValid() || !source._currentAid.isCertValid() || !source._currentAid.privateKeyPem || source._currentAid.aid !== source._aid || (index === 1 ? ['human', 'group', 'org'].includes(source.getType()) : !['human', 'agent'].includes(source.getType()))) || new Set(sources.map((source) => source._aid)).size !== sources.length)
|
|
1352
|
+
throw ownershipFailure('forbidden', 'local ownership requires a distinct non-human subaid outside group/org lifecycles and human or agent owners with private identities');
|
|
1335
1353
|
const identities = sources.map((source) => [source._aid, source._currentAid, source._serviceEventIdentityVersion]);
|
|
1336
1354
|
const guard = () => { if (sources.some((source, index) => source._aid !== identities[index][0] || source._currentAid !== identities[index][1] || source._serviceEventIdentityVersion !== identities[index][2]))
|
|
1337
1355
|
throw ownershipFailure('conflict', 'local ownership source identity changed'); };
|
|
@@ -1343,8 +1361,8 @@ export class AUNClient {
|
|
|
1343
1361
|
throw ownershipFailure('forbidden', 'local ownership requires a published agent document');
|
|
1344
1362
|
const verified = await source._getOwnershipFiles().verifyFile(document.content, 'agent', source._aid);
|
|
1345
1363
|
guard();
|
|
1346
|
-
if (
|
|
1347
|
-
throw ownershipFailure('forbidden', 'local ownership requires
|
|
1364
|
+
if (typeof verified.frontmatter.type !== 'string' || !verified.frontmatter.type.trim() || (index === 1 ? ['human', 'group', 'org'].includes(verified.frontmatter.type) : !['human', 'agent'].includes(verified.frontmatter.type)))
|
|
1365
|
+
throw ownershipFailure('forbidden', 'local ownership requires a non-human subaid outside group/org lifecycles and human or agent owners');
|
|
1348
1366
|
}
|
|
1349
1367
|
const slot = `ownership-${crypto.randomUUID()}`, clients = [];
|
|
1350
1368
|
try {
|
|
@@ -1904,14 +1922,14 @@ export class AUNClient {
|
|
|
1904
1922
|
* 发送 JSON-RPC 调用。
|
|
1905
1923
|
* 自动处理内部方法限制、E2EE 加解密、客户端签名等。
|
|
1906
1924
|
*/
|
|
1907
|
-
async call(method, params) {
|
|
1925
|
+
async call(method, params, options) {
|
|
1908
1926
|
const assertCurrent = ['group.transfer_owner', 'org.lifecycle.transfer', 'group.dissolve', 'org.lifecycle.dissolve'].includes(method) ? this._entityOwnershipGuard() : undefined;
|
|
1909
1927
|
const recoverOwnership = ['group.transfer_owner', 'org.lifecycle.transfer', 'group.dissolve', 'org.lifecycle.dissolve'].includes(method) ? await this._prepareEntityOwnershipLifecycle(method, params ?? {}) : undefined;
|
|
1910
1928
|
await this._checkEntityOwnershipOnAccess(method, params ?? {});
|
|
1911
1929
|
const readIdentity = ['message.read', 'message.read_state', 'group.read', 'group.read_state'].includes(method)
|
|
1912
1930
|
? this._ensureReadStateIdentity() : null;
|
|
1913
1931
|
try {
|
|
1914
|
-
const result = await this._rpcPipeline.call(method, params, assertCurrent);
|
|
1932
|
+
const result = await (options === undefined ? this._rpcPipeline.call(method, params, assertCurrent) : this._rpcPipeline.call(method, params, assertCurrent, options));
|
|
1915
1933
|
await this._safeAsync(this._getCredentialRenewal().observe(method, params ?? {}, result));
|
|
1916
1934
|
if (readIdentity !== null && readIdentity === this._ensureReadStateIdentity())
|
|
1917
1935
|
this._observeReadStateResult(method, result, params ?? {});
|
|
@@ -3231,8 +3249,8 @@ export class AUNClient {
|
|
|
3231
3249
|
const messageEvent = event === 'message.received' || event === 'message.recalled' || event === 'message.batch';
|
|
3232
3250
|
const hadMessageConsumer = messageEvent && [...this._dispatcher._snapshotApplicationHandlers(['message.received', 'message.recalled', 'message.batch']).values()].some((handlers) => handlers.length > 0);
|
|
3233
3251
|
const result = this._dispatcher.subscribe(event, handler);
|
|
3234
|
-
if (messageEvent) {
|
|
3235
|
-
if (this._p2pPeerPullEnabled && !hadMessageConsumer)
|
|
3252
|
+
if (messageEvent || event === 'group.message_created' || event === 'group.message_batch') {
|
|
3253
|
+
if (messageEvent && this._p2pPeerPullEnabled && !hadMessageConsumer)
|
|
3236
3254
|
this._delivery.refreshPendingPeers();
|
|
3237
3255
|
this._delivery.requestBackgroundPullRecovery();
|
|
3238
3256
|
}
|
|
@@ -3376,7 +3394,7 @@ export class AUNClient {
|
|
|
3376
3394
|
const errors = [];
|
|
3377
3395
|
for (const entry of [...this._readStateQueries.values()]) {
|
|
3378
3396
|
try {
|
|
3379
|
-
const result = await this.call(entry.method, { ...entry.params });
|
|
3397
|
+
const result = await this.call(entry.method, { ...entry.params, _rpc_background: true });
|
|
3380
3398
|
if (identity !== this._ensureReadStateIdentity())
|
|
3381
3399
|
return;
|
|
3382
3400
|
this._observeReadStateResult(entry.method, result, entry.params);
|
|
@@ -4386,7 +4404,7 @@ export class AUNClient {
|
|
|
4386
4404
|
const seen = new Set();
|
|
4387
4405
|
do {
|
|
4388
4406
|
if (response === undefined) {
|
|
4389
|
-
response = await this.call('group.list_my_invites', cursor ? { cursor } : {});
|
|
4407
|
+
response = await this.call('group.list_my_invites', { ...(cursor ? { cursor } : {}), _rpc_background: true });
|
|
4390
4408
|
}
|
|
4391
4409
|
let items = [];
|
|
4392
4410
|
let nextCursor = '';
|
|
@@ -4500,6 +4518,7 @@ export class AUNClient {
|
|
|
4500
4518
|
const tStart = Date.now();
|
|
4501
4519
|
connectionOwner ??= this._connectAbort ?? undefined;
|
|
4502
4520
|
this._lifecycle.assertConnectionAttemptOwner(connectionOwner);
|
|
4521
|
+
this._controlMessageCoordinator?.close();
|
|
4503
4522
|
const gatewayUrl = this._resolveGateway(params);
|
|
4504
4523
|
this._gatewayUrl = gatewayUrl;
|
|
4505
4524
|
this._slotId = String(params.slot_id ?? '');
|
|
@@ -4512,7 +4531,7 @@ export class AUNClient {
|
|
|
4512
4531
|
delete capabilities.message_classes_v1;
|
|
4513
4532
|
if (typeof this._tokenStore.updateInstanceState === 'function') {
|
|
4514
4533
|
capabilities.message_classes_v2 = { p2p: ['normal', 'control', 'sdk_control'], group: ['normal', 'control'] };
|
|
4515
|
-
capabilities.sdk_control_protocols = { 'aun.agent_md.changed': [1] };
|
|
4534
|
+
capabilities.sdk_control_protocols = { 'aun.agent_md.changed': [1], 'aun.pubsub': [1] };
|
|
4516
4535
|
}
|
|
4517
4536
|
else {
|
|
4518
4537
|
delete capabilities.message_classes_v2;
|
|
@@ -4657,8 +4676,6 @@ export class AUNClient {
|
|
|
4657
4676
|
else {
|
|
4658
4677
|
this._clientLog.debug('V2 session init deferred for short connection');
|
|
4659
4678
|
}
|
|
4660
|
-
this._controlMessages().close();
|
|
4661
|
-
this._safeAsync(this._controlMessages().recover());
|
|
4662
4679
|
this._agentMdChanges?.close();
|
|
4663
4680
|
this._agentMdChanges = new AgentMdChangeCoordinator(this);
|
|
4664
4681
|
// connect/reconnect 成功后自动触发一次 P2P message.v2.pull,补齐离线期间积压
|
|
@@ -4672,6 +4689,10 @@ export class AUNClient {
|
|
|
4672
4689
|
this._entityOwnershipChecks.clear();
|
|
4673
4690
|
if (!this._ownershipOperation)
|
|
4674
4691
|
this._safeAsync(this._checkIdentityAdmissionAfterConnect());
|
|
4692
|
+
this._safeAsync(this._delivery.restoreMessageClassPulls());
|
|
4693
|
+
if (!isShortConnection && backgroundSyncEnabled && this._v2Session) {
|
|
4694
|
+
this._safeAsync(this._v2AutoConfirmPendingProposals());
|
|
4695
|
+
}
|
|
4675
4696
|
this._clientLog.debug(`_connectOnce exit: elapsed=${Date.now() - tStart}ms gateway=${gatewayUrl}, aid=${this._aid ?? ''}`);
|
|
4676
4697
|
}
|
|
4677
4698
|
catch (err) {
|
|
@@ -4823,8 +4844,8 @@ export class AUNClient {
|
|
|
4823
4844
|
async _getV2SenderPubDer(fromAid, senderDeviceId, certFingerprint) {
|
|
4824
4845
|
return await this._v2E2EE.getV2SenderPubDer(fromAid, senderDeviceId, certFingerprint);
|
|
4825
4846
|
}
|
|
4826
|
-
async _fetchV2SenderIKOnce(fromAid, senderDeviceId, groupId, certFingerprint) {
|
|
4827
|
-
return await this._v2E2EE.fetchSenderIKOnce(fromAid, senderDeviceId, groupId, certFingerprint);
|
|
4847
|
+
async _fetchV2SenderIKOnce(fromAid, senderDeviceId, groupId, certFingerprint, rpcOptions) {
|
|
4848
|
+
return await this._v2E2EE.fetchSenderIKOnce(fromAid, senderDeviceId, groupId, certFingerprint, ...(rpcOptions ? [rpcOptions] : []));
|
|
4828
4849
|
}
|
|
4829
4850
|
_cacheV2PeerIKFromDevice(dev, fallbackAid = '') {
|
|
4830
4851
|
const session = this._v2Session;
|
|
@@ -4885,7 +4906,9 @@ export class AUNClient {
|
|
|
4885
4906
|
return await this._v2E2EE.ackGroupV2(groupId, upToSeq, groupAid);
|
|
4886
4907
|
}
|
|
4887
4908
|
/** 解密单条 V2 pull 消息。缺 sender IK 时先入 pending,后台补齐后重试。 */
|
|
4888
|
-
async _decryptV2Message(msg, allowPending = true, emitUndecryptable = true, rotateKeys = true, observeAgentMd = true, deferStatus, deferKeyFetch = false, source = 'pull', deferredEffects) {
|
|
4909
|
+
async _decryptV2Message(msg, allowPending = true, emitUndecryptable = true, rotateKeys = true, observeAgentMd = true, deferStatus, deferKeyFetch = false, source = 'pull', deferredEffects, rpcOptions) {
|
|
4910
|
+
if (rpcOptions?.deadline !== undefined && rpcOptions.deadline <= Date.now())
|
|
4911
|
+
return null;
|
|
4889
4912
|
const session = this._v2Session;
|
|
4890
4913
|
if (!session)
|
|
4891
4914
|
return null;
|
|
@@ -5000,9 +5023,11 @@ export class AUNClient {
|
|
|
5000
5023
|
const senderDeviceId = String(aad.from_device ?? '');
|
|
5001
5024
|
const senderCertFingerprint = String(envelope.sender_cert_fingerprint ?? '').trim().toLowerCase();
|
|
5002
5025
|
let senderPubDer = await this._getV2SenderPubDer(fromAid, senderDeviceId, senderCertFingerprint);
|
|
5026
|
+
if (rpcOptions?.deadline !== undefined && rpcOptions.deadline <= Date.now())
|
|
5027
|
+
return null;
|
|
5003
5028
|
if (!senderPubDer && !deferKeyFetch) {
|
|
5004
5029
|
this._clientLog.warn(`V2 decrypt: no sender IK for ${fromAid} device=${senderDeviceId}`);
|
|
5005
|
-
senderPubDer = await this._fetchV2SenderIKOnce(fromAid, senderDeviceId, groupIdForKeys, senderCertFingerprint);
|
|
5030
|
+
senderPubDer = await this._fetchV2SenderIKOnce(fromAid, senderDeviceId, groupIdForKeys, senderCertFingerprint, ...(rpcOptions ? [rpcOptions] : []));
|
|
5006
5031
|
}
|
|
5007
5032
|
if (!senderPubDer) {
|
|
5008
5033
|
if (allowPending || deferStatus) {
|
|
@@ -5334,7 +5359,7 @@ export class AUNClient {
|
|
|
5334
5359
|
}
|
|
5335
5360
|
}
|
|
5336
5361
|
/** 发现并缓存全部 Gateway 候选,供首连和自动重连故障转移使用。 */
|
|
5337
|
-
async _resolveGatewayCandidatesForAid(aid, fresh = false, reconnectOwner) {
|
|
5362
|
+
async _resolveGatewayCandidatesForAid(aid, fresh = false, reconnectOwner, connectionOwner) {
|
|
5338
5363
|
const resolvedAid = String(aid ?? this._aid ?? '').trim();
|
|
5339
5364
|
if (!resolvedAid) {
|
|
5340
5365
|
throw new StateError('gateway discovery requires a loaded AID');
|
|
@@ -5348,7 +5373,8 @@ export class AUNClient {
|
|
|
5348
5373
|
const discoveryIsCurrent = () => (this._discovery === discovery
|
|
5349
5374
|
&& this._tokenStore === tokenStore
|
|
5350
5375
|
&& !this._closing
|
|
5351
|
-
&& (!reconnectOwner || this._ownsReconnect(reconnectOwner))
|
|
5376
|
+
&& (!reconnectOwner || this._ownsReconnect(reconnectOwner))
|
|
5377
|
+
&& (!connectionOwner || this._lifecycle.ownsConnectionAttempt(connectionOwner)));
|
|
5352
5378
|
if (!fresh && sameIssuer && this._gatewayCandidates.length > 0)
|
|
5353
5379
|
return [...this._gatewayCandidates];
|
|
5354
5380
|
if (!fresh && sameIssuer && this._gatewayUrl) {
|
|
@@ -5641,6 +5667,11 @@ export class AUNClient {
|
|
|
5641
5667
|
scheduleNext();
|
|
5642
5668
|
return;
|
|
5643
5669
|
}
|
|
5670
|
+
const rateLimitRemaining = this._transport._rateLimitRemainingMs();
|
|
5671
|
+
if (rateLimitRemaining > 0) {
|
|
5672
|
+
scheduleNext(rateLimitRemaining);
|
|
5673
|
+
return;
|
|
5674
|
+
}
|
|
5644
5675
|
let identity = this._identity;
|
|
5645
5676
|
if (identity === null) {
|
|
5646
5677
|
scheduleNext();
|
|
@@ -5678,6 +5709,11 @@ export class AUNClient {
|
|
|
5678
5709
|
this._tokenRefreshFailures = 0;
|
|
5679
5710
|
}
|
|
5680
5711
|
catch (exc) {
|
|
5712
|
+
if (exc instanceof AUNError && (exc.code === -32429 || exc.code === -32029 || exc.code === 429 || exc.code === 4290)) {
|
|
5713
|
+
this._transport._observeRateLimit(exc);
|
|
5714
|
+
scheduleNext(this._transport._rateLimitRemainingMs());
|
|
5715
|
+
return;
|
|
5716
|
+
}
|
|
5681
5717
|
if (exc instanceof AuthError) {
|
|
5682
5718
|
if (authErrorRequiresRelogin(exc)) {
|
|
5683
5719
|
this._clientLog.warn(`token refresh requires relogin, stopping refresh loop and triggering reconnect: ${exc.message}`);
|