liangzimixin 0.3.35 → 0.3.36

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/index.cjs CHANGED
@@ -18929,7 +18929,11 @@ var quantumImPlugin = {
18929
18929
  })
18930
18930
  },
18931
18931
  messaging: {
18932
- normalizeTarget: (raw) => raw ?? void 0
18932
+ normalizeTarget: (raw) => {
18933
+ if (!raw) return void 0;
18934
+ const normalized = parseChannelAddress(raw).trim();
18935
+ return normalized || void 0;
18936
+ }
18933
18937
  },
18934
18938
  outbound: quantumImOutbound,
18935
18939
  setup: {
@@ -19865,6 +19869,9 @@ var WSClient = class extends import_node_events.EventEmitter {
19865
19869
  ws.on("message", (data) => {
19866
19870
  this.emit("message", data);
19867
19871
  });
19872
+ ws.on("pong", () => {
19873
+ this.emit("pong");
19874
+ });
19868
19875
  ws.on("close", (code, reason) => {
19869
19876
  log19.info("ws:closed", { code, reason: reason.toString() });
19870
19877
  this.emit("close", code, reason.toString());
@@ -19887,6 +19894,12 @@ var WSClient = class extends import_node_events.EventEmitter {
19887
19894
  }
19888
19895
  this.ws.send(data);
19889
19896
  }
19897
+ /** 发送 WebSocket 协议级 Ping 帧 */
19898
+ ping() {
19899
+ if (this.ws && this.ws.readyState === wrapper_default.OPEN) {
19900
+ this.ws.ping();
19901
+ }
19902
+ }
19890
19903
  /** 关闭连接 */
19891
19904
  close(code, reason) {
19892
19905
  if (this.ws) {
@@ -20243,6 +20256,8 @@ var ConnectionManager = class {
20243
20256
  appId = "";
20244
20257
  /** 是否正在重连中 (防止并发重连) */
20245
20258
  reconnecting = false;
20259
+ /** 是否收到了最近一次 pong 响应 */
20260
+ pongReceived = true;
20246
20261
  constructor(client, options) {
20247
20262
  this.client = client;
20248
20263
  this.options = {
@@ -20276,6 +20291,15 @@ var ConnectionManager = class {
20276
20291
  ...this.appId ? { "X-App-ID": this.appId } : {}
20277
20292
  }
20278
20293
  });
20294
+ this.registerEvents();
20295
+ this.startHeartbeat();
20296
+ log22.info("ConnectionManager started \u2713", { url: url2 });
20297
+ }
20298
+ /** 注册 close / error / pong 事件 */
20299
+ registerEvents() {
20300
+ this.client.removeAllListeners("close");
20301
+ this.client.removeAllListeners("error");
20302
+ this.client.removeAllListeners("pong");
20279
20303
  this.client.on("close", () => {
20280
20304
  if (this.running) {
20281
20305
  log22.warn("ws:disconnected, scheduling reconnect");
@@ -20285,17 +20309,29 @@ var ConnectionManager = class {
20285
20309
  this.client.on("error", (err) => {
20286
20310
  log22.error("ws:connection-error", { error: err.message });
20287
20311
  });
20288
- this.startHeartbeat();
20289
- log22.info("ConnectionManager started \u2713", { url: url2 });
20312
+ this.client.on("pong", () => {
20313
+ this.pongReceived = true;
20314
+ });
20290
20315
  }
20291
- /** 启动心跳保活 — 定时检查连接状态 */
20316
+ /** 启动心跳保活 — 定时发送 WebSocket Ping 帧 */
20292
20317
  startHeartbeat() {
20293
20318
  this.stopHeartbeat();
20319
+ this.pongReceived = true;
20294
20320
  this.heartbeatTimer = setInterval(() => {
20295
20321
  if (this.client.readyState !== wrapper_default.OPEN) {
20296
20322
  log22.warn("heartbeat: connection not open, scheduling reconnect");
20297
20323
  this.scheduleReconnect();
20324
+ return;
20325
+ }
20326
+ if (!this.pongReceived) {
20327
+ log22.warn("heartbeat: pong timeout, connection dead");
20328
+ this.client.close(4e3, "pong timeout");
20329
+ this.scheduleReconnect();
20330
+ return;
20298
20331
  }
20332
+ this.pongReceived = false;
20333
+ this.client.ping();
20334
+ log22.debug?.("heartbeat: ping sent");
20299
20335
  }, this.options.heartbeatIntervalMs);
20300
20336
  }
20301
20337
  /** 停止心跳定时器 */
@@ -20337,6 +20373,7 @@ var ConnectionManager = class {
20337
20373
  }
20338
20374
  });
20339
20375
  this.reconnectAttempts = 0;
20376
+ this.registerEvents();
20340
20377
  this.startHeartbeat();
20341
20378
  log22.info("ws:reconnected", { attempt: this.reconnectAttempts, url: this.url });
20342
20379
  return;
package/dist/index.d.cts CHANGED
@@ -684,6 +684,8 @@ declare class WSClient extends EventEmitter {
684
684
  connect(options: WSClientOptions): Promise<void>;
685
685
  /** 发送数据到服务器 — 前置检查连接状态 */
686
686
  send(data: string | Buffer): void;
687
+ /** 发送 WebSocket 协议级 Ping 帧 */
688
+ ping(): void;
687
689
  /** 关闭连接 */
688
690
  close(code?: number, reason?: string): void;
689
691
  /** 当前连接状态 (0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED) */
@@ -865,6 +867,8 @@ declare class ConnectionManager {
865
867
  private appId;
866
868
  /** 是否正在重连中 (防止并发重连) */
867
869
  private reconnecting;
870
+ /** 是否收到了最近一次 pong 响应 */
871
+ private pongReceived;
868
872
  constructor(client: WSClient, options?: ConnectionManagerOptions);
869
873
  /**
870
874
  * 启动连接 — 连接 WS + 开始心跳 + 注册重连逻辑
@@ -873,7 +877,9 @@ declare class ConnectionManager {
873
877
  * @param appId - 应用 ID (用于 X-App-ID 头)
874
878
  */
875
879
  start(url: string, tokenFn: () => Promise<string>, appId?: string): Promise<void>;
876
- /** 启动心跳保活 定时检查连接状态 */
880
+ /** 注册 close / error / pong 事件 */
881
+ private registerEvents;
882
+ /** 启动心跳保活 — 定时发送 WebSocket Ping 帧 */
877
883
  private startHeartbeat;
878
884
  /** 停止心跳定时器 */
879
885
  private stopHeartbeat;
@@ -18928,6 +18928,9 @@ var WSClient = class extends import_node_events.EventEmitter {
18928
18928
  ws.on("message", (data) => {
18929
18929
  this.emit("message", data);
18930
18930
  });
18931
+ ws.on("pong", () => {
18932
+ this.emit("pong");
18933
+ });
18931
18934
  ws.on("close", (code, reason) => {
18932
18935
  log10.info("ws:closed", { code, reason: reason.toString() });
18933
18936
  this.emit("close", code, reason.toString());
@@ -18950,6 +18953,12 @@ var WSClient = class extends import_node_events.EventEmitter {
18950
18953
  }
18951
18954
  this.ws.send(data);
18952
18955
  }
18956
+ /** 发送 WebSocket 协议级 Ping 帧 */
18957
+ ping() {
18958
+ if (this.ws && this.ws.readyState === wrapper_default.OPEN) {
18959
+ this.ws.ping();
18960
+ }
18961
+ }
18953
18962
  /** 关闭连接 */
18954
18963
  close(code, reason) {
18955
18964
  if (this.ws) {
@@ -19306,6 +19315,8 @@ var ConnectionManager = class {
19306
19315
  appId = "";
19307
19316
  /** 是否正在重连中 (防止并发重连) */
19308
19317
  reconnecting = false;
19318
+ /** 是否收到了最近一次 pong 响应 */
19319
+ pongReceived = true;
19309
19320
  constructor(client, options) {
19310
19321
  this.client = client;
19311
19322
  this.options = {
@@ -19339,6 +19350,15 @@ var ConnectionManager = class {
19339
19350
  ...this.appId ? { "X-App-ID": this.appId } : {}
19340
19351
  }
19341
19352
  });
19353
+ this.registerEvents();
19354
+ this.startHeartbeat();
19355
+ log13.info("ConnectionManager started \u2713", { url: url2 });
19356
+ }
19357
+ /** 注册 close / error / pong 事件 */
19358
+ registerEvents() {
19359
+ this.client.removeAllListeners("close");
19360
+ this.client.removeAllListeners("error");
19361
+ this.client.removeAllListeners("pong");
19342
19362
  this.client.on("close", () => {
19343
19363
  if (this.running) {
19344
19364
  log13.warn("ws:disconnected, scheduling reconnect");
@@ -19348,17 +19368,29 @@ var ConnectionManager = class {
19348
19368
  this.client.on("error", (err) => {
19349
19369
  log13.error("ws:connection-error", { error: err.message });
19350
19370
  });
19351
- this.startHeartbeat();
19352
- log13.info("ConnectionManager started \u2713", { url: url2 });
19371
+ this.client.on("pong", () => {
19372
+ this.pongReceived = true;
19373
+ });
19353
19374
  }
19354
- /** 启动心跳保活 — 定时检查连接状态 */
19375
+ /** 启动心跳保活 — 定时发送 WebSocket Ping 帧 */
19355
19376
  startHeartbeat() {
19356
19377
  this.stopHeartbeat();
19378
+ this.pongReceived = true;
19357
19379
  this.heartbeatTimer = setInterval(() => {
19358
19380
  if (this.client.readyState !== wrapper_default.OPEN) {
19359
19381
  log13.warn("heartbeat: connection not open, scheduling reconnect");
19360
19382
  this.scheduleReconnect();
19383
+ return;
19361
19384
  }
19385
+ if (!this.pongReceived) {
19386
+ log13.warn("heartbeat: pong timeout, connection dead");
19387
+ this.client.close(4e3, "pong timeout");
19388
+ this.scheduleReconnect();
19389
+ return;
19390
+ }
19391
+ this.pongReceived = false;
19392
+ this.client.ping();
19393
+ log13.debug?.("heartbeat: ping sent");
19362
19394
  }, this.options.heartbeatIntervalMs);
19363
19395
  }
19364
19396
  /** 停止心跳定时器 */
@@ -19400,6 +19432,7 @@ var ConnectionManager = class {
19400
19432
  }
19401
19433
  });
19402
19434
  this.reconnectAttempts = 0;
19435
+ this.registerEvents();
19403
19436
  this.startHeartbeat();
19404
19437
  log13.info("ws:reconnected", { attempt: this.reconnectAttempts, url: this.url });
19405
19438
  return;
@@ -20661,7 +20694,11 @@ var quantumImPlugin = {
20661
20694
  })
20662
20695
  },
20663
20696
  messaging: {
20664
- normalizeTarget: (raw) => raw ?? void 0
20697
+ normalizeTarget: (raw) => {
20698
+ if (!raw) return void 0;
20699
+ const normalized = parseChannelAddress(raw).trim();
20700
+ return normalized || void 0;
20701
+ }
20665
20702
  },
20666
20703
  outbound: quantumImOutbound,
20667
20704
  setup: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liangzimixin",
3
- "version": "0.3.35",
3
+ "version": "0.3.36",
4
4
  "description": "Quantum-encrypted IM channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",