@agentunion/fastaun-browser 0.2.13

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 (82) hide show
  1. package/README.md +604 -0
  2. package/dist/auth.d.ts +150 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +1388 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/certs/root.d.ts +2 -0
  7. package/dist/certs/root.d.ts.map +1 -0
  8. package/dist/certs/root.js +16 -0
  9. package/dist/certs/root.js.map +1 -0
  10. package/dist/client.d.ts +341 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +4061 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/config.d.ts +37 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +85 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/crypto.d.ts +41 -0
  19. package/dist/crypto.d.ts.map +1 -0
  20. package/dist/crypto.js +132 -0
  21. package/dist/crypto.js.map +1 -0
  22. package/dist/discovery.d.ts +20 -0
  23. package/dist/discovery.d.ts.map +1 -0
  24. package/dist/discovery.js +75 -0
  25. package/dist/discovery.js.map +1 -0
  26. package/dist/e2ee-group.d.ts +221 -0
  27. package/dist/e2ee-group.d.ts.map +1 -0
  28. package/dist/e2ee-group.js +1174 -0
  29. package/dist/e2ee-group.js.map +1 -0
  30. package/dist/e2ee.d.ts +187 -0
  31. package/dist/e2ee.d.ts.map +1 -0
  32. package/dist/e2ee.js +1067 -0
  33. package/dist/e2ee.js.map +1 -0
  34. package/dist/errors.d.ts +118 -0
  35. package/dist/errors.d.ts.map +1 -0
  36. package/dist/errors.js +250 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/events.d.ts +33 -0
  39. package/dist/events.d.ts.map +1 -0
  40. package/dist/events.js +68 -0
  41. package/dist/events.js.map +1 -0
  42. package/dist/index.d.ts +22 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +32 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/keystore/index.d.ts +88 -0
  47. package/dist/keystore/index.d.ts.map +1 -0
  48. package/dist/keystore/index.js +3 -0
  49. package/dist/keystore/index.js.map +1 -0
  50. package/dist/keystore/indexeddb.d.ts +94 -0
  51. package/dist/keystore/indexeddb.d.ts.map +1 -0
  52. package/dist/keystore/indexeddb.js +1434 -0
  53. package/dist/keystore/indexeddb.js.map +1 -0
  54. package/dist/namespaces/auth.d.ts +52 -0
  55. package/dist/namespaces/auth.d.ts.map +1 -0
  56. package/dist/namespaces/auth.js +237 -0
  57. package/dist/namespaces/auth.js.map +1 -0
  58. package/dist/namespaces/custody.d.ts +48 -0
  59. package/dist/namespaces/custody.d.ts.map +1 -0
  60. package/dist/namespaces/custody.js +230 -0
  61. package/dist/namespaces/custody.js.map +1 -0
  62. package/dist/secret-store/index.d.ts +20 -0
  63. package/dist/secret-store/index.d.ts.map +1 -0
  64. package/dist/secret-store/index.js +12 -0
  65. package/dist/secret-store/index.js.map +1 -0
  66. package/dist/secret-store/indexeddb-store.d.ts +22 -0
  67. package/dist/secret-store/indexeddb-store.d.ts.map +1 -0
  68. package/dist/secret-store/indexeddb-store.js +133 -0
  69. package/dist/secret-store/indexeddb-store.js.map +1 -0
  70. package/dist/seq-tracker.d.ts +30 -0
  71. package/dist/seq-tracker.d.ts.map +1 -0
  72. package/dist/seq-tracker.js +219 -0
  73. package/dist/seq-tracker.js.map +1 -0
  74. package/dist/transport.d.ts +45 -0
  75. package/dist/transport.d.ts.map +1 -0
  76. package/dist/transport.js +251 -0
  77. package/dist/transport.js.map +1 -0
  78. package/dist/types.d.ts +171 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +10 -0
  81. package/dist/types.js.map +1 -0
  82. package/package.json +37 -0
