@koi-design/callkit 2.0.3 → 2.0.5

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.js CHANGED
@@ -645,12 +645,13 @@ var Call = class {
645
645
  // package.json
646
646
  var package_default = {
647
647
  name: "@koi-design/callkit",
648
- version: "2.0.3",
648
+ version: "2.0.5",
649
649
  description: "callkit",
650
650
  author: "koi",
651
651
  license: "ISC",
652
652
  scripts: {
653
653
  build: "tsup",
654
+ "build:w": "tsup --watch",
654
655
  dev: "vite",
655
656
  lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
656
657
  release: "tsup && node scripts/pkg.js"
@@ -1918,36 +1919,48 @@ var Connect = class {
1918
1919
  var RECONNECT_CONFIG = {
1919
1920
  enabled: true,
1920
1921
  maxAttempts: 3,
1921
- delay: 500,
1922
- backoffMultiplier: 1.5,
1922
+ delay: 1e3,
1923
1923
  pingInterval: 3e4,
1924
- pingTimeout: 5e3,
1925
- maxConnectsPerWindow: 5,
1926
- timeWindow: 6e4
1927
- // 60 seconds
1924
+ pingTimeout: 5e3
1928
1925
  };
1929
1926
  var Socket = class {
1930
1927
  callKit;
1931
1928
  ws;
1932
- socketConfig;
1933
1929
  lastPingTime = void 0;
1934
- isConnected = false;
1935
1930
  pingTimer;
1936
- // Whether received start confirmation
1937
- satrtConfirm = false;
1931
+ /**
1932
+ * @description reconnect timer
1933
+ */
1938
1934
  reconnectTimer;
1939
- isReconnecting = false;
1935
+ /**
1936
+ * @description reconnect attempts
1937
+ */
1940
1938
  reconnectAttempts = 0;
1941
- socketError = false;
1942
- // Track connection attempts for rate limiting
1943
- connectAttemptTimes = [];
1939
+ /**
1940
+ * @description connect auth state
1941
+ * @default {
1942
+ * satrtConfirm: false,
1943
+ * isConnected: false,
1944
+ * isReconnecting: false,
1945
+ * isAuthenticated: false,
1946
+ * isError: false
1947
+ * }
1948
+ */
1949
+ connectAuthState = {
1950
+ satrtConfirm: false,
1951
+ isConnected: false,
1952
+ isReconnecting: false,
1953
+ isAuthenticated: false,
1954
+ isError: false
1955
+ };
1956
+ get satrtConfirm() {
1957
+ return this.connectAuthState.satrtConfirm;
1958
+ }
1959
+ get isError() {
1960
+ return this.connectAuthState.isError;
1961
+ }
1944
1962
  constructor(callKit) {
1945
1963
  this.callKit = callKit;
1946
- const { reconnect } = this.callKit.config.getConfig();
1947
- this.socketConfig = {
1948
- ...RECONNECT_CONFIG,
1949
- ...reconnect
1950
- };
1951
1964
  }
1952
1965
  init() {
1953
1966
  const { socket } = this.callKit.config.getConfig();
@@ -1960,16 +1973,29 @@ var Socket = class {
1960
1973
  });
1961
1974
  this.connect(socket);
1962
1975
  }
1976
+ getSocketConfig() {
1977
+ const { reconnect } = this.callKit.config.getConfig();
1978
+ return {
1979
+ ...RECONNECT_CONFIG,
1980
+ ...reconnect
1981
+ };
1982
+ }
1983
+ setConnectAuthState(key, value) {
1984
+ if (this.connectAuthState[key] === value)
1985
+ return;
1986
+ this.connectAuthState[key] = value;
1987
+ }
1963
1988
  handleDisconnect() {
1964
- this.isConnected = false;
1965
- if (!this.callKit.config.isLogin() || !this.socketConfig.enabled) {
1966
- this.reset();
1989
+ this.setConnectAuthState("isConnected", false);
1990
+ const { enabled } = this.getSocketConfig();
1991
+ if (!this.callKit.config.isLogin() || !enabled) {
1992
+ this.callKit.reset();
1967
1993
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
1968
1994
  event: "INCALL_NOT_CONNECTED"
1969
1995
  });
1970
1996
  return;
1971
1997
  }
1972
- if (this.isReconnecting) {
1998
+ if (this.connectAuthState.isReconnecting) {
1973
1999
  return;
1974
2000
  }
1975
2001
  this.attemptReconnect();
@@ -1990,13 +2016,12 @@ var Socket = class {
1990
2016
  });
1991
2017
  }
1992
2018
  this.ws = void 0;
1993
- this.isConnected = false;
2019
+ this.setConnectAuthState("isConnected", false);
1994
2020
  }
1995
2021
  connect(socketUrl) {
1996
2022
  if (this.ws) {
1997
2023
  this.clearWebSocket();
1998
2024
  }
1999
- this.connectAttemptTimes.push(Date.now());
2000
2025
  this.ws = new WebSocket(socketUrl);
2001
2026
  this.ws.onopen = (ev) => this.onOpen(ev);
2002
2027
  this.ws.onclose = (ev) => this.onClose(ev);
@@ -2009,11 +2034,11 @@ var Socket = class {
2009
2034
  type: "INCALL",
2010
2035
  content: { ev }
2011
2036
  });
2012
- this.socketError = false;
2013
- this.isConnected = true;
2037
+ this.setConnectAuthState("isConnected", true);
2014
2038
  this.lastPingTime = Date.now();
2015
2039
  this.checkPing();
2016
- if (this.isReconnecting) {
2040
+ if (this.connectAuthState.isReconnecting) {
2041
+ this.setConnectAuthState("isReconnecting", false);
2017
2042
  this.callKit.logger.info("reconnect success", {
2018
2043
  caller: "Socket.onOpen",
2019
2044
  type: "INCALL",
@@ -2026,10 +2051,15 @@ var Socket = class {
2026
2051
  event: "INCALL_RECONNECT_SUCCESS"
2027
2052
  });
2028
2053
  }
2029
- this.resetReconnectState();
2030
2054
  }
2031
- resetReconnectState() {
2032
- this.isReconnecting = false;
2055
+ resetConnectState() {
2056
+ this.connectAuthState = {
2057
+ satrtConfirm: false,
2058
+ isConnected: false,
2059
+ isReconnecting: false,
2060
+ isAuthenticated: false,
2061
+ isError: false
2062
+ };
2033
2063
  this.reconnectAttempts = 0;
2034
2064
  if (this.reconnectTimer) {
2035
2065
  clearTimeout(this.reconnectTimer);
@@ -2042,13 +2072,9 @@ var Socket = class {
2042
2072
  type: "INCALL",
2043
2073
  content: { ev }
2044
2074
  });
2045
- if (this.socketError) {
2046
- return;
2047
- }
2048
2075
  this.handleDisconnect();
2049
2076
  }
2050
2077
  onError(ev) {
2051
- this.socketError = true;
2052
2078
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2053
2079
  event: "INCALL_CONNECT_ERROR",
2054
2080
  err: ev
@@ -2098,6 +2124,20 @@ var Socket = class {
2098
2124
  this.confirmAck(data);
2099
2125
  if (data.event === SocketReceiveEvent.PONG) {
2100
2126
  this.lastPingTime = Date.now();
2127
+ this.setConnectAuthState("isAuthenticated", true);
2128
+ this.callKit.logger.info("socket onMessage pong Authenticated", {
2129
+ caller: "Socket.onMessage",
2130
+ type: "INCALL",
2131
+ content: {
2132
+ data: content,
2133
+ event: SocketReceiveEvent.PONG,
2134
+ isAuthenticated: true
2135
+ }
2136
+ });
2137
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2138
+ event: "INCALL_AUTHENTICATED",
2139
+ isAuthenticated: true
2140
+ });
2101
2141
  return;
2102
2142
  }
2103
2143
  if (data.event === SocketReceiveEvent.START_CONFIRM) {
@@ -2109,7 +2149,7 @@ var Socket = class {
2109
2149
  event: SocketReceiveEvent.START_CONFIRM
2110
2150
  }
2111
2151
  });
2112
- this.satrtConfirm = true;
2152
+ this.setConnectAuthState("satrtConfirm", true);
2113
2153
  }
2114
2154
  if (data.event === SocketReceiveEvent.CALL_SUCCESS) {
2115
2155
  this.callKit.logger.info("call success", {
@@ -2223,12 +2263,10 @@ var Socket = class {
2223
2263
  event: SocketReceiveEvent.CLOSE
2224
2264
  }
2225
2265
  });
2226
- this.send(SocketSendEvent.END, {
2227
- agentId: userInfo.agentId
2228
- });
2266
+ this.send(SocketSendEvent.END, { agentId: userInfo.agentId });
2229
2267
  }
2230
2268
  if (data.event === SocketReceiveEvent.ERROR) {
2231
- this.socketError = true;
2269
+ this.setConnectAuthState("isError", true);
2232
2270
  this.callKit.reset();
2233
2271
  this.callKit.logger.error(data.msg, {
2234
2272
  caller: `Socket.onMessage:${data.event}`,
@@ -2240,7 +2278,7 @@ var Socket = class {
2240
2278
  });
2241
2279
  }
2242
2280
  if (data.event === SocketReceiveEvent.SESSION_ERROR) {
2243
- this.socketError = true;
2281
+ this.setConnectAuthState("isError", true);
2244
2282
  this.callKit.reset();
2245
2283
  this.callKit.logger.error(data.msg, {
2246
2284
  caller: `Socket.onMessage:${data.event}`,
@@ -2267,7 +2305,7 @@ var Socket = class {
2267
2305
  this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);
2268
2306
  }
2269
2307
  send(event, message) {
2270
- if (!this.isConnected) {
2308
+ if (!this.connectAuthState.isConnected) {
2271
2309
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2272
2310
  event: "INCALL_NOT_CONNECTED"
2273
2311
  });
@@ -2326,7 +2364,7 @@ var Socket = class {
2326
2364
  }
2327
2365
  }
2328
2366
  ping() {
2329
- if (!this.isConnected)
2367
+ if (!this.connectAuthState.isConnected)
2330
2368
  return;
2331
2369
  this.send(SocketSendEvent.PING);
2332
2370
  this.callKit.logger.info(`socket ping`, {
@@ -2337,12 +2375,12 @@ var Socket = class {
2337
2375
  }
2338
2376
  });
2339
2377
  const now = Date.now();
2340
- const { pingInterval, pingTimeout } = this.socketConfig;
2378
+ const { pingInterval, pingTimeout } = this.getSocketConfig();
2341
2379
  if (now - this.lastPingTime > pingInterval + pingTimeout) {
2342
- if (this.ws && this.isConnected) {
2380
+ if (this.ws && this.connectAuthState.isConnected) {
2343
2381
  this.ws.close(4001, "ping timeout");
2344
2382
  } else {
2345
- this.reset();
2383
+ this.callKit.reset();
2346
2384
  }
2347
2385
  this.callKit.logger.error("socket ping timeout", {
2348
2386
  caller: "Socket.ping",
@@ -2358,23 +2396,29 @@ var Socket = class {
2358
2396
  clearInterval(this.pingTimer);
2359
2397
  }
2360
2398
  this.ping();
2399
+ const { pingInterval } = this.getSocketConfig();
2361
2400
  this.pingTimer = setInterval(() => {
2362
2401
  this.ping();
2363
- }, this.socketConfig.pingInterval);
2402
+ }, pingInterval);
2364
2403
  }
2365
2404
  /**
2366
2405
  * reset socket connection and all states
2367
2406
  */
2368
- async reset() {
2407
+ async reset(config) {
2408
+ const { focus = false } = config || {};
2369
2409
  if (this.pingTimer) {
2370
2410
  clearInterval(this.pingTimer);
2371
2411
  this.pingTimer = void 0;
2372
2412
  }
2373
- this.resetReconnectState();
2413
+ if (focus) {
2414
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2415
+ event: "INCALL_RESET"
2416
+ });
2417
+ this.resetConnectState();
2418
+ this.setConnectAuthState("isConnected", false);
2419
+ }
2374
2420
  this.lastPingTime = void 0;
2375
- this.satrtConfirm = false;
2376
- this.socketError = false;
2377
- this.connectAttemptTimes = [];
2421
+ this.setConnectAuthState("satrtConfirm", false);
2378
2422
  this.clearWebSocket();
2379
2423
  }
2380
2424
  attemptReconnect() {
@@ -2382,34 +2426,12 @@ var Socket = class {
2382
2426
  clearTimeout(this.reconnectTimer);
2383
2427
  this.reconnectTimer = void 0;
2384
2428
  }
2385
- const { maxConnectsPerWindow, timeWindow } = this.socketConfig;
2386
- if (maxConnectsPerWindow && timeWindow) {
2387
- const now = Date.now();
2388
- this.connectAttemptTimes = this.connectAttemptTimes.filter(
2389
- (time) => now - time < timeWindow
2390
- );
2391
- if (this.connectAttemptTimes.length >= maxConnectsPerWindow) {
2392
- this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2393
- event: "INCALL_RECONNECT_ERROR"
2394
- });
2395
- this.callKit.logger.warn("Connection rate limit exceeded", {
2396
- caller: "Socket.attemptReconnect",
2397
- type: "INCALL",
2398
- content: {
2399
- errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
2400
- attempts: this.connectAttemptTimes.length,
2401
- maxConnectsPerWindow,
2402
- timeWindow
2403
- }
2404
- });
2405
- return;
2406
- }
2407
- }
2408
- if (this.reconnectAttempts >= this.socketConfig.maxAttempts) {
2429
+ const { maxAttempts } = this.getSocketConfig();
2430
+ if (this.reconnectAttempts >= maxAttempts) {
2409
2431
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2410
2432
  event: "INCALL_RECONNECT_ERROR"
2411
2433
  });
2412
- this.reset();
2434
+ this.callKit.reset();
2413
2435
  this.callKit.logger.error("Maximum reconnection attempts reached", {
2414
2436
  caller: "Socket.attemptReconnect",
2415
2437
  type: "INCALL",
@@ -2425,17 +2447,17 @@ var Socket = class {
2425
2447
  event: "INCALL_RECONNECT_START"
2426
2448
  });
2427
2449
  }
2428
- this.isReconnecting = true;
2450
+ this.setConnectAuthState("isReconnecting", true);
2429
2451
  this.reconnectAttempts += 1;
2430
- const { delay } = this.socketConfig;
2452
+ const { delay } = this.getSocketConfig();
2431
2453
  this.callKit.logger.info(
2432
- `Preparing reconnection attempt ${this.reconnectAttempts}/${this.socketConfig.maxAttempts}, delay: ${delay}ms`,
2454
+ `Preparing reconnection attempt ${this.reconnectAttempts}/${maxAttempts}, delay: ${delay}ms`,
2433
2455
  {
2434
2456
  caller: "Socket.attemptReconnect",
2435
2457
  type: "INCALL",
2436
2458
  content: {
2437
2459
  reconnectAttempts: this.reconnectAttempts,
2438
- maxAttempts: this.socketConfig.maxAttempts,
2460
+ maxAttempts,
2439
2461
  delay
2440
2462
  }
2441
2463
  }
@@ -2510,6 +2532,13 @@ var CallKit = class {
2510
2532
  encryptionPassword
2511
2533
  }
2512
2534
  });
2535
+ if (this.socket.isError) {
2536
+ this.logger.warn("socket is error", {
2537
+ caller: "CallKit.login",
2538
+ content: { username, password, extra, socketError: this.socket.isError }
2539
+ });
2540
+ return;
2541
+ }
2513
2542
  try {
2514
2543
  const user = await this.api.login({
2515
2544
  userName: username,
@@ -2561,7 +2590,7 @@ var CallKit = class {
2561
2590
  try {
2562
2591
  await this.api.loginOut({ sessionId });
2563
2592
  } catch (error) {
2564
- this.logger.error(error, {
2593
+ this.logger.warn(error, {
2565
2594
  caller: "CallKit.logout",
2566
2595
  content: {
2567
2596
  errCode: ErrorCode.API_USER_LOGOUT_ERROR
@@ -2637,9 +2666,6 @@ var CallKit = class {
2637
2666
  });
2638
2667
  this.connect.unregister();
2639
2668
  }
2640
- async stop() {
2641
- await this.connect.stop();
2642
- }
2643
2669
  async hangup() {
2644
2670
  if (!this.config.check())
2645
2671
  return;
@@ -2722,11 +2748,13 @@ var CallKit = class {
2722
2748
  userStatus: status
2723
2749
  });
2724
2750
  }
2725
- async reset() {
2751
+ async _reset(config) {
2752
+ const { focus = false } = config || {};
2726
2753
  this.logger.info("reset", {
2727
2754
  caller: "CallKit.reset",
2728
2755
  content: {
2729
- connectStatus: this.connect.connectStatus
2756
+ connectStatus: this.connect.connectStatus,
2757
+ focus
2730
2758
  }
2731
2759
  });
2732
2760
  if (this.connect.isCalling()) {
@@ -2737,7 +2765,14 @@ var CallKit = class {
2737
2765
  await this.logout({ isReset: false });
2738
2766
  }
2739
2767
  await this.config.reset();
2740
- await this.socket.reset();
2768
+ await this.socket.reset({ focus });
2769
+ }
2770
+ /**
2771
+ * reset callkit
2772
+ * @description recover the callkit to the initial state
2773
+ */
2774
+ async reset() {
2775
+ await this._reset({ focus: true });
2741
2776
  }
2742
2777
  on(event, callback) {
2743
2778
  this.listener.push({