@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.mjs CHANGED
@@ -612,12 +612,13 @@ var Call = class {
612
612
  // package.json
613
613
  var package_default = {
614
614
  name: "@koi-design/callkit",
615
- version: "2.0.3",
615
+ version: "2.0.5",
616
616
  description: "callkit",
617
617
  author: "koi",
618
618
  license: "ISC",
619
619
  scripts: {
620
620
  build: "tsup",
621
+ "build:w": "tsup --watch",
621
622
  dev: "vite",
622
623
  lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
623
624
  release: "tsup && node scripts/pkg.js"
@@ -1891,36 +1892,48 @@ var Connect = class {
1891
1892
  var RECONNECT_CONFIG = {
1892
1893
  enabled: true,
1893
1894
  maxAttempts: 3,
1894
- delay: 500,
1895
- backoffMultiplier: 1.5,
1895
+ delay: 1e3,
1896
1896
  pingInterval: 3e4,
1897
- pingTimeout: 5e3,
1898
- maxConnectsPerWindow: 5,
1899
- timeWindow: 6e4
1900
- // 60 seconds
1897
+ pingTimeout: 5e3
1901
1898
  };
1902
1899
  var Socket = class {
1903
1900
  callKit;
1904
1901
  ws;
1905
- socketConfig;
1906
1902
  lastPingTime = void 0;
1907
- isConnected = false;
1908
1903
  pingTimer;
1909
- // Whether received start confirmation
1910
- satrtConfirm = false;
1904
+ /**
1905
+ * @description reconnect timer
1906
+ */
1911
1907
  reconnectTimer;
1912
- isReconnecting = false;
1908
+ /**
1909
+ * @description reconnect attempts
1910
+ */
1913
1911
  reconnectAttempts = 0;
1914
- socketError = false;
1915
- // Track connection attempts for rate limiting
1916
- connectAttemptTimes = [];
1912
+ /**
1913
+ * @description connect auth state
1914
+ * @default {
1915
+ * satrtConfirm: false,
1916
+ * isConnected: false,
1917
+ * isReconnecting: false,
1918
+ * isAuthenticated: false,
1919
+ * isError: false
1920
+ * }
1921
+ */
1922
+ connectAuthState = {
1923
+ satrtConfirm: false,
1924
+ isConnected: false,
1925
+ isReconnecting: false,
1926
+ isAuthenticated: false,
1927
+ isError: false
1928
+ };
1929
+ get satrtConfirm() {
1930
+ return this.connectAuthState.satrtConfirm;
1931
+ }
1932
+ get isError() {
1933
+ return this.connectAuthState.isError;
1934
+ }
1917
1935
  constructor(callKit) {
1918
1936
  this.callKit = callKit;
1919
- const { reconnect } = this.callKit.config.getConfig();
1920
- this.socketConfig = {
1921
- ...RECONNECT_CONFIG,
1922
- ...reconnect
1923
- };
1924
1937
  }
1925
1938
  init() {
1926
1939
  const { socket } = this.callKit.config.getConfig();
@@ -1933,16 +1946,29 @@ var Socket = class {
1933
1946
  });
1934
1947
  this.connect(socket);
1935
1948
  }
1949
+ getSocketConfig() {
1950
+ const { reconnect } = this.callKit.config.getConfig();
1951
+ return {
1952
+ ...RECONNECT_CONFIG,
1953
+ ...reconnect
1954
+ };
1955
+ }
1956
+ setConnectAuthState(key, value) {
1957
+ if (this.connectAuthState[key] === value)
1958
+ return;
1959
+ this.connectAuthState[key] = value;
1960
+ }
1936
1961
  handleDisconnect() {
1937
- this.isConnected = false;
1938
- if (!this.callKit.config.isLogin() || !this.socketConfig.enabled) {
1939
- this.reset();
1962
+ this.setConnectAuthState("isConnected", false);
1963
+ const { enabled } = this.getSocketConfig();
1964
+ if (!this.callKit.config.isLogin() || !enabled) {
1965
+ this.callKit.reset();
1940
1966
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
1941
1967
  event: "INCALL_NOT_CONNECTED"
1942
1968
  });
1943
1969
  return;
1944
1970
  }
1945
- if (this.isReconnecting) {
1971
+ if (this.connectAuthState.isReconnecting) {
1946
1972
  return;
1947
1973
  }
1948
1974
  this.attemptReconnect();
@@ -1963,13 +1989,12 @@ var Socket = class {
1963
1989
  });
1964
1990
  }
1965
1991
  this.ws = void 0;
1966
- this.isConnected = false;
1992
+ this.setConnectAuthState("isConnected", false);
1967
1993
  }
1968
1994
  connect(socketUrl) {
1969
1995
  if (this.ws) {
1970
1996
  this.clearWebSocket();
1971
1997
  }
1972
- this.connectAttemptTimes.push(Date.now());
1973
1998
  this.ws = new WebSocket(socketUrl);
1974
1999
  this.ws.onopen = (ev) => this.onOpen(ev);
1975
2000
  this.ws.onclose = (ev) => this.onClose(ev);
@@ -1982,11 +2007,11 @@ var Socket = class {
1982
2007
  type: "INCALL",
1983
2008
  content: { ev }
1984
2009
  });
1985
- this.socketError = false;
1986
- this.isConnected = true;
2010
+ this.setConnectAuthState("isConnected", true);
1987
2011
  this.lastPingTime = Date.now();
1988
2012
  this.checkPing();
1989
- if (this.isReconnecting) {
2013
+ if (this.connectAuthState.isReconnecting) {
2014
+ this.setConnectAuthState("isReconnecting", false);
1990
2015
  this.callKit.logger.info("reconnect success", {
1991
2016
  caller: "Socket.onOpen",
1992
2017
  type: "INCALL",
@@ -1999,10 +2024,15 @@ var Socket = class {
1999
2024
  event: "INCALL_RECONNECT_SUCCESS"
2000
2025
  });
2001
2026
  }
2002
- this.resetReconnectState();
2003
2027
  }
2004
- resetReconnectState() {
2005
- this.isReconnecting = false;
2028
+ resetConnectState() {
2029
+ this.connectAuthState = {
2030
+ satrtConfirm: false,
2031
+ isConnected: false,
2032
+ isReconnecting: false,
2033
+ isAuthenticated: false,
2034
+ isError: false
2035
+ };
2006
2036
  this.reconnectAttempts = 0;
2007
2037
  if (this.reconnectTimer) {
2008
2038
  clearTimeout(this.reconnectTimer);
@@ -2015,13 +2045,9 @@ var Socket = class {
2015
2045
  type: "INCALL",
2016
2046
  content: { ev }
2017
2047
  });
2018
- if (this.socketError) {
2019
- return;
2020
- }
2021
2048
  this.handleDisconnect();
2022
2049
  }
2023
2050
  onError(ev) {
2024
- this.socketError = true;
2025
2051
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2026
2052
  event: "INCALL_CONNECT_ERROR",
2027
2053
  err: ev
@@ -2071,6 +2097,20 @@ var Socket = class {
2071
2097
  this.confirmAck(data);
2072
2098
  if (data.event === SocketReceiveEvent.PONG) {
2073
2099
  this.lastPingTime = Date.now();
2100
+ this.setConnectAuthState("isAuthenticated", true);
2101
+ this.callKit.logger.info("socket onMessage pong Authenticated", {
2102
+ caller: "Socket.onMessage",
2103
+ type: "INCALL",
2104
+ content: {
2105
+ data: content,
2106
+ event: SocketReceiveEvent.PONG,
2107
+ isAuthenticated: true
2108
+ }
2109
+ });
2110
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2111
+ event: "INCALL_AUTHENTICATED",
2112
+ isAuthenticated: true
2113
+ });
2074
2114
  return;
2075
2115
  }
2076
2116
  if (data.event === SocketReceiveEvent.START_CONFIRM) {
@@ -2082,7 +2122,7 @@ var Socket = class {
2082
2122
  event: SocketReceiveEvent.START_CONFIRM
2083
2123
  }
2084
2124
  });
2085
- this.satrtConfirm = true;
2125
+ this.setConnectAuthState("satrtConfirm", true);
2086
2126
  }
2087
2127
  if (data.event === SocketReceiveEvent.CALL_SUCCESS) {
2088
2128
  this.callKit.logger.info("call success", {
@@ -2196,12 +2236,10 @@ var Socket = class {
2196
2236
  event: SocketReceiveEvent.CLOSE
2197
2237
  }
2198
2238
  });
2199
- this.send(SocketSendEvent.END, {
2200
- agentId: userInfo.agentId
2201
- });
2239
+ this.send(SocketSendEvent.END, { agentId: userInfo.agentId });
2202
2240
  }
2203
2241
  if (data.event === SocketReceiveEvent.ERROR) {
2204
- this.socketError = true;
2242
+ this.setConnectAuthState("isError", true);
2205
2243
  this.callKit.reset();
2206
2244
  this.callKit.logger.error(data.msg, {
2207
2245
  caller: `Socket.onMessage:${data.event}`,
@@ -2213,7 +2251,7 @@ var Socket = class {
2213
2251
  });
2214
2252
  }
2215
2253
  if (data.event === SocketReceiveEvent.SESSION_ERROR) {
2216
- this.socketError = true;
2254
+ this.setConnectAuthState("isError", true);
2217
2255
  this.callKit.reset();
2218
2256
  this.callKit.logger.error(data.msg, {
2219
2257
  caller: `Socket.onMessage:${data.event}`,
@@ -2240,7 +2278,7 @@ var Socket = class {
2240
2278
  this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);
2241
2279
  }
2242
2280
  send(event, message) {
2243
- if (!this.isConnected) {
2281
+ if (!this.connectAuthState.isConnected) {
2244
2282
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2245
2283
  event: "INCALL_NOT_CONNECTED"
2246
2284
  });
@@ -2299,7 +2337,7 @@ var Socket = class {
2299
2337
  }
2300
2338
  }
2301
2339
  ping() {
2302
- if (!this.isConnected)
2340
+ if (!this.connectAuthState.isConnected)
2303
2341
  return;
2304
2342
  this.send(SocketSendEvent.PING);
2305
2343
  this.callKit.logger.info(`socket ping`, {
@@ -2310,12 +2348,12 @@ var Socket = class {
2310
2348
  }
2311
2349
  });
2312
2350
  const now = Date.now();
2313
- const { pingInterval, pingTimeout } = this.socketConfig;
2351
+ const { pingInterval, pingTimeout } = this.getSocketConfig();
2314
2352
  if (now - this.lastPingTime > pingInterval + pingTimeout) {
2315
- if (this.ws && this.isConnected) {
2353
+ if (this.ws && this.connectAuthState.isConnected) {
2316
2354
  this.ws.close(4001, "ping timeout");
2317
2355
  } else {
2318
- this.reset();
2356
+ this.callKit.reset();
2319
2357
  }
2320
2358
  this.callKit.logger.error("socket ping timeout", {
2321
2359
  caller: "Socket.ping",
@@ -2331,23 +2369,29 @@ var Socket = class {
2331
2369
  clearInterval(this.pingTimer);
2332
2370
  }
2333
2371
  this.ping();
2372
+ const { pingInterval } = this.getSocketConfig();
2334
2373
  this.pingTimer = setInterval(() => {
2335
2374
  this.ping();
2336
- }, this.socketConfig.pingInterval);
2375
+ }, pingInterval);
2337
2376
  }
2338
2377
  /**
2339
2378
  * reset socket connection and all states
2340
2379
  */
2341
- async reset() {
2380
+ async reset(config) {
2381
+ const { focus = false } = config || {};
2342
2382
  if (this.pingTimer) {
2343
2383
  clearInterval(this.pingTimer);
2344
2384
  this.pingTimer = void 0;
2345
2385
  }
2346
- this.resetReconnectState();
2386
+ if (focus) {
2387
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2388
+ event: "INCALL_RESET"
2389
+ });
2390
+ this.resetConnectState();
2391
+ this.setConnectAuthState("isConnected", false);
2392
+ }
2347
2393
  this.lastPingTime = void 0;
2348
- this.satrtConfirm = false;
2349
- this.socketError = false;
2350
- this.connectAttemptTimes = [];
2394
+ this.setConnectAuthState("satrtConfirm", false);
2351
2395
  this.clearWebSocket();
2352
2396
  }
2353
2397
  attemptReconnect() {
@@ -2355,34 +2399,12 @@ var Socket = class {
2355
2399
  clearTimeout(this.reconnectTimer);
2356
2400
  this.reconnectTimer = void 0;
2357
2401
  }
2358
- const { maxConnectsPerWindow, timeWindow } = this.socketConfig;
2359
- if (maxConnectsPerWindow && timeWindow) {
2360
- const now = Date.now();
2361
- this.connectAttemptTimes = this.connectAttemptTimes.filter(
2362
- (time) => now - time < timeWindow
2363
- );
2364
- if (this.connectAttemptTimes.length >= maxConnectsPerWindow) {
2365
- this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2366
- event: "INCALL_RECONNECT_ERROR"
2367
- });
2368
- this.callKit.logger.warn("Connection rate limit exceeded", {
2369
- caller: "Socket.attemptReconnect",
2370
- type: "INCALL",
2371
- content: {
2372
- errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
2373
- attempts: this.connectAttemptTimes.length,
2374
- maxConnectsPerWindow,
2375
- timeWindow
2376
- }
2377
- });
2378
- return;
2379
- }
2380
- }
2381
- if (this.reconnectAttempts >= this.socketConfig.maxAttempts) {
2402
+ const { maxAttempts } = this.getSocketConfig();
2403
+ if (this.reconnectAttempts >= maxAttempts) {
2382
2404
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2383
2405
  event: "INCALL_RECONNECT_ERROR"
2384
2406
  });
2385
- this.reset();
2407
+ this.callKit.reset();
2386
2408
  this.callKit.logger.error("Maximum reconnection attempts reached", {
2387
2409
  caller: "Socket.attemptReconnect",
2388
2410
  type: "INCALL",
@@ -2398,17 +2420,17 @@ var Socket = class {
2398
2420
  event: "INCALL_RECONNECT_START"
2399
2421
  });
2400
2422
  }
2401
- this.isReconnecting = true;
2423
+ this.setConnectAuthState("isReconnecting", true);
2402
2424
  this.reconnectAttempts += 1;
2403
- const { delay } = this.socketConfig;
2425
+ const { delay } = this.getSocketConfig();
2404
2426
  this.callKit.logger.info(
2405
- `Preparing reconnection attempt ${this.reconnectAttempts}/${this.socketConfig.maxAttempts}, delay: ${delay}ms`,
2427
+ `Preparing reconnection attempt ${this.reconnectAttempts}/${maxAttempts}, delay: ${delay}ms`,
2406
2428
  {
2407
2429
  caller: "Socket.attemptReconnect",
2408
2430
  type: "INCALL",
2409
2431
  content: {
2410
2432
  reconnectAttempts: this.reconnectAttempts,
2411
- maxAttempts: this.socketConfig.maxAttempts,
2433
+ maxAttempts,
2412
2434
  delay
2413
2435
  }
2414
2436
  }
@@ -2483,6 +2505,13 @@ var CallKit = class {
2483
2505
  encryptionPassword
2484
2506
  }
2485
2507
  });
2508
+ if (this.socket.isError) {
2509
+ this.logger.warn("socket is error", {
2510
+ caller: "CallKit.login",
2511
+ content: { username, password, extra, socketError: this.socket.isError }
2512
+ });
2513
+ return;
2514
+ }
2486
2515
  try {
2487
2516
  const user = await this.api.login({
2488
2517
  userName: username,
@@ -2534,7 +2563,7 @@ var CallKit = class {
2534
2563
  try {
2535
2564
  await this.api.loginOut({ sessionId });
2536
2565
  } catch (error) {
2537
- this.logger.error(error, {
2566
+ this.logger.warn(error, {
2538
2567
  caller: "CallKit.logout",
2539
2568
  content: {
2540
2569
  errCode: ErrorCode.API_USER_LOGOUT_ERROR
@@ -2610,9 +2639,6 @@ var CallKit = class {
2610
2639
  });
2611
2640
  this.connect.unregister();
2612
2641
  }
2613
- async stop() {
2614
- await this.connect.stop();
2615
- }
2616
2642
  async hangup() {
2617
2643
  if (!this.config.check())
2618
2644
  return;
@@ -2695,11 +2721,13 @@ var CallKit = class {
2695
2721
  userStatus: status
2696
2722
  });
2697
2723
  }
2698
- async reset() {
2724
+ async _reset(config) {
2725
+ const { focus = false } = config || {};
2699
2726
  this.logger.info("reset", {
2700
2727
  caller: "CallKit.reset",
2701
2728
  content: {
2702
- connectStatus: this.connect.connectStatus
2729
+ connectStatus: this.connect.connectStatus,
2730
+ focus
2703
2731
  }
2704
2732
  });
2705
2733
  if (this.connect.isCalling()) {
@@ -2710,7 +2738,14 @@ var CallKit = class {
2710
2738
  await this.logout({ isReset: false });
2711
2739
  }
2712
2740
  await this.config.reset();
2713
- await this.socket.reset();
2741
+ await this.socket.reset({ focus });
2742
+ }
2743
+ /**
2744
+ * reset callkit
2745
+ * @description recover the callkit to the initial state
2746
+ */
2747
+ async reset() {
2748
+ await this._reset({ focus: true });
2714
2749
  }
2715
2750
  on(event, callback) {
2716
2751
  this.listener.push({