@agentunion/fastaun 0.5.33 → 0.5.34
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 +30 -2
- package/README.md +28 -26
- package/_packed_docs/CHANGELOG.md +30 -2
- package/_packed_docs/INDEX.md +17 -3
- package/_packed_docs/KITE_DOCS_GUIDE.md +10 -4
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +58 -8
- package/_packed_docs/sdk/0.5.33-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +464 -316
- package/_packed_docs/sdk/0.5.33-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +499 -304
- package/_packed_docs/sdk/0.5.34-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +133 -0
- package/_packed_docs/sdk/0.5.34-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +107 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +16 -13
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +13 -1
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +17 -7
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +55 -14
- package/_packed_docs/sdk/09-collab-rpc-manual.md +48 -30
- package/_packed_docs/sdk/09-custody-api-manual.md +3 -3
- package/_packed_docs/sdk/09-group-rpc-manual.md +53 -6
- package/_packed_docs/sdk/09-message-rpc-manual.md +22 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +2 -1
- package/_packed_docs/sdk/09-payload-reference.md +9 -8
- package/_packed_docs/sdk/09-proxy-rpc-manual.md +20 -14
- package/_packed_docs/sdk/09-storage-rpc-manual.md +1698 -1659
- package/_packed_docs/sdk/09-stream-rpc-manual.md +33 -20
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +11 -9
- 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 +53 -28
- 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 +62 -28
- package/_packed_docs/sdk/INDEX.md +21 -9
- package/_packed_docs/sdk/README.md +11 -6
- package/dist/auth.js +8 -2
- package/dist/auth.js.map +1 -1
- package/dist/client/control-messages.js +2 -2
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.d.ts +5 -0
- package/dist/client/delivery.js +146 -32
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/lifecycle.js +3 -0
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-budget.d.ts +21 -0
- package/dist/client/rpc-budget.js +82 -0
- package/dist/client/rpc-budget.js.map +1 -0
- package/dist/client/rpc-pipeline.d.ts +3 -0
- package/dist/client/rpc-pipeline.js +166 -60
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/sync-channels.d.ts +89 -0
- package/dist/client/sync-channels.js +489 -0
- package/dist/client/sync-channels.js.map +1 -0
- package/dist/client/v2-e2ee.d.ts +4 -1
- package/dist/client/v2-e2ee.js +401 -298
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.js +63 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pubsub/binding.js +14 -1
- package/dist/pubsub/binding.js.map +1 -1
- package/dist/pubsub/channel.d.ts +4 -0
- package/dist/pubsub/channel.js +26 -0
- package/dist/pubsub/channel.js.map +1 -1
- package/dist/pubsub/client.d.ts +9 -0
- package/dist/pubsub/client.js +154 -31
- package/dist/pubsub/client.js.map +1 -1
- package/dist/pubsub/credentials.d.ts +3 -0
- package/dist/pubsub/credentials.js +57 -20
- package/dist/pubsub/credentials.js.map +1 -1
- package/dist/pubsub/index.d.ts +3 -0
- package/dist/pubsub/index.js +69 -53
- package/dist/pubsub/index.js.map +1 -1
- package/dist/pubsub/service.d.ts +3 -0
- package/dist/pubsub/service.js +167 -12
- package/dist/pubsub/service.js.map +1 -1
- package/dist/pubsub/types.d.ts +2 -0
- package/dist/storage/lowlevel.d.ts +3 -1
- package/dist/storage/lowlevel.js +13 -0
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/types.d.ts +10 -0
- package/dist/storage/types.js.map +1 -1
- package/dist/storage/vfs.d.ts +3 -1
- package/dist/storage/vfs.js +2 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +55 -5
- package/dist/tools/cross-sdk-agent.js +88 -21
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +12 -0
- package/dist/transport.js +91 -6
- 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/transport.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { EventDispatcher } from './events.js';
|
|
|
11
11
|
import { type ModuleLogger } from './logger.js';
|
|
12
12
|
import { type JsonObject, type RpcMessage, type RpcParams, type RpcResult } from './types.js';
|
|
13
13
|
import { type ServiceEventVerificationResult } from './org-protocol.js';
|
|
14
|
+
import { RpcBudget } from './client/rpc-budget.js';
|
|
14
15
|
export type RpcBackground = false | true | 'event' | 'pull';
|
|
15
16
|
/** 断线回调,closeCode 为 WebSocket close code(1006 = 网络异常断开,其他 = 服务端主动关闭) */
|
|
16
17
|
export type DisconnectCallback = (error: Error | null, closeCode?: number) => void | Promise<void>;
|
|
@@ -26,6 +27,7 @@ export declare function shortRpcViaNetworkActor(url: string, method: string, par
|
|
|
26
27
|
* WebSocket JSON-RPC 2.0 传输层
|
|
27
28
|
*/
|
|
28
29
|
export declare class RPCTransport {
|
|
30
|
+
readonly rpcBudget: RpcBudget;
|
|
29
31
|
private _logger;
|
|
30
32
|
private _dispatcher;
|
|
31
33
|
private _serviceEventVerifier;
|
|
@@ -67,6 +69,10 @@ export declare class RPCTransport {
|
|
|
67
69
|
private _riskDeliveries;
|
|
68
70
|
private _idCounter;
|
|
69
71
|
private _metaObserver;
|
|
72
|
+
private _syncControlObserver;
|
|
73
|
+
private _syncAdmission;
|
|
74
|
+
private _syncAuxiliary;
|
|
75
|
+
private readonly _budgetWaiters;
|
|
70
76
|
private _requestAdmission;
|
|
71
77
|
private _requestCheck;
|
|
72
78
|
private _riskControlHandler;
|
|
@@ -100,6 +106,8 @@ export declare class RPCTransport {
|
|
|
100
106
|
};
|
|
101
107
|
constructor(opts: {
|
|
102
108
|
eventDispatcher: EventDispatcher;
|
|
109
|
+
rpcBudget?: RpcBudget;
|
|
110
|
+
syncAuxiliary?: boolean;
|
|
103
111
|
timeout?: number;
|
|
104
112
|
onDisconnect?: DisconnectCallback | null;
|
|
105
113
|
verifySsl?: boolean;
|
|
@@ -137,6 +145,9 @@ export declare class RPCTransport {
|
|
|
137
145
|
private _finishRiskDelivery;
|
|
138
146
|
private _receiveRiskControl;
|
|
139
147
|
private _dispatchRiskControl;
|
|
148
|
+
setSyncControlObserver(observer: ((meta: Record<string, unknown>, method: string, params: JsonObject) => void) | null): void;
|
|
149
|
+
setSyncAdmission(policy: JsonObject | null): void;
|
|
150
|
+
private _checkSyncAdmission;
|
|
140
151
|
setProtocolMetaObserver(observer: MetaObserver | null): void;
|
|
141
152
|
setProtocolDisconnectCallback(callback: DisconnectCallback | null): void;
|
|
142
153
|
waitForPending(timeoutMs: number, signal?: AbortSignal): Promise<void>;
|
|
@@ -177,6 +188,7 @@ export declare class RPCTransport {
|
|
|
177
188
|
call(method: string, params?: RpcParams, timeout?: number, trace?: string, background?: RpcBackground): Promise<RpcResult>;
|
|
178
189
|
private _callWithSent;
|
|
179
190
|
private _call;
|
|
191
|
+
private _callWithAdmission;
|
|
180
192
|
private _callAdmitted;
|
|
181
193
|
private _callLocal;
|
|
182
194
|
/** 发送 JSON-RPC 2.0 Notification,不分配 id,也不等待响应。 */
|
package/dist/transport.js
CHANGED
|
@@ -16,6 +16,7 @@ import { isJsonObject } from './types.js';
|
|
|
16
16
|
import { parseJsonStrict, validateOrgRequestJSON } from './org-protocol.js';
|
|
17
17
|
import { RiskController } from './risk-control.js';
|
|
18
18
|
import { messageClassOf } from './client/control-messages.js';
|
|
19
|
+
import { RpcBudget } from './client/rpc-budget.js';
|
|
19
20
|
const MAX_WS_PAYLOAD_SIZE = 1_000_000;
|
|
20
21
|
const MAX_RPC_INFLIGHT = 16;
|
|
21
22
|
const MAX_BACKGROUND_RPC_INFLIGHT = 8;
|
|
@@ -550,6 +551,7 @@ export function shortRpcViaNetworkActor(url, method, params, verifySsl = false)
|
|
|
550
551
|
* WebSocket JSON-RPC 2.0 传输层
|
|
551
552
|
*/
|
|
552
553
|
export class RPCTransport {
|
|
554
|
+
rpcBudget;
|
|
553
555
|
_logger;
|
|
554
556
|
_dispatcher;
|
|
555
557
|
_serviceEventVerifier = null;
|
|
@@ -593,6 +595,10 @@ export class RPCTransport {
|
|
|
593
595
|
// Gateway 在 RPC envelope 注入 _meta 字段(与 result 同级),由 client 层 observer 接收。
|
|
594
596
|
// observer 抛异常会被吞掉,不影响 RPC result 返回。
|
|
595
597
|
_metaObserver = null;
|
|
598
|
+
_syncControlObserver = null;
|
|
599
|
+
_syncAdmission = null;
|
|
600
|
+
_syncAuxiliary = false;
|
|
601
|
+
_budgetWaiters = new Set();
|
|
596
602
|
_requestAdmission = null;
|
|
597
603
|
_requestCheck = null;
|
|
598
604
|
_riskControlHandler = null;
|
|
@@ -626,11 +632,13 @@ export class RPCTransport {
|
|
|
626
632
|
};
|
|
627
633
|
}
|
|
628
634
|
get foregroundWaiting() {
|
|
629
|
-
return this._rpcQueue.length;
|
|
635
|
+
return this._rpcQueue.length + this.rpcBudget.foregroundWaiting;
|
|
630
636
|
}
|
|
631
637
|
_eventBackpressure(timeout = 30_000) { if (this._worker)
|
|
632
638
|
return this._workerCommand({ type: 'event_backpressure', timeout }); return Promise.resolve(this.foregroundWaiting > 0 || Number(this._ws?.bufferedAmount ?? 0) >= 65536); }
|
|
633
639
|
constructor(opts) {
|
|
640
|
+
this.rpcBudget = opts.rpcBudget ?? new RpcBudget();
|
|
641
|
+
this._syncAuxiliary = opts.syncAuxiliary ?? false;
|
|
634
642
|
this._logger = opts.logger ?? _noopLogger;
|
|
635
643
|
this._dispatcher = opts.eventDispatcher;
|
|
636
644
|
this._timeout = opts.timeout ?? 35_000;
|
|
@@ -687,6 +695,7 @@ export class RPCTransport {
|
|
|
687
695
|
aunTransportWorker: true,
|
|
688
696
|
timeout: opts.timeout ?? 35_000,
|
|
689
697
|
verifySsl: opts.verifySsl ?? true,
|
|
698
|
+
syncAuxiliary: this._syncAuxiliary,
|
|
690
699
|
},
|
|
691
700
|
});
|
|
692
701
|
this._worker = worker;
|
|
@@ -712,7 +721,7 @@ export class RPCTransport {
|
|
|
712
721
|
return;
|
|
713
722
|
}
|
|
714
723
|
if (message.type === 'foreground_drained') {
|
|
715
|
-
if (this._workerConnected && message.generation === this._workerGeneration)
|
|
724
|
+
if (this._workerConnected && message.generation === this._workerGeneration && !this.rpcBudget.foregroundWaiting)
|
|
716
725
|
this._onForegroundDrained?.();
|
|
717
726
|
return;
|
|
718
727
|
}
|
|
@@ -818,6 +827,9 @@ export class RPCTransport {
|
|
|
818
827
|
pending.reject(error);
|
|
819
828
|
}
|
|
820
829
|
this._workerPending.clear();
|
|
830
|
+
for (const request of this._budgetWaiters)
|
|
831
|
+
request.cancel?.();
|
|
832
|
+
this._budgetWaiters.clear();
|
|
821
833
|
void worker.terminate().catch(() => { });
|
|
822
834
|
if (wasConnected) {
|
|
823
835
|
this._dispatcher.enqueueProtocol('connection.error', { error });
|
|
@@ -864,6 +876,11 @@ export class RPCTransport {
|
|
|
864
876
|
}
|
|
865
877
|
if (this._workerGeneration === null || message.generation !== this._workerGeneration)
|
|
866
878
|
return;
|
|
879
|
+
if (message.event === '_transport.sync_control') {
|
|
880
|
+
const value = message.payload;
|
|
881
|
+
this._syncControlObserver?.(value.meta, value.method, value.params ?? {});
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
867
884
|
if (message.event === '_transport.rate_limit') {
|
|
868
885
|
const until = Number(message.payload?.until_ms);
|
|
869
886
|
if (Number.isFinite(until))
|
|
@@ -1110,6 +1127,23 @@ export class RPCTransport {
|
|
|
1110
1127
|
this._worker.postMessage({ type: 'risk_release', generation: this._workerGeneration ?? undefined });
|
|
1111
1128
|
});
|
|
1112
1129
|
}
|
|
1130
|
+
setSyncControlObserver(observer) {
|
|
1131
|
+
this._syncControlObserver = observer;
|
|
1132
|
+
}
|
|
1133
|
+
setSyncAdmission(policy) {
|
|
1134
|
+
this._syncAdmission = policy ? { ...policy } : null;
|
|
1135
|
+
this._worker?.postMessage({ type: 'sync_admission', syncAdmission: this._syncAdmission });
|
|
1136
|
+
}
|
|
1137
|
+
_checkSyncAdmission(guard) {
|
|
1138
|
+
if (!isJsonObject(guard))
|
|
1139
|
+
return;
|
|
1140
|
+
const value = guard;
|
|
1141
|
+
const policy = this._syncAdmission;
|
|
1142
|
+
if (!policy || policy.parent_connection_id !== value.parent_connection_id || policy.version !== value.version
|
|
1143
|
+
|| Number(policy.max_history_pull_inflight) <= 0 || Number(policy.max_history_inflight_bytes) <= 0 || Number(policy.history_bytes_per_second) <= 0) {
|
|
1144
|
+
throw new StateError('history sync policy changed before send', { data: { sync_policy_changed: true }, retryable: true });
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1113
1147
|
setProtocolMetaObserver(observer) {
|
|
1114
1148
|
this._metaObserver = observer;
|
|
1115
1149
|
this._protocolMetaObserver = true;
|
|
@@ -1528,6 +1562,9 @@ export class RPCTransport {
|
|
|
1528
1562
|
}
|
|
1529
1563
|
/** 关闭连接 */
|
|
1530
1564
|
async close() {
|
|
1565
|
+
for (const request of this._budgetWaiters)
|
|
1566
|
+
request.cancel?.();
|
|
1567
|
+
this._budgetWaiters.clear();
|
|
1531
1568
|
if (this._worker) {
|
|
1532
1569
|
const worker = this._worker;
|
|
1533
1570
|
this._workerConnected = false;
|
|
@@ -1673,6 +1710,25 @@ export class RPCTransport {
|
|
|
1673
1710
|
return Object.assign(result, { cancel: request.cancel });
|
|
1674
1711
|
}
|
|
1675
1712
|
_call(method, params, timeout, trace, background = false, onSent, sentCheckpoint) {
|
|
1713
|
+
const selected = normalizeRpcBackground(background !== false ? background : params?._rpc_background);
|
|
1714
|
+
const kind = selected === true && ['message.peers', 'message.pull', 'message.v2.pull', 'message.ack', 'message.v2.ack', 'group.pull', 'group.v2.pull', 'group.pull_events', 'group.ack_messages', 'group.v2.ack'].includes(method) ? 'pull' : selected;
|
|
1715
|
+
const deadline = Math.min(typeof params?._rpc_deadline === 'number' ? params._rpc_deadline : Infinity, Date.now() + (timeout ?? this._timeout));
|
|
1716
|
+
if (method === 'gateway.risk_ack')
|
|
1717
|
+
return this._callWithAdmission(method, params, Math.max(1, deadline - Date.now()), trace, background, onSent, sentCheckpoint);
|
|
1718
|
+
let started = false;
|
|
1719
|
+
let request;
|
|
1720
|
+
request = this.rpcBudget.run(kind, () => {
|
|
1721
|
+
started = true;
|
|
1722
|
+
this._budgetWaiters.delete(request);
|
|
1723
|
+
return this._callWithAdmission(method, params, Math.max(1, deadline - Date.now()), trace, background, onSent, sentCheckpoint);
|
|
1724
|
+
}, deadline, this._messagePriority(params?.message_class), method);
|
|
1725
|
+
if (!started) {
|
|
1726
|
+
this._budgetWaiters.add(request);
|
|
1727
|
+
void request.then(() => this._budgetWaiters.delete(request), () => this._budgetWaiters.delete(request));
|
|
1728
|
+
}
|
|
1729
|
+
return request;
|
|
1730
|
+
}
|
|
1731
|
+
_callWithAdmission(method, params, timeout, trace, background = false, onSent, sentCheckpoint) {
|
|
1676
1732
|
if (!this._requestAdmission)
|
|
1677
1733
|
return this._callAdmitted(method, params, timeout, trace, background, onSent, sentCheckpoint);
|
|
1678
1734
|
let release;
|
|
@@ -1687,6 +1743,7 @@ export class RPCTransport {
|
|
|
1687
1743
|
}
|
|
1688
1744
|
}
|
|
1689
1745
|
_callAdmitted(method, params, timeout, trace, background = false, onSent, sentCheckpoint) {
|
|
1746
|
+
this._checkSyncAdmission(params?._rpc_sync_guard);
|
|
1690
1747
|
if (this._worker) {
|
|
1691
1748
|
const requestContext = trafficLogContext('outbound', params ?? {});
|
|
1692
1749
|
const requestLog = withLogContext(this._logger, requestContext);
|
|
@@ -1726,6 +1783,10 @@ export class RPCTransport {
|
|
|
1726
1783
|
const backgroundRpc = selectedBackground === true && ['message.peers', 'message.pull', 'message.v2.pull', 'message.ack', 'message.v2.ack', 'group.pull', 'group.v2.pull', 'group.pull_events', 'group.ack_messages', 'group.v2.ack'].includes(method) ? 'pull' : selectedBackground;
|
|
1727
1784
|
delete localParams._rpc_background;
|
|
1728
1785
|
delete localParams._rpc_deadline;
|
|
1786
|
+
const sync = localParams._rpc_sync;
|
|
1787
|
+
delete localParams._rpc_sync;
|
|
1788
|
+
const syncGuard = localParams._rpc_sync_guard;
|
|
1789
|
+
delete localParams._rpc_sync_guard;
|
|
1729
1790
|
const requestContext = trafficLogContext('outbound', sendParams);
|
|
1730
1791
|
const requestLog = withLogContext(this._logger, requestContext);
|
|
1731
1792
|
const responseLog = withLogContext(requestLog, {
|
|
@@ -1746,6 +1807,7 @@ export class RPCTransport {
|
|
|
1746
1807
|
id: rpcId,
|
|
1747
1808
|
method,
|
|
1748
1809
|
params: sendParams,
|
|
1810
|
+
...(sync && typeof sync === 'object' ? { _meta: { sync } } : {}),
|
|
1749
1811
|
});
|
|
1750
1812
|
const payloadSize = new TextEncoder().encode(payload).length;
|
|
1751
1813
|
if (payloadSize > MAX_WS_PAYLOAD_SIZE) {
|
|
@@ -1829,6 +1891,7 @@ export class RPCTransport {
|
|
|
1829
1891
|
priority: this._messagePriority(localParams.message_class),
|
|
1830
1892
|
logger: requestLog,
|
|
1831
1893
|
onSent,
|
|
1894
|
+
...(isJsonObject(syncGuard) ? { syncGuard: syncGuard } : {}),
|
|
1832
1895
|
});
|
|
1833
1896
|
if (backgroundRpc) {
|
|
1834
1897
|
this._rpcQueue.pop();
|
|
@@ -1843,6 +1906,7 @@ export class RPCTransport {
|
|
|
1843
1906
|
priority: this._messagePriority(localParams.message_class),
|
|
1844
1907
|
logger: requestLog,
|
|
1845
1908
|
onSent,
|
|
1909
|
+
...(isJsonObject(syncGuard) ? { syncGuard: syncGuard } : {}),
|
|
1846
1910
|
});
|
|
1847
1911
|
}
|
|
1848
1912
|
this._drainRpcQueue();
|
|
@@ -1874,7 +1938,7 @@ export class RPCTransport {
|
|
|
1874
1938
|
});
|
|
1875
1939
|
}
|
|
1876
1940
|
const normalizedMethod = String(method ?? '').trim();
|
|
1877
|
-
if (!normalizedMethod.startsWith('notification/') && !normalizedMethod.startsWith('event/')) {
|
|
1941
|
+
if (!normalizedMethod.startsWith('notification/') && !normalizedMethod.startsWith('event/') && normalizedMethod !== 'gateway.sync_demand') {
|
|
1878
1942
|
throw new ValidationError('notify method must start with notification/ or event/');
|
|
1879
1943
|
}
|
|
1880
1944
|
if (params !== undefined && params !== null && !isJsonObject(params)) {
|
|
@@ -2071,7 +2135,7 @@ export class RPCTransport {
|
|
|
2071
2135
|
}
|
|
2072
2136
|
if (this._rpcQueue.length > 0) {
|
|
2073
2137
|
this._rpcQueue = this._rpcQueue.filter((entry) => entry.rpcId !== rpcId || (pending !== undefined && entry.pending !== pending));
|
|
2074
|
-
if (this.
|
|
2138
|
+
if (this.foregroundWaiting === 0 && !this._closed)
|
|
2075
2139
|
this._onForegroundDrained?.();
|
|
2076
2140
|
}
|
|
2077
2141
|
if (this._backgroundRpcQueue.length > 0) {
|
|
@@ -2150,6 +2214,7 @@ export class RPCTransport {
|
|
|
2150
2214
|
return false;
|
|
2151
2215
|
}
|
|
2152
2216
|
this._requestCheck?.(`rpc:${entry.method}`);
|
|
2217
|
+
this._checkSyncAdmission(entry.syncGuard);
|
|
2153
2218
|
entry.pending.sent = true;
|
|
2154
2219
|
return true;
|
|
2155
2220
|
}, this._isRiskControlMethod(entry.method) ? 3 : entry.priority).then(() => {
|
|
@@ -2178,7 +2243,7 @@ export class RPCTransport {
|
|
|
2178
2243
|
if (!this._closed && this._backgroundRpcQueue.length && remaining > 0) {
|
|
2179
2244
|
this._rateLimitTimer = setTimeout(() => { this._rateLimitTimer = null; this._drainRpcQueue(); }, Math.min(remaining, 2_147_483_647));
|
|
2180
2245
|
}
|
|
2181
|
-
if (foregroundDrained)
|
|
2246
|
+
if (foregroundDrained && !this.rpcBudget.foregroundWaiting)
|
|
2182
2247
|
this._onForegroundDrained?.();
|
|
2183
2248
|
}
|
|
2184
2249
|
}
|
|
@@ -2229,6 +2294,9 @@ export class RPCTransport {
|
|
|
2229
2294
|
this._stopWebSocketHeartbeat(ws);
|
|
2230
2295
|
const wasClosed = this._closed;
|
|
2231
2296
|
this._closed = true;
|
|
2297
|
+
for (const request of this._budgetWaiters)
|
|
2298
|
+
request.cancel?.();
|
|
2299
|
+
this._budgetWaiters.clear();
|
|
2232
2300
|
for (const wake of this._rateLimitWaiters)
|
|
2233
2301
|
wake();
|
|
2234
2302
|
if (this._rateLimitTimer !== null)
|
|
@@ -2272,7 +2340,8 @@ export class RPCTransport {
|
|
|
2272
2340
|
this._dispatcher.enqueueProtocol('connection.error', { error: err });
|
|
2273
2341
|
}
|
|
2274
2342
|
});
|
|
2275
|
-
this.
|
|
2343
|
+
if (!this._syncAuxiliary)
|
|
2344
|
+
this._startWebSocketHeartbeat(ws);
|
|
2276
2345
|
}
|
|
2277
2346
|
/** 使用 WebSocket 控制帧检测半开连接,不占用 JSON-RPC 并发额度。 */
|
|
2278
2347
|
_startWebSocketHeartbeat(ws) {
|
|
@@ -2365,6 +2434,17 @@ export class RPCTransport {
|
|
|
2365
2434
|
}
|
|
2366
2435
|
/** 路由消息:RPC 响应 / challenge / 事件 / 通知 */
|
|
2367
2436
|
_routeMessage(message) {
|
|
2437
|
+
const syncMethod = String(message.method ?? '');
|
|
2438
|
+
const syncMeta = isJsonObject(message._meta) ? message._meta : {};
|
|
2439
|
+
if (syncMeta.sync_policy !== undefined || syncMethod.startsWith('event/gateway.sync_')) {
|
|
2440
|
+
const policy = syncMeta.sync_policy;
|
|
2441
|
+
if (isJsonObject(policy) && this._syncAdmission?.parent_connection_id === policy.parent_connection_id
|
|
2442
|
+
&& Number.isSafeInteger(policy.version) && Number(policy.version) > Number(this._syncAdmission?.version))
|
|
2443
|
+
this._syncAdmission = { ...policy };
|
|
2444
|
+
this._syncControlObserver?.(syncMeta, syncMethod, message.params ?? {});
|
|
2445
|
+
}
|
|
2446
|
+
if (syncMethod === 'event/gateway.sync_policy_changed' || syncMethod === 'event/gateway.sync_channel_close')
|
|
2447
|
+
return;
|
|
2368
2448
|
// 入口 debug: 识别消息类型
|
|
2369
2449
|
const hasId = 'id' in message;
|
|
2370
2450
|
const methodStr = String(message.method ?? '');
|
|
@@ -2550,6 +2630,7 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
|
|
|
2550
2630
|
eventDispatcher: workerDispatcher,
|
|
2551
2631
|
timeout: Number(workerData.timeout ?? 35_000),
|
|
2552
2632
|
verifySsl: Boolean(workerData.verifySsl ?? true),
|
|
2633
|
+
syncAuxiliary: Boolean(workerData.syncAuxiliary),
|
|
2553
2634
|
// Worker 内只让 close handler 经 workerDispatcher 转发一次,主线程负责执行真实回调。
|
|
2554
2635
|
onDisconnect: () => { },
|
|
2555
2636
|
});
|
|
@@ -2562,6 +2643,7 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
|
|
|
2562
2643
|
actor._onRpcResponse = () => parentPort.postMessage({
|
|
2563
2644
|
type: 'rpc_response', generation: bridgeGeneration(),
|
|
2564
2645
|
});
|
|
2646
|
+
actor.setSyncControlObserver((meta, method, params) => parentPort.postMessage({ type: 'event', generation: actor._connectionGeneration, event: '_transport.sync_control', payload: { meta, method, params } }));
|
|
2565
2647
|
actor.setProtocolMetaObserver((meta) => workerDispatcher.enqueueProtocol('_transport.observer', {
|
|
2566
2648
|
kind: 'meta_observer', payload: meta,
|
|
2567
2649
|
}));
|
|
@@ -2596,6 +2678,9 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
|
|
|
2596
2678
|
}
|
|
2597
2679
|
let result;
|
|
2598
2680
|
switch (command.type) {
|
|
2681
|
+
case 'sync_admission':
|
|
2682
|
+
actor.setSyncAdmission(command.syncAdmission ?? null);
|
|
2683
|
+
return;
|
|
2599
2684
|
case 'risk_snapshot': {
|
|
2600
2685
|
const state = command.riskState;
|
|
2601
2686
|
const target = state.target;
|