@@ -0,0 +1,219 @@
1
+ // ── 消息序列号跟踪与空洞检测 ──────────────────────────────
2
+ //
3
+ // SeqTracker 维护按命名空间(group_id 或 conversation_id)分组的消息序列连续性。
4
+ // 用法:群消息 key = "group:" + groupId,P2P 消息 key = "p2p:" + myAid
5
+ const BACKOFF_INTERVALS = [1, 3, 10, 30, 60]; // 秒
6
+ // S2: 删除"probeCount >= 5 强制 resolved"的硬限制;仅用作 backoff 索引上限。
7
+ // resolved 只应由"完整补齐"或服务端明确 tombstone 驱动。
8
+ const MAX_PROBE_COUNT = 5;
9
+ function gapKey(start, end) {
10
+ return `${start}:${end}`;
11
+ }
12
+ function nowMs() {
13
+ return typeof performance !== 'undefined' ? performance.now() : Date.now();
14
+ }
15
+ export class SeqTracker {
16
+ _trackers = new Map();
17
+ _get(ns) {
18
+ let t = this._trackers.get(ns);
19
+ if (!t) {
20
+ t = { contiguousSeq: 0, maxSeenSeq: 0, receivedSeqs: new Set(), pendingGaps: new Map() };
21
+ this._trackers.set(ns, t);
22
+ }
23
+ return t;
24
+ }
25
+ getContiguousSeq(ns) {
26
+ return this._get(ns).contiguousSeq;
27
+ }
28
+ getMaxSeenSeq(ns) {
29
+ return this._get(ns).maxSeenSeq;
30
+ }
31
+ /** S2: 从持久化(keystore 最近 ack seq)恢复 baseline,
32
+ * 以便首条 push 消息能构造 [baseline+1, seq-1] 的历史 gap。
33
+ * 必须在收到首条消息前调用。 */
34
+ setBaseline(ns, baselineSeq) {
35
+ if (baselineSeq <= 0)
36
+ return;
37
+ const t = this._get(ns);
38
+ if (t.contiguousSeq === 0 && t.maxSeenSeq === 0) {
39
+ t.contiguousSeq = baselineSeq;
40
+ t.maxSeenSeq = baselineSeq;
41
+ }
42
+ }
43
+ /** 记录收到的 seq,返回 true 表示需要 pull 补齐空洞 */
44
+ onMessageSeq(ns, seq) {
45
+ if (seq <= 0)
46
+ return false;
47
+ const t = this._get(ns);
48
+ if (seq <= t.contiguousSeq)
49
+ return false;
50
+ // S2: 首次收到消息时,必须构造 [1, seq-1] 的历史 gap 来触发补洞,
51
+ // 而不是把当前 seq 当成 baseline 丢弃历史。
52
+ if (t.contiguousSeq === 0 && t.maxSeenSeq === 0) {
53
+ if (seq === 1) {
54
+ t.contiguousSeq = seq;
55
+ t.maxSeenSeq = seq;
56
+ return false;
57
+ }
58
+ t.maxSeenSeq = seq;
59
+ t.receivedSeqs.add(seq);
60
+ const histKey = gapKey(1, seq - 1);
61
+ t.pendingGaps.set(histKey, {
62
+ gapStart: 1, gapEnd: seq - 1,
63
+ lastProbeAt: 0, probeCount: 0, resolved: false,
64
+ });
65
+ return true;
66
+ }
67
+ t.receivedSeqs.add(seq);
68
+ t.maxSeenSeq = Math.max(t.maxSeenSeq, seq);
69
+ if (seq === t.contiguousSeq + 1) {
70
+ t.contiguousSeq = seq;
71
+ t.receivedSeqs.delete(seq);
72
+ this._tryAdvance(t);
73
+ return false;
74
+ }
75
+ // 空洞
76
+ const gs = t.contiguousSeq + 1;
77
+ const ge = seq - 1;
78
+ const key = gapKey(gs, ge);
79
+ const existing = t.pendingGaps.get(key);
80
+ if (existing) {
81
+ if (existing.resolved) {
82
+ t.contiguousSeq = Math.max(t.contiguousSeq, existing.gapEnd);
83
+ t.pendingGaps.delete(key);
84
+ this._tryAdvance(t);
85
+ return false;
86
+ }
87
+ if (!this._shouldProbe(existing))
88
+ return false;
89
+ }
90
+ else {
91
+ t.pendingGaps.set(key, {
92
+ gapStart: gs, gapEnd: ge,
93
+ lastProbeAt: 0, probeCount: 0, resolved: false,
94
+ });
95
+ }
96
+ return true;
97
+ }
98
+ /** pull 返回后更新 tracker 状态 */
99
+ onPullResult(ns, messages) {
100
+ const t = this._get(ns);
101
+ const pulledSeqs = new Set();
102
+ for (const m of messages) {
103
+ const s = m.seq;
104
+ if (typeof s === 'number' && s > 0)
105
+ pulledSeqs.add(s);
106
+ }
107
+ const now = nowMs();
108
+ for (const [key, probe] of t.pendingGaps) {
109
+ if (probe.resolved)
110
+ continue;
111
+ probe.lastProbeAt = now;
112
+ probe.probeCount += 1;
113
+ let allCovered = true;
114
+ let anyHit = false;
115
+ for (let s = probe.gapStart; s <= probe.gapEnd; s++) {
116
+ if (pulledSeqs.has(s)) {
117
+ anyHit = true;
118
+ }
119
+ else {
120
+ allCovered = false;
121
+ }
122
+ }
123
+ if (allCovered) {
124
+ probe.resolved = true;
125
+ }
126
+ // S2: 不再因 probeCount >= 3 自动 resolved;仅由完整补齐 / 服务端 tombstone 驱动。
127
+ }
128
+ for (const s of pulledSeqs) {
129
+ t.receivedSeqs.add(s);
130
+ }
131
+ if (pulledSeqs.size) {
132
+ t.maxSeenSeq = Math.max(t.maxSeenSeq, Math.max(...pulledSeqs));
133
+ }
134
+ this._tryAdvance(t);
135
+ }
136
+ _tryAdvance(t) {
137
+ // 先清理已解决的空洞
138
+ let changed = true;
139
+ while (changed) {
140
+ changed = false;
141
+ for (const [key, probe] of t.pendingGaps) {
142
+ if (probe.resolved && probe.gapStart <= t.contiguousSeq + 1) {
143
+ t.contiguousSeq = Math.max(t.contiguousSeq, probe.gapEnd);
144
+ t.pendingGaps.delete(key);
145
+ changed = true;
146
+ }
147
+ }
148
+ }
149
+ // 从 contiguous+1 逐个推进(检查 receivedSeqs)
150
+ while (t.receivedSeqs.has(t.contiguousSeq + 1)) {
151
+ t.contiguousSeq += 1;
152
+ t.receivedSeqs.delete(t.contiguousSeq);
153
+ }
154
+ }
155
+ _shouldProbe(probe) {
156
+ // S2: 不再以 probeCount >= MAX_PROBE_COUNT 为由将 probe 置为 resolved。
157
+ // 超出 backoff 表长度后按最长间隔持续重试。
158
+ const now = nowMs();
159
+ const idx = Math.min(probe.probeCount, BACKOFF_INTERVALS.length - 1);
160
+ const interval = BACKOFF_INTERVALS[idx] * 1000; // 秒转毫秒
161
+ return now - probe.lastProbeAt >= interval;
162
+ }
163
+ /** S2: 服务端明确告知某区间无消息(tombstone)→ 将 gap 标记为 resolved */
164
+ markGapResolvedByTombstone(ns, gapStart, gapEnd) {
165
+ const t = this._get(ns);
166
+ for (const [, probe] of t.pendingGaps) {
167
+ if (probe.gapStart >= gapStart && probe.gapEnd <= gapEnd) {
168
+ probe.resolved = true;
169
+ }
170
+ }
171
+ this._tryAdvance(t);
172
+ }
173
+ /** 删除指定命名空间的所有跟踪状态(群组解散时使用) */
174
+ removeNamespace(ns) {
175
+ this._trackers.delete(ns);
176
+ }
177
+ /** 强制跳过不连续区间,将 contiguousSeq 拨到指定位置。
178
+ * 当服务端返回 server_ack_seq 且本地 contiguousSeq 落后时调用,
179
+ * 跳过 [contiguousSeq, server_ack_seq) 这段不连续区间。 */
180
+ forceContiguousSeq(ns, seq) {
181
+ const t = this._get(ns);
182
+ if (seq > t.contiguousSeq) {
183
+ // 清除被跳过区间内的 pendingGaps
184
+ for (const [key, probe] of t.pendingGaps) {
185
+ if (probe.gapEnd <= seq) {
186
+ t.pendingGaps.delete(key);
187
+ }
188
+ }
189
+ // 清除被跳过区间内的 receivedSeqs
190
+ for (const s of t.receivedSeqs) {
191
+ if (s <= seq)
192
+ t.receivedSeqs.delete(s);
193
+ }
194
+ t.contiguousSeq = seq;
195
+ t.maxSeenSeq = Math.max(t.maxSeenSeq, seq);
196
+ this._tryAdvance(t);
197
+ }
198
+ }
199
+ /** 导出各命名空间的 contiguousSeq,用于持久化 */
200
+ exportState() {
201
+ const result = {};
202
+ for (const [ns, t] of this._trackers) {
203
+ if (t.contiguousSeq > 0)
204
+ result[ns] = t.contiguousSeq;
205
+ }
206
+ return result;
207
+ }
208
+ /** 从持久化数据恢复各命名空间的 contiguousSeq */
209
+ restoreState(state) {
210
+ for (const [ns, seq] of Object.entries(state)) {
211
+ if (typeof seq === 'number' && seq > 0) {
212
+ const t = this._get(ns);
213
+ t.contiguousSeq = Math.max(t.contiguousSeq, seq);
214
+ t.maxSeenSeq = Math.max(t.maxSeenSeq, seq);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ //# sourceMappingURL=seq-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seq-tracker.js","sourceRoot":"","sources":["../src/seq-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { EventDispatcher } from './events.js';
2
+ import { type RpcMessage, type RpcParams, type RpcResult } from './types.js';
3
+ /**
4
+ * JSON-RPC 2.0 传输层 — 基于浏览器原生 WebSocket。
5
+ *
6
+ * 职责:
7
+ * - 连接管理(connect / close)
8
+ * - RPC 调用(call — 请求/响应匹配)
9
+ * - 事件路由(服务端推送 → EventDispatcher)
10
+ */
11
+ export declare class RPCTransport {
12
+ private _dispatcher;
13
+ private _timeout;
14
+ private _onDisconnect;
15
+ private _ws;
16
+ private _closed;
17
+ private _challenge;
18
+ private _pending;
19
+ constructor(opts: {
20
+ eventDispatcher: EventDispatcher;
21
+ timeout?: number;
22
+ onDisconnect?: ((error: Error | null, closeCode?: number) => Promise<void>) | null;
23
+ });
24
+ /** 设置默认超时(秒) */
25
+ setTimeout(timeout: number): void;
26
+ /** 获取连接时收到的 challenge */
27
+ get challenge(): RpcMessage | null;
28
+ /**
29
+ * 连接到 WebSocket URL。
30
+ * 等待首条消息,若为 challenge 则返回,否则进入消息路由。
31
+ */
32
+ connect(url: string): Promise<RpcMessage | null>;
33
+ /** 关闭连接 */
34
+ close(): Promise<void>;
35
+ /**
36
+ * 发起 JSON-RPC 2.0 调用。
37
+ * 返回 result 字段的值;若有 error 字段则抛出映射后的错误。
38
+ */
39
+ call(method: string, params?: RpcParams | null, timeout?: number): Promise<RpcResult>;
40
+ private _handleMessage;
41
+ private _handleClose;
42
+ private _routeMessage;
43
+ private _decodeMessage;
44
+ }
45
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,EAAiD,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAe5H;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAsE;IAC3F,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAGD;gBAEH,IAAI,EAAE;QAChB,eAAe,EAAE,eAAe,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;KACpF;IAMD,gBAAgB;IAChB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,yBAAyB;IACzB,IAAI,SAAS,IAAI,UAAU,GAAG,IAAI,CAEjC;IAED;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAuDtD,WAAW;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5B;;;OAGG;IACG,IAAI,CACR,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,CAAC;IAsDrB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,cAAc;CAiBvB"}
@@ -0,0 +1,251 @@
1
+ // ── RPC Transport(浏览器原生 WebSocket)──────────────────
2
+ import { ConnectionError, SerializationError, TimeoutError, mapRemoteError, } from './errors.js';
3
+ import { isJsonObject } from './types.js';
4
+ /** RPC 请求递增计数器,避免 Date.now() 高并发碰撞 */
5
+ let _rpcIdCounter = 0;
6
+ /** 协议事件名映射 */
7
+ const EVENT_NAME_MAP = {
8
+ 'message.received': 'message.received',
9
+ 'message.recalled': 'message.recalled',
10
+ 'message.ack': 'message.ack',
11
+ 'group.changed': 'group.changed',
12
+ 'group.message_created': 'group.message_created',
13
+ 'storage.object_changed': 'storage.object_changed',
14
+ };
15
+ /**
16
+ * JSON-RPC 2.0 传输层 — 基于浏览器原生 WebSocket。
17
+ *
18
+ * 职责:
19
+ * - 连接管理(connect / close)
20
+ * - RPC 调用(call — 请求/响应匹配)
21
+ * - 事件路由(服务端推送 → EventDispatcher)
22
+ */
23
+ export class RPCTransport {
24
+ _dispatcher;
25
+ _timeout;
26
+ _onDisconnect;
27
+ _ws = null;
28
+ _closed = true;
29
+ _challenge = null;
30
+ _pending = new Map();
31
+ constructor(opts) {
32
+ this._dispatcher = opts.eventDispatcher;
33
+ this._timeout = opts.timeout ?? 10;
34
+ this._onDisconnect = opts.onDisconnect ?? null;
35
+ }
36
+ /** 设置默认超时(秒) */
37
+ setTimeout(timeout) {
38
+ this._timeout = timeout;
39
+ }
40
+ /** 获取连接时收到的 challenge */
41
+ get challenge() {
42
+ return this._challenge;
43
+ }
44
+ /**
45
+ * 连接到 WebSocket URL。
46
+ * 等待首条消息,若为 challenge 则返回,否则进入消息路由。
47
+ */
48
+ async connect(url) {
49
+ return new Promise((resolve, reject) => {
50
+ const ws = new WebSocket(url);
51
+ this._ws = ws;
52
+ this._closed = false;
53
+ let initialResolved = false;
54
+ ws.onopen = () => {
55
+ // 连接已建立,等待首条消息
56
+ };
57
+ ws.onerror = (event) => {
58
+ if (!initialResolved) {
59
+ initialResolved = true;
60
+ reject(new ConnectionError(`websocket connection failed to ${url}`));
61
+ }
62
+ };
63
+ ws.onmessage = (event) => {
64
+ if (!initialResolved) {
65
+ // 首条消息:可能是 challenge
66
+ initialResolved = true;
67
+ try {
68
+ const message = this._decodeMessage(event.data);
69
+ if (message.method === 'challenge') {
70
+ this._challenge = message;
71
+ // 切换到正常消息路由
72
+ ws.onmessage = (evt) => this._handleMessage(evt.data);
73
+ ws.onclose = (evt) => this._handleClose(evt);
74
+ ws.onerror = null;
75
+ resolve(message);
76
+ }
77
+ else {
78
+ // 非 challenge 消息,路由处理后返回 null
79
+ ws.onmessage = (evt) => this._handleMessage(evt.data);
80
+ ws.onclose = (evt) => this._handleClose(evt);
81
+ ws.onerror = null;
82
+ this._routeMessage(message);
83
+ resolve(null);
84
+ }
85
+ }
86
+ catch (err) {
87
+ reject(err instanceof Error ? err : new ConnectionError(String(err)));
88
+ }
89
+ return;
90
+ }
91
+ };
92
+ ws.onclose = (event) => {
93
+ if (!initialResolved) {
94
+ initialResolved = true;
95
+ reject(new ConnectionError(`websocket closed before initial message: code=${event.code}`));
96
+ }
97
+ };
98
+ });
99
+ }
100
+ /** 关闭连接 */
101
+ async close() {
102
+ this._closed = true;
103
+ if (this._ws) {
104
+ try {
105
+ this._ws.onclose = null;
106
+ this._ws.onerror = null;
107
+ this._ws.onmessage = null;
108
+ this._ws.close();
109
+ }
110
+ catch (exc) {
111
+ console.warn('[aun_core.transport] WebSocket 关闭异常:', String(exc));
112
+ }
113
+ this._ws = null;
114
+ }
115
+ // 拒绝所有待处理的 RPC 调用
116
+ for (const [, pending] of this._pending) {
117
+ pending.reject(new ConnectionError('transport closed'));
118
+ }
119
+ this._pending.clear();
120
+ }
121
+ /**
122
+ * 发起 JSON-RPC 2.0 调用。
123
+ * 返回 result 字段的值;若有 error 字段则抛出映射后的错误。
124
+ */
125
+ async call(method, params, timeout) {
126
+ if (this._closed || !this._ws) {
127
+ throw new ConnectionError('transport not connected');
128
+ }
129
+ // 生成唯一 RPC ID(递增计数器,避免高并发碰撞)
130
+ const rpcId = `rpc-${String(++_rpcIdCounter).padStart(6, '0')}`;
131
+ const effectiveTimeout = (timeout ?? this._timeout) * 1000;
132
+ const promise = new Promise((resolve, reject) => {
133
+ this._pending.set(rpcId, { resolve, reject });
134
+ });
135
+ // 发送请求
136
+ try {
137
+ this._ws.send(JSON.stringify({
138
+ jsonrpc: '2.0',
139
+ id: rpcId,
140
+ method,
141
+ params: params ?? {},
142
+ }));
143
+ }
144
+ catch (exc) {
145
+ this._pending.delete(rpcId);
146
+ throw new ConnectionError(`failed to send rpc ${method}: ${exc}`);
147
+ }
148
+ // 超时控制(H23 修复:成功路径必须 clearTimeout,避免定时器泄漏 + 慢响应被静默丢弃)
149
+ let timeoutHandle = null;
150
+ const timeoutPromise = new Promise((_, reject) => {
151
+ timeoutHandle = globalThis.setTimeout(() => {
152
+ this._pending.delete(rpcId);
153
+ reject(new TimeoutError(`rpc timeout: ${method}`, { retryable: true }));
154
+ }, effectiveTimeout);
155
+ });
156
+ try {
157
+ const response = await Promise.race([promise, timeoutPromise]);
158
+ if (response.error !== undefined) {
159
+ throw mapRemoteError(response.error);
160
+ }
161
+ if (response.result === undefined) {
162
+ throw new SerializationError(`rpc response missing result and error: ${method}`);
163
+ }
164
+ return response.result;
165
+ }
166
+ finally {
167
+ if (timeoutHandle !== null) {
168
+ globalThis.clearTimeout(timeoutHandle);
169
+ }
170
+ }
171
+ }
172
+ // ── 内部消息处理 ──────────────────────────────────
173
+ _handleMessage(data) {
174
+ try {
175
+ const message = this._decodeMessage(data);
176
+ this._routeMessage(message);
177
+ }
178
+ catch (exc) {
179
+ console.warn('消息解码异常:', exc);
180
+ }
181
+ }
182
+ _handleClose(event) {
183
+ const wasClosed = this._closed;
184
+ this._closed = true;
185
+ // 拒绝所有待处理调用
186
+ for (const [, pending] of this._pending) {
187
+ pending.reject(new ConnectionError(`websocket closed: code=${event.code}`));
188
+ }
189
+ this._pending.clear();
190
+ // 非主动关闭时触发断线回调
191
+ if (!wasClosed) {
192
+ const error = new ConnectionError(`websocket closed: code=${event.code} reason=${event.reason}`);
193
+ this._dispatcher.publish('connection.error', { error });
194
+ if (this._onDisconnect) {
195
+ this._onDisconnect(error, event.code).catch(exc => console.warn('[aun_core.transport] disconnect 回调异常:', exc));
196
+ }
197
+ }
198
+ }
199
+ _routeMessage(message) {
200
+ // RPC 响应(有 id 字段)
201
+ if ('id' in message) {
202
+ const rpcId = String(message.id);
203
+ const pending = this._pending.get(rpcId);
204
+ if (pending) {
205
+ this._pending.delete(rpcId);
206
+ pending.resolve(message);
207
+ }
208
+ else {
209
+ // H23: 未知 id 多数是超时后到达的慢响应;打 warn 便于排查,避免被完全吞掉
210
+ console.warn('[aun_core.transport] 收到未知 rpc 响应(可能超时后到达): id=' + rpcId);
211
+ }
212
+ return;
213
+ }
214
+ const method = String(message.method ?? '');
215
+ // challenge 消息
216
+ if (method === 'challenge') {
217
+ this._challenge = message;
218
+ this._dispatcher.publish('connection.challenge', message.params ?? {});
219
+ return;
220
+ }
221
+ // 事件推送
222
+ if (method.startsWith('event/')) {
223
+ const protocolEvent = method.slice(6);
224
+ const sdkEvent = EVENT_NAME_MAP[protocolEvent] ?? protocolEvent;
225
+ // 发布为 _raw.{event},由 AUNClient 处理后再发布用户可见的事件
226
+ this._dispatcher.publish(`_raw.${sdkEvent}`, message.params ?? {});
227
+ return;
228
+ }
229
+ // 其他通知
230
+ this._dispatcher.publish('notification', message);
231
+ }
232
+ _decodeMessage(raw) {
233
+ if (isJsonObject(raw)) {
234
+ return raw;
235
+ }
236
+ if (typeof raw !== 'string') {
237
+ throw new SerializationError(`unsupported websocket payload type: ${typeof raw}`);
238
+ }
239
+ try {
240
+ const parsed = JSON.parse(raw);
241
+ if (!isJsonObject(parsed)) {
242
+ throw new SerializationError('invalid json payload');
243
+ }
244
+ return parsed;
245
+ }
246
+ catch {
247
+ throw new SerializationError('invalid json payload');
248
+ }
249
+ }
250
+ }
251
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}