acp-ts 1.2.2 → 1.2.4
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/dist/agentcp.js +40 -33
- package/dist/agentws.d.ts +8 -2
- package/dist/agentws.js +22 -4
- package/dist/api.js +8 -8
- package/dist/cert.js +3 -2
- package/dist/cli.js +16 -15
- package/dist/datamanager.js +27 -11
- package/dist/filesync.js +11 -10
- package/dist/group/client.js +44 -36
- package/dist/group/cursor_store.d.ts +4 -9
- package/dist/group/cursor_store.js +12 -40
- package/dist/group/events.d.ts +2 -1
- package/dist/group/events.js +7 -3
- package/dist/group/index.d.ts +1 -1
- package/dist/group/index.js +2 -1
- package/dist/group/message_store.d.ts +5 -6
- package/dist/group/message_store.js +64 -72
- package/dist/group/operations.d.ts +24 -6
- package/dist/group/operations.js +55 -6
- package/dist/group/types.d.ts +30 -1
- package/dist/group/types.js +11 -1
- package/dist/heartbeat.js +24 -24
- package/dist/messagestore.js +9 -8
- package/dist/server.js +2288 -1661
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +19 -2
- package/dist/websocket.d.ts +12 -1
- package/dist/websocket.js +61 -28
- package/package.json +1 -1
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export declare const logger: {
|
|
2
|
+
log: (...args: any[]) => void;
|
|
3
|
+
warn: (...args: any[]) => void;
|
|
4
|
+
error: (...args: any[]) => void;
|
|
5
|
+
info: (...args: any[]) => void;
|
|
6
|
+
};
|
|
1
7
|
export declare function getDecryptKey(aid: string, password: string): Promise<string | null>;
|
|
2
8
|
export declare function savePrivateKey(aid: string, privateKey: string, password: string): Promise<void>;
|
|
3
9
|
export declare function createAid(aid: string, apiUrl: string, seedPassword: string): Promise<boolean>;
|
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logger = void 0;
|
|
3
4
|
exports.getDecryptKey = getDecryptKey;
|
|
4
5
|
exports.savePrivateKey = savePrivateKey;
|
|
5
6
|
exports.createAid = createAid;
|
|
@@ -7,6 +8,22 @@ const datamanager_1 = require("./datamanager");
|
|
|
7
8
|
const cert_1 = require("./cert");
|
|
8
9
|
const jsrsasign_1 = require("jsrsasign");
|
|
9
10
|
const api_1 = require("./api");
|
|
11
|
+
function getTimestamp() {
|
|
12
|
+
const now = new Date();
|
|
13
|
+
const y = now.getFullYear();
|
|
14
|
+
const m = String(now.getMonth() + 1).padStart(2, '0');
|
|
15
|
+
const d = String(now.getDate()).padStart(2, '0');
|
|
16
|
+
const h = String(now.getHours()).padStart(2, '0');
|
|
17
|
+
const min = String(now.getMinutes()).padStart(2, '0');
|
|
18
|
+
const s = String(now.getSeconds()).padStart(2, '0');
|
|
19
|
+
return `${y}/${m}/${d} ${h}:${min}:${s}`;
|
|
20
|
+
}
|
|
21
|
+
exports.logger = {
|
|
22
|
+
log: (...args) => console.log(`[${getTimestamp()}]`, ...args),
|
|
23
|
+
warn: (...args) => console.warn(`[${getTimestamp()}]`, ...args),
|
|
24
|
+
error: (...args) => console.error(`[${getTimestamp()}]`, ...args),
|
|
25
|
+
info: (...args) => console.info(`[${getTimestamp()}]`, ...args),
|
|
26
|
+
};
|
|
10
27
|
// 解密私钥数据
|
|
11
28
|
function decryptPrivateKey(encryptedData, password) {
|
|
12
29
|
try {
|
|
@@ -16,7 +33,7 @@ function decryptPrivateKey(encryptedData, password) {
|
|
|
16
33
|
return privateKeyPEM;
|
|
17
34
|
}
|
|
18
35
|
catch (err) {
|
|
19
|
-
|
|
36
|
+
exports.logger.error('私钥解密失败:', err);
|
|
20
37
|
return null;
|
|
21
38
|
}
|
|
22
39
|
}
|
|
@@ -29,7 +46,7 @@ function encryptPrivateKey(privateKeyPEM, password) {
|
|
|
29
46
|
return encryptedPEM;
|
|
30
47
|
}
|
|
31
48
|
catch (err) {
|
|
32
|
-
|
|
49
|
+
exports.logger.error('私钥加密失败:', err);
|
|
33
50
|
return null;
|
|
34
51
|
}
|
|
35
52
|
}
|
package/dist/websocket.d.ts
CHANGED
|
@@ -26,17 +26,28 @@ declare class WSClient {
|
|
|
26
26
|
private _isReconnecting;
|
|
27
27
|
private options;
|
|
28
28
|
private rawMessageCallback;
|
|
29
|
+
private reconnectNeededCallback;
|
|
30
|
+
private _isReconnectNeededRunning;
|
|
29
31
|
constructor(options?: WSClientOptions);
|
|
30
32
|
/**
|
|
31
33
|
* 检查 WebSocket 是否已连接
|
|
32
34
|
*/
|
|
33
35
|
private isConnected;
|
|
34
36
|
connectToServer(wsServer: string, aid: string, sinature: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* 注册"快速重连全部失败"回调,通知上层需要重新鉴权
|
|
39
|
+
*/
|
|
40
|
+
onReconnectNeeded(cb: () => void): void;
|
|
41
|
+
/**
|
|
42
|
+
* 更新 WebSocket URL(上层重新获取 signature 后调用)
|
|
43
|
+
*/
|
|
44
|
+
updateWsUrl(url: string): void;
|
|
35
45
|
/**
|
|
36
46
|
* 重连 WebSocket(供外部调用,如心跳重连后触发)
|
|
37
47
|
* 会关闭旧连接,重置状态,重新建立连接
|
|
48
|
+
* @param newUrl 可选,传入新的 wsUrl(重新鉴权后使用)
|
|
38
49
|
*/
|
|
39
|
-
reconnect(): Promise<void>;
|
|
50
|
+
reconnect(newUrl?: string): Promise<void>;
|
|
40
51
|
createSession(cb: (status: ACPMessageSessionResponse) => void): void;
|
|
41
52
|
invite(receiver: string, sessionId: string, identifyingCode: string, cb?: (((status: InviteStatus) => void) | null)): void;
|
|
42
53
|
onStatusChange(cb: (status: ConnectionStatus) => void): void;
|
package/dist/websocket.js
CHANGED
|
@@ -40,6 +40,7 @@ exports.WSClient = exports.isNodeEnvironment = void 0;
|
|
|
40
40
|
const uuid_1 = require("uuid");
|
|
41
41
|
const mitt_1 = __importDefault(require("mitt"));
|
|
42
42
|
const https = __importStar(require("https"));
|
|
43
|
+
const utils_1 = require("./utils");
|
|
43
44
|
// 统一的环境检测函数
|
|
44
45
|
exports.isNodeEnvironment = typeof process !== 'undefined' &&
|
|
45
46
|
process.versions != null &&
|
|
@@ -67,8 +68,10 @@ class WSClient {
|
|
|
67
68
|
this._isReconnecting = false;
|
|
68
69
|
this.options = {};
|
|
69
70
|
this.rawMessageCallback = null;
|
|
71
|
+
this.reconnectNeededCallback = null;
|
|
72
|
+
this._isReconnectNeededRunning = false;
|
|
70
73
|
this.options = options || {};
|
|
71
|
-
this.maxRetries = (_a = this.options.maxRetries) !== null && _a !== void 0 ? _a :
|
|
74
|
+
this.maxRetries = (_a = this.options.maxRetries) !== null && _a !== void 0 ? _a : 2;
|
|
72
75
|
}
|
|
73
76
|
/**
|
|
74
77
|
* 检查 WebSocket 是否已连接
|
|
@@ -87,21 +90,37 @@ class WSClient {
|
|
|
87
90
|
await this.connect();
|
|
88
91
|
}
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* 注册"快速重连全部失败"回调,通知上层需要重新鉴权
|
|
95
|
+
*/
|
|
96
|
+
onReconnectNeeded(cb) {
|
|
97
|
+
this.reconnectNeededCallback = cb;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 更新 WebSocket URL(上层重新获取 signature 后调用)
|
|
101
|
+
*/
|
|
102
|
+
updateWsUrl(url) {
|
|
103
|
+
this.wsUrl = url;
|
|
104
|
+
}
|
|
90
105
|
/**
|
|
91
106
|
* 重连 WebSocket(供外部调用,如心跳重连后触发)
|
|
92
107
|
* 会关闭旧连接,重置状态,重新建立连接
|
|
108
|
+
* @param newUrl 可选,传入新的 wsUrl(重新鉴权后使用)
|
|
93
109
|
*/
|
|
94
|
-
async reconnect() {
|
|
110
|
+
async reconnect(newUrl) {
|
|
95
111
|
if (this._isReconnecting) {
|
|
96
|
-
|
|
112
|
+
utils_1.logger.log('[WS] 已在重连中,跳过');
|
|
97
113
|
return;
|
|
98
114
|
}
|
|
99
|
-
if (!this.wsUrl) {
|
|
100
|
-
|
|
115
|
+
if (!this.wsUrl && !newUrl) {
|
|
116
|
+
utils_1.logger.error('[WS] 重连失败: wsUrl 为空,尚未进行过初始连接');
|
|
101
117
|
return;
|
|
102
118
|
}
|
|
103
119
|
this._isReconnecting = true;
|
|
104
|
-
|
|
120
|
+
if (newUrl) {
|
|
121
|
+
this.wsUrl = newUrl;
|
|
122
|
+
}
|
|
123
|
+
utils_1.logger.log('[WS] 开始 WebSocket 重连...');
|
|
105
124
|
try {
|
|
106
125
|
// 关闭旧连接(标记为正常关闭,避免触发 onclose 重试)
|
|
107
126
|
if (this.socket) {
|
|
@@ -116,10 +135,10 @@ class WSClient {
|
|
|
116
135
|
this.updateStatus('reconnecting');
|
|
117
136
|
// 重新建立连接
|
|
118
137
|
await this.connect();
|
|
119
|
-
|
|
138
|
+
utils_1.logger.log('[WS] WebSocket 重连成功');
|
|
120
139
|
}
|
|
121
140
|
catch (error) {
|
|
122
|
-
|
|
141
|
+
utils_1.logger.error('[WS] WebSocket 重连失败:', error);
|
|
123
142
|
this.updateStatus('error');
|
|
124
143
|
}
|
|
125
144
|
finally {
|
|
@@ -174,7 +193,7 @@ class WSClient {
|
|
|
174
193
|
sendRaw(message, to, sessionId) {
|
|
175
194
|
var _a;
|
|
176
195
|
if (!this.isConnected()) {
|
|
177
|
-
|
|
196
|
+
utils_1.logger.error('[WS] sendRaw: WebSocket连接未建立或已断开');
|
|
178
197
|
return false;
|
|
179
198
|
}
|
|
180
199
|
try {
|
|
@@ -195,14 +214,14 @@ class WSClient {
|
|
|
195
214
|
return true;
|
|
196
215
|
}
|
|
197
216
|
catch (error) {
|
|
198
|
-
|
|
217
|
+
utils_1.logger.error('发送原始消息失败:', error);
|
|
199
218
|
return false;
|
|
200
219
|
}
|
|
201
220
|
}
|
|
202
221
|
send(message, to, sessionId, identifyingCode) {
|
|
203
222
|
var _a;
|
|
204
223
|
if (!message || message.trim().length === 0) {
|
|
205
|
-
|
|
224
|
+
utils_1.logger.error('发送的消息不能为空');
|
|
206
225
|
return;
|
|
207
226
|
}
|
|
208
227
|
if (!this.isConnected()) {
|
|
@@ -250,7 +269,7 @@ class WSClient {
|
|
|
250
269
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify(msg));
|
|
251
270
|
}
|
|
252
271
|
catch (error) {
|
|
253
|
-
|
|
272
|
+
utils_1.logger.error('发送消息失败:', error);
|
|
254
273
|
this.emitter.emit('message', {
|
|
255
274
|
type: 'error',
|
|
256
275
|
content: JSON.stringify([{ content: '发送消息失败' }])
|
|
@@ -289,7 +308,7 @@ class WSClient {
|
|
|
289
308
|
this.handleMessage(data);
|
|
290
309
|
}
|
|
291
310
|
catch (error) {
|
|
292
|
-
|
|
311
|
+
utils_1.logger.error('解析消息失败:', error);
|
|
293
312
|
}
|
|
294
313
|
};
|
|
295
314
|
this.socket.onclose = (event) => {
|
|
@@ -297,21 +316,35 @@ class WSClient {
|
|
|
297
316
|
this.updateStatus('disconnected');
|
|
298
317
|
if (!this.isNormalClose && !event.wasClean && retryCount < this.maxRetries) {
|
|
299
318
|
retryCount++;
|
|
300
|
-
const retryDelay =
|
|
301
|
-
|
|
319
|
+
const retryDelay = retryCount * 1000;
|
|
320
|
+
utils_1.logger.warn(`WebSocket连接断开,${retryDelay}ms后快速重试 (${retryCount}/${this.maxRetries})...`);
|
|
302
321
|
setTimeout(attemptConnect, retryDelay);
|
|
303
322
|
}
|
|
304
323
|
else if (!this.isNormalClose && retryCount >= this.maxRetries) {
|
|
305
324
|
if (!resolved) {
|
|
325
|
+
// 首次连接就失败,直接 reject
|
|
306
326
|
resolved = true;
|
|
307
327
|
reject(new Error(`WebSocket连接失败,已达到最大重试次数 (${this.maxRetries})`));
|
|
308
328
|
}
|
|
329
|
+
else if (this.reconnectNeededCallback
|
|
330
|
+
&& !this._isReconnectNeededRunning
|
|
331
|
+
&& !this._isReconnecting // 避免 reconnect() 内部的 connect() 失败再次触发,形成循环
|
|
332
|
+
) {
|
|
333
|
+
// 曾经连接成功过、后来断开且快速重试耗尽 → 通知上层重新鉴权
|
|
334
|
+
utils_1.logger.warn('[WS] 快速重试耗尽,触发 onReconnectNeeded 回调');
|
|
335
|
+
this._isReconnectNeededRunning = true;
|
|
336
|
+
// 回调可能是异步的,用 Promise 确保标志位在异步完成后才重置
|
|
337
|
+
Promise.resolve()
|
|
338
|
+
.then(() => this.reconnectNeededCallback())
|
|
339
|
+
.catch((err) => utils_1.logger.error('[WS] onReconnectNeeded 回调执行失败:', err))
|
|
340
|
+
.finally(() => { this._isReconnectNeededRunning = false; });
|
|
341
|
+
}
|
|
309
342
|
}
|
|
310
343
|
this.isNormalClose = false;
|
|
311
344
|
};
|
|
312
345
|
this.socket.onerror = (error) => {
|
|
313
346
|
var _a, _b;
|
|
314
|
-
|
|
347
|
+
utils_1.logger.error('WebSocket 错误:', {
|
|
315
348
|
error,
|
|
316
349
|
readyState: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.readyState,
|
|
317
350
|
url: this.wsUrl,
|
|
@@ -324,12 +357,12 @@ class WSClient {
|
|
|
324
357
|
};
|
|
325
358
|
}
|
|
326
359
|
catch (err) {
|
|
327
|
-
|
|
360
|
+
utils_1.logger.error('创建 WebSocket 实例失败:', err);
|
|
328
361
|
this.updateStatus('error');
|
|
329
362
|
if (retryCount < this.maxRetries) {
|
|
330
363
|
retryCount++;
|
|
331
364
|
const retryDelay = retryCount * 1000;
|
|
332
|
-
|
|
365
|
+
utils_1.logger.warn(`创建失败,${retryCount}秒后重试...`);
|
|
333
366
|
setTimeout(attemptConnect, retryDelay);
|
|
334
367
|
}
|
|
335
368
|
else {
|
|
@@ -358,7 +391,7 @@ class WSClient {
|
|
|
358
391
|
}
|
|
359
392
|
createSessionId() {
|
|
360
393
|
if (!this.isConnected()) {
|
|
361
|
-
|
|
394
|
+
utils_1.logger.error('WebSocket连接未建立,无法创建会话');
|
|
362
395
|
return;
|
|
363
396
|
}
|
|
364
397
|
try {
|
|
@@ -375,17 +408,17 @@ class WSClient {
|
|
|
375
408
|
this.socket.send(JSON.stringify(msg));
|
|
376
409
|
}
|
|
377
410
|
catch (error) {
|
|
378
|
-
|
|
411
|
+
utils_1.logger.error('发送创建会话请求失败:', error);
|
|
379
412
|
}
|
|
380
413
|
}
|
|
381
414
|
sendInviteMessage(receiver, sessionId, identifyingCode) {
|
|
382
415
|
var _a;
|
|
383
416
|
if (!receiver || !sessionId || !identifyingCode) {
|
|
384
|
-
|
|
417
|
+
utils_1.logger.error('邀请参数不完整');
|
|
385
418
|
return;
|
|
386
419
|
}
|
|
387
420
|
if (!this.isConnected()) {
|
|
388
|
-
|
|
421
|
+
utils_1.logger.error('WebSocket连接未建立,无法发送邀请');
|
|
389
422
|
return;
|
|
390
423
|
}
|
|
391
424
|
try {
|
|
@@ -402,7 +435,7 @@ class WSClient {
|
|
|
402
435
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify(msg));
|
|
403
436
|
}
|
|
404
437
|
catch (error) {
|
|
405
|
-
|
|
438
|
+
utils_1.logger.error('发送邀请失败:', error);
|
|
406
439
|
}
|
|
407
440
|
}
|
|
408
441
|
handleMessage(message) {
|
|
@@ -434,7 +467,7 @@ class WSClient {
|
|
|
434
467
|
else if (cmd === "invite_agent_req") {
|
|
435
468
|
// 收到邀请请求,自动接受
|
|
436
469
|
const { session_id, inviter_id, invite_code } = data;
|
|
437
|
-
|
|
470
|
+
utils_1.logger.log(`收到来自 ${inviter_id} 的会话邀请,会话ID: ${session_id}`);
|
|
438
471
|
this.acceptInvite(session_id, inviter_id, invite_code);
|
|
439
472
|
}
|
|
440
473
|
else if (cmd === "session_message") {
|
|
@@ -443,7 +476,7 @@ class WSClient {
|
|
|
443
476
|
}
|
|
444
477
|
acceptInvite(sessionId, inviterId, inviteCode) {
|
|
445
478
|
if (!this.isConnected()) {
|
|
446
|
-
|
|
479
|
+
utils_1.logger.error('WebSocket连接未建立,无法接受邀请');
|
|
447
480
|
return;
|
|
448
481
|
}
|
|
449
482
|
try {
|
|
@@ -458,11 +491,11 @@ class WSClient {
|
|
|
458
491
|
}
|
|
459
492
|
};
|
|
460
493
|
this.socket.send(JSON.stringify(msg));
|
|
461
|
-
|
|
494
|
+
utils_1.logger.log(`已接受会话邀请: ${sessionId}`);
|
|
462
495
|
this.isOnline = true;
|
|
463
496
|
}
|
|
464
497
|
catch (error) {
|
|
465
|
-
|
|
498
|
+
utils_1.logger.error('接受邀请失败:', error);
|
|
466
499
|
}
|
|
467
500
|
}
|
|
468
501
|
/**
|
|
@@ -470,7 +503,7 @@ class WSClient {
|
|
|
470
503
|
* 当心跳客户端收到邀请时,调用此方法通过 WebSocket 加入会话
|
|
471
504
|
*/
|
|
472
505
|
acceptInviteFromHeartbeat(sessionId, inviterId, inviteCode) {
|
|
473
|
-
|
|
506
|
+
utils_1.logger.log(`[WebSocket] 通过心跳通道收到邀请,加入会话: ${sessionId}`);
|
|
474
507
|
this.acceptInvite(sessionId, inviterId, inviteCode);
|
|
475
508
|
}
|
|
476
509
|
}
|