@koi-design/callkit 2.3.0-beta.10 → 2.3.0-beta.11

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.d.ts CHANGED
@@ -4805,7 +4805,7 @@ declare class Socket {
4805
4805
  private callKit;
4806
4806
  private ws?;
4807
4807
  lastPingTime: any;
4808
- pingTimer?: ReturnType<typeof setInterval>;
4808
+ private heartbeatManager;
4809
4809
  /**
4810
4810
  * @description reconnect timer
4811
4811
  */
@@ -4829,6 +4829,7 @@ declare class Socket {
4829
4829
  get isError(): boolean;
4830
4830
  constructor(callKit: CallKit);
4831
4831
  get reconnectConfig(): IncallConfig;
4832
+ get pingInterval(): number;
4832
4833
  isConnected(): boolean;
4833
4834
  init(): void;
4834
4835
  private setConnectAuthState;
@@ -4851,6 +4852,10 @@ declare class Socket {
4851
4852
  reset(config?: {
4852
4853
  force?: boolean;
4853
4854
  }): Promise<void>;
4855
+ /**
4856
+ * Destroy the heartbeat manager
4857
+ */
4858
+ destroyHeartbeat(): void;
4854
4859
  private attemptReconnect;
4855
4860
  }
4856
4861
 
@@ -4895,6 +4900,7 @@ interface IConfig {
4895
4900
  iceGatheringTimeout: number;
4896
4901
  encryptionMethod: EncryptionMethodType;
4897
4902
  logGather: boolean;
4903
+ keepaliveInterval?: number;
4898
4904
  };
4899
4905
  }
4900
4906
  declare class Config {
@@ -1736,7 +1736,7 @@ var WebCall = (() => {
1736
1736
  var require_follow_redirects = __commonJS({
1737
1737
  "../../node_modules/.pnpm/follow-redirects@1.15.9/node_modules/follow-redirects/index.js"(exports, module) {
1738
1738
  var url = __require("url");
1739
- var URL = url.URL;
1739
+ var URL2 = url.URL;
1740
1740
  var http = __require("http");
1741
1741
  var https = __require("https");
1742
1742
  var Writable = __require("stream").Writable;
@@ -1752,7 +1752,7 @@ var WebCall = (() => {
1752
1752
  })();
1753
1753
  var useNativeURL = false;
1754
1754
  try {
1755
- assert(new URL(""));
1755
+ assert(new URL2(""));
1756
1756
  } catch (error) {
1757
1757
  useNativeURL = error.code === "ERR_INVALID_URL";
1758
1758
  }
@@ -2132,7 +2132,7 @@ var WebCall = (() => {
2132
2132
  function parseUrl(input) {
2133
2133
  var parsed;
2134
2134
  if (useNativeURL) {
2135
- parsed = new URL(input);
2135
+ parsed = new URL2(input);
2136
2136
  } else {
2137
2137
  parsed = validateUrl(url.parse(input));
2138
2138
  if (!isString(parsed.protocol)) {
@@ -2142,7 +2142,7 @@ var WebCall = (() => {
2142
2142
  return parsed;
2143
2143
  }
2144
2144
  function resolveUrl(relative, base) {
2145
- return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));
2145
+ return useNativeURL ? new URL2(relative, base) : parseUrl(url.resolve(base, relative));
2146
2146
  }
2147
2147
  function validateUrl(input) {
2148
2148
  if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
@@ -2221,7 +2221,7 @@ var WebCall = (() => {
2221
2221
  return typeof value === "object" && "length" in value;
2222
2222
  }
2223
2223
  function isURL(value) {
2224
- return URL && value instanceof URL;
2224
+ return URL2 && value instanceof URL2;
2225
2225
  }
2226
2226
  module.exports = wrap({ http, https });
2227
2227
  module.exports.wrap = wrap;
@@ -3237,7 +3237,7 @@ var WebCall = (() => {
3237
3237
  const res = await this.post({
3238
3238
  url: "/auth/agentUser/login",
3239
3239
  method: "post",
3240
- data: params
3240
+ data: { ...params, browserVersion: navigator.userAgent }
3241
3241
  });
3242
3242
  return res;
3243
3243
  } finally {
@@ -3893,7 +3893,7 @@ var WebCall = (() => {
3893
3893
  // package.json
3894
3894
  var package_default = {
3895
3895
  name: "@koi-design/callkit",
3896
- version: "2.3.0-beta.10",
3896
+ version: "2.3.0-beta.11",
3897
3897
  description: "callkit",
3898
3898
  author: "koi",
3899
3899
  license: "ISC",
@@ -19929,12 +19929,152 @@ ${log}` : log;
19929
19929
  }
19930
19930
  };
19931
19931
 
19932
+ // core/heartbeat-worker.ts
19933
+ var workerCode = `
19934
+ let timer = null;
19935
+ let interval = 30000;
19936
+
19937
+ self.onmessage = function(e) {
19938
+ const { type, interval: newInterval } = e.data;
19939
+
19940
+ if (type === 'start') {
19941
+ if (timer) {
19942
+ clearInterval(timer);
19943
+ }
19944
+ interval = newInterval || interval;
19945
+ timer = setInterval(() => {
19946
+ self.postMessage({ type: 'tick' });
19947
+ }, interval);
19948
+ }
19949
+
19950
+ if (type === 'stop') {
19951
+ if (timer) {
19952
+ clearInterval(timer);
19953
+ timer = null;
19954
+ }
19955
+ }
19956
+
19957
+ if (type === 'updateInterval') {
19958
+ interval = newInterval;
19959
+ if (timer) {
19960
+ clearInterval(timer);
19961
+ timer = setInterval(() => {
19962
+ self.postMessage({ type: 'tick' });
19963
+ }, interval);
19964
+ }
19965
+ }
19966
+ };
19967
+ `;
19968
+ function createHeartbeatWorker() {
19969
+ try {
19970
+ const blob = new Blob([workerCode], { type: "application/javascript" });
19971
+ const workerUrl = URL.createObjectURL(blob);
19972
+ const worker = new Worker(workerUrl);
19973
+ URL.revokeObjectURL(workerUrl);
19974
+ return worker;
19975
+ } catch {
19976
+ return null;
19977
+ }
19978
+ }
19979
+ var HeartbeatManager = class {
19980
+ worker = null;
19981
+ fallbackTimer = null;
19982
+ interval = 3e4;
19983
+ onTick = null;
19984
+ isRunning = false;
19985
+ constructor() {
19986
+ this.worker = createHeartbeatWorker();
19987
+ if (this.worker) {
19988
+ this.worker.onmessage = (e) => {
19989
+ if (e.data.type === "tick" && this.onTick) {
19990
+ this.onTick();
19991
+ }
19992
+ };
19993
+ }
19994
+ }
19995
+ /**
19996
+ * Start the heartbeat
19997
+ * @param interval - Interval in milliseconds
19998
+ * @param onTick - Callback function to execute on each tick
19999
+ */
20000
+ start(interval, onTick) {
20001
+ this.stop();
20002
+ this.interval = interval;
20003
+ this.onTick = onTick;
20004
+ this.isRunning = true;
20005
+ if (this.worker) {
20006
+ this.worker.postMessage({
20007
+ type: "start",
20008
+ interval
20009
+ });
20010
+ } else {
20011
+ this.fallbackTimer = setInterval(() => {
20012
+ if (this.onTick) {
20013
+ this.onTick();
20014
+ }
20015
+ }, interval);
20016
+ }
20017
+ }
20018
+ /**
20019
+ * Stop the heartbeat
20020
+ */
20021
+ stop() {
20022
+ this.isRunning = false;
20023
+ this.onTick = null;
20024
+ if (this.worker) {
20025
+ this.worker.postMessage({ type: "stop" });
20026
+ }
20027
+ if (this.fallbackTimer) {
20028
+ clearInterval(this.fallbackTimer);
20029
+ this.fallbackTimer = null;
20030
+ }
20031
+ }
20032
+ /**
20033
+ * Update the heartbeat interval
20034
+ * @param interval - New interval in milliseconds
20035
+ */
20036
+ updateInterval(interval) {
20037
+ this.interval = interval;
20038
+ if (!this.isRunning)
20039
+ return;
20040
+ if (this.worker) {
20041
+ this.worker.postMessage({
20042
+ type: "updateInterval",
20043
+ interval
20044
+ });
20045
+ } else if (this.fallbackTimer && this.onTick) {
20046
+ clearInterval(this.fallbackTimer);
20047
+ this.fallbackTimer = setInterval(() => {
20048
+ if (this.onTick) {
20049
+ this.onTick();
20050
+ }
20051
+ }, interval);
20052
+ }
20053
+ }
20054
+ /**
20055
+ * Destroy the heartbeat manager and release resources
20056
+ */
20057
+ destroy() {
20058
+ this.stop();
20059
+ if (this.worker) {
20060
+ this.worker.terminate();
20061
+ this.worker = null;
20062
+ }
20063
+ }
20064
+ /**
20065
+ * Check if using Web Worker
20066
+ */
20067
+ isUsingWorker() {
20068
+ return this.worker !== null;
20069
+ }
20070
+ };
20071
+
19932
20072
  // core/socket.ts
19933
20073
  var Socket = class {
19934
20074
  callKit;
19935
20075
  ws;
19936
20076
  lastPingTime = void 0;
19937
- pingTimer;
20077
+ heartbeatManager;
19938
20078
  /**
19939
20079
  * @description reconnect timer
19940
20080
  */
@@ -19967,10 +20107,18 @@ ${log}` : log;
19967
20107
  }
19968
20108
  constructor(callKit) {
19969
20109
  this.callKit = callKit;
20110
+ this.heartbeatManager = new HeartbeatManager();
19970
20111
  }
19971
20112
  get reconnectConfig() {
19972
20113
  return this.callKit.config.getReconnectConfig("incall");
19973
20114
  }
20115
+ get pingInterval() {
20116
+ const { keepaliveInterval } = this.callKit.config.getConfig().userInfo;
20117
+ if (Number.isInteger(keepaliveInterval) && keepaliveInterval > 0) {
20118
+ return keepaliveInterval * 1e3;
20119
+ }
20120
+ return this.reconnectConfig.pingInterval;
20121
+ }
19974
20122
  isConnected() {
19975
20123
  return this.connectAuthState.isConnected;
19976
20124
  }
@@ -20327,8 +20475,8 @@ ${log}` : log;
20327
20475
  return;
20328
20476
  this.send(SocketSendEvent.PING);
20329
20477
  const now = Date.now();
20330
- const { pingInterval, pingTimeout } = this.reconnectConfig;
20331
- if (now - this.lastPingTime > pingInterval + pingTimeout) {
20478
+ const { pingTimeout } = this.reconnectConfig;
20479
+ if (now - this.lastPingTime > this.pingInterval + pingTimeout) {
20332
20480
  this.callKit.logger.warn("Ping timeout not connected", {
20333
20481
  caller: "Socket.ping",
20334
20482
  type: "INCALL",
@@ -20343,23 +20491,27 @@ ${log}` : log;
20343
20491
  }
20344
20492
  }
20345
20493
  checkPing() {
20346
- if (this.pingTimer) {
20347
- clearInterval(this.pingTimer);
20348
- }
20349
- const { pingInterval } = this.reconnectConfig;
20350
- this.pingTimer = setInterval(() => {
20494
+ this.heartbeatManager.start(this.pingInterval, () => {
20351
20495
  this.ping();
20352
- }, pingInterval);
20496
+ });
20497
+ this.callKit.logger.info(
20498
+ `Heartbeat started with Worker: ${this.heartbeatManager.isUsingWorker()}`,
20499
+ {
20500
+ caller: "Socket.checkPing",
20501
+ type: "INCALL",
20502
+ content: {
20503
+ pingInterval: this.pingInterval,
20504
+ usingWorker: this.heartbeatManager.isUsingWorker()
20505
+ }
20506
+ }
20507
+ );
20353
20508
  }
20354
20509
  /**
20355
20510
  * reset socket connection and all states
20356
20511
  */
20357
20512
  async reset(config) {
20358
20513
  const { force = false } = config || {};
20359
- if (this.pingTimer) {
20360
- clearInterval(this.pingTimer);
20361
- this.pingTimer = void 0;
20362
- }
20514
+ this.heartbeatManager.stop();
20363
20515
  if (force) {
20364
20516
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
20365
20517
  event: "INCALL_RESET"
@@ -20370,6 +20522,12 @@ ${log}` : log;
20370
20522
  this.setConnectAuthState("startConfirm", false);
20371
20523
  this.clearWebSocket();
20372
20524
  }
20525
+ /**
20526
+ * Destroy the heartbeat manager
20527
+ */
20528
+ destroyHeartbeat() {
20529
+ this.heartbeatManager.destroy();
20530
+ }
20373
20531
  attemptReconnect() {
20374
20532
  if (this.reconnectTimer) {
20375
20533
  clearTimeout(this.reconnectTimer);
@@ -20495,6 +20653,7 @@ ${log}` : log;
20495
20653
  content: {
20496
20654
  username,
20497
20655
  password,
20656
+ ua: navigator.userAgent,
20498
20657
  encryptionMethod,
20499
20658
  encryptionPassword
20500
20659
  }
@@ -20528,6 +20687,7 @@ ${log}` : log;
20528
20687
  iceInfo: user.iceInfo,
20529
20688
  iceGatheringTimeout: user.iceGatheringTimeout,
20530
20689
  logGather: user.logGather,
20690
+ keepaliveInterval: user.keepaliveInterval,
20531
20691
  phoneType: user.phoneType,
20532
20692
  // encryptionType is in extra
20533
20693
  ...extra