@koi-design/callkit 2.0.5 → 2.1.0-beta.1

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
@@ -27,6 +27,11 @@ var Api = class {
27
27
  isLoginOuting = false;
28
28
  async login(params) {
29
29
  if (this.isLogining) {
30
+ this.callKit.logger.info("login is already in progress cancel", {
31
+ caller: "Api.login",
32
+ type: "API",
33
+ content: { userName: params.userName, timestamp: params.timestamp }
34
+ });
30
35
  return;
31
36
  }
32
37
  this.isLogining = true;
@@ -36,15 +41,18 @@ var Api = class {
36
41
  method: "post",
37
42
  data: params
38
43
  });
39
- this.isLogining = false;
40
44
  return res;
41
- } catch (error) {
45
+ } finally {
42
46
  this.isLogining = false;
43
- throw error;
44
47
  }
45
48
  }
46
49
  async loginOut(params) {
47
50
  if (this.isLoginOuting) {
51
+ this.callKit.logger.info("loginOut is already in progress cancel", {
52
+ type: "API",
53
+ caller: "Api.loginOut",
54
+ content: { sessionId: params.sessionId, timestamp: params.timestamp }
55
+ });
48
56
  return;
49
57
  }
50
58
  this.isLoginOuting = true;
@@ -54,20 +62,29 @@ var Api = class {
54
62
  method: "post",
55
63
  data: params
56
64
  });
57
- this.isLoginOuting = false;
58
65
  return res;
59
- } catch (error) {
66
+ } finally {
60
67
  this.isLoginOuting = false;
61
- throw error;
62
68
  }
63
69
  }
64
70
  async trackLogs(log) {
65
- return this.post(
66
- { url: "/agent/user/sdkLog", method: "post", data: { content: [log] } },
67
- {
68
- useFormData: true
69
- }
70
- );
71
+ try {
72
+ const { userInfo, host } = this.callKit.config.getConfig();
73
+ const { sessionId } = userInfo;
74
+ const formData = new FormData();
75
+ formData.append("content", JSON.stringify([log]));
76
+ const config = {
77
+ url: `${host}/agent/user/sdkLog`,
78
+ method: "post",
79
+ data: formData,
80
+ headers: {
81
+ ...sessionId ? { sessionId } : {}
82
+ }
83
+ };
84
+ await axios_default(config).catch(() => {
85
+ });
86
+ } catch (error) {
87
+ }
71
88
  }
72
89
  /**
73
90
  *
@@ -81,7 +98,7 @@ var Api = class {
81
98
  data: params
82
99
  });
83
100
  }
84
- async post(config, extra = {}) {
101
+ async post(config, extra = { skipLog: false }) {
85
102
  const { userInfo, host } = this.callKit.config.getConfig();
86
103
  const { sessionId } = userInfo;
87
104
  config.url = `${host}${config.url}`;
@@ -104,11 +121,37 @@ var Api = class {
104
121
  if (sessionId) {
105
122
  config.headers.sessionId = sessionId;
106
123
  }
124
+ const startTime = Date.now();
125
+ if (!extra.skipLog) {
126
+ this.callKit.logger.info("API Request Start", {
127
+ type: "API",
128
+ caller: "API.Request",
129
+ content: {
130
+ url: config.url,
131
+ headers: config.headers,
132
+ data: config.data,
133
+ extra,
134
+ startTime
135
+ }
136
+ });
137
+ }
107
138
  const res = await axios_default(config).catch(() => {
108
- this.callKit.config.reset();
139
+ this.callKit.config.reset("api request error");
109
140
  });
141
+ const endTime = Date.now();
142
+ if (!extra.skipLog) {
143
+ this.callKit.logger.info("API Request Finish", {
144
+ type: "API",
145
+ caller: "API.Request",
146
+ content: {
147
+ url: config.url,
148
+ duration: `${endTime - startTime}ms`,
149
+ response: res
150
+ }
151
+ });
152
+ }
110
153
  if (!res) {
111
- this.callKit.config.reset();
154
+ this.callKit.reset();
112
155
  throw new Error("Network error");
113
156
  }
114
157
  const { code, data, message } = res;
@@ -116,7 +159,7 @@ var Api = class {
116
159
  return data;
117
160
  }
118
161
  if (code === "100013") {
119
- this.callKit.config.reset();
162
+ this.callKit.config.reset("api request error");
120
163
  }
121
164
  throw new Error(message ?? "Request failed");
122
165
  }
@@ -429,6 +472,10 @@ var SocketReceiveEvent = {
429
472
  * Agent no answer
430
473
  */
431
474
  AGENT_NO_ANSWER: "AGENT_NO_ANSWER",
475
+ /**
476
+ * Agent hang up
477
+ */
478
+ AGENT_HANG_UP: "AGENT_HANG_UP",
432
479
  /**
433
480
  * Call detail record push
434
481
  */
@@ -445,7 +492,8 @@ var SocketReceiveEvent = {
445
492
  * Error
446
493
  */
447
494
  ERROR: "ERROR",
448
- SESSION_ERROR: "SESSION_ERROR"
495
+ SESSION_ERROR: "SESSION_ERROR",
496
+ WAITING_QUEUE: "WAITING_QUEUE"
449
497
  };
450
498
  var EncryptionMethod = {
451
499
  NONE: "NONE",
@@ -468,7 +516,19 @@ var CallSourceType = {
468
516
  var trackLogsDefaultConfig = {
469
517
  enabled: false,
470
518
  interval: 5e3,
471
- maxSize: 8192
519
+ maxSize: 4096
520
+ };
521
+ var SOCKET_RECONNECT_CONFIG = {
522
+ enabled: true,
523
+ maxAttempts: 3,
524
+ delay: 1e3,
525
+ pingInterval: 3e4,
526
+ pingTimeout: 5e3
527
+ };
528
+ var SIP_RECONNECT_CONFIG = {
529
+ enabled: true,
530
+ maxAttempts: 3,
531
+ delay: 1e3
472
532
  };
473
533
 
474
534
  // core/call.ts
@@ -483,14 +543,14 @@ var Call = class {
483
543
  this.callKit.logger.info("callStart", {
484
544
  caller: "Call.callStart",
485
545
  content: {
486
- startConfirm: this.callKit.socket.satrtConfirm
546
+ startConfirm: this.callKit.socket.startConfirm
487
547
  }
488
548
  });
489
- if (!this.callKit.socket.satrtConfirm) {
549
+ if (!this.callKit.socket.startConfirm) {
490
550
  this.callKit.logger.warn("server not confirm start", {
491
551
  caller: "Call.callStart",
492
552
  content: {
493
- startConfirm: this.callKit.socket.satrtConfirm
553
+ startConfirm: this.callKit.socket.startConfirm
494
554
  }
495
555
  });
496
556
  return;
@@ -612,14 +672,14 @@ var Call = class {
612
672
  // package.json
613
673
  var package_default = {
614
674
  name: "@koi-design/callkit",
615
- version: "2.0.5",
675
+ version: "2.1.0-beta.1",
616
676
  description: "callkit",
617
677
  author: "koi",
618
678
  license: "ISC",
619
679
  scripts: {
620
680
  build: "tsup",
621
- "build:w": "tsup --watch",
622
- dev: "vite",
681
+ start: "vite",
682
+ dev: "tsup --watch",
623
683
  lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
624
684
  release: "tsup && node scripts/pkg.js"
625
685
  },
@@ -676,6 +736,10 @@ var Config = class {
676
736
  audioRef: void 0,
677
737
  constrains: constrainsDefault,
678
738
  socket: "",
739
+ reconnect: {
740
+ sip: SIP_RECONNECT_CONFIG,
741
+ incall: SOCKET_RECONNECT_CONFIG
742
+ },
679
743
  userInfo: {
680
744
  wsUrl: "",
681
745
  logGather: false,
@@ -714,7 +778,12 @@ var Config = class {
714
778
  }
715
779
  });
716
780
  };
717
- reset = async () => {
781
+ reset = async (form) => {
782
+ this.callKit.logger.info(`Reset User Info ${form}`, {
783
+ caller: "Config.reset",
784
+ type: "OTHER",
785
+ content: {}
786
+ });
718
787
  if (this.isLogin()) {
719
788
  this.config.userInfo = {
720
789
  wsUrl: "",
@@ -760,7 +829,16 @@ var Config = class {
760
829
  return true;
761
830
  }
762
831
  getTrackLogsConfig() {
763
- return this.config?.trackLogs ?? trackLogsDefaultConfig;
832
+ return {
833
+ ...trackLogsDefaultConfig,
834
+ ...this.config?.trackLogs
835
+ };
836
+ }
837
+ getReconnectConfig(type) {
838
+ const config = this.config?.reconnect?.[type] ?? (type === "sip" ? SIP_RECONNECT_CONFIG : SOCKET_RECONNECT_CONFIG);
839
+ return {
840
+ ...config
841
+ };
764
842
  }
765
843
  enableTrackLogs(enabled) {
766
844
  this.config.trackLogs.enabled = enabled;
@@ -800,7 +878,7 @@ var Logger = class {
800
878
  this.flushTrackLogs();
801
879
  }, interval);
802
880
  }
803
- flushTrackLogs() {
881
+ async flushTrackLogs() {
804
882
  if (this.pendingTrackLogs.length === 0) {
805
883
  return;
806
884
  }
@@ -809,26 +887,29 @@ var Logger = class {
809
887
  try {
810
888
  const chunks = [];
811
889
  let currentChunk = [];
812
- let currentSize = 0;
813
890
  for (const log of this.pendingTrackLogs) {
814
- const logSize = getByteSize(log);
815
- const separator = currentChunk.length > 0 ? "\n" : "";
816
- const separatorSize = getByteSize(separator);
817
- if (currentSize + logSize + separatorSize > maxSize && currentChunk.length > 0) {
891
+ const testChunk = currentChunk.length > 0 ? `${currentChunk.join("\n")}
892
+ ${log}` : log;
893
+ const actualSize = getByteSize(JSON.stringify([testChunk]));
894
+ if (actualSize > maxSize && currentChunk.length > 0) {
818
895
  chunks.push(currentChunk.join("\n"));
819
896
  currentChunk = [log];
820
- currentSize = logSize;
821
897
  } else {
822
898
  currentChunk.push(log);
823
- currentSize += logSize + separatorSize;
824
899
  }
825
900
  }
826
901
  if (currentChunk.length > 0) {
827
902
  chunks.push(currentChunk.join("\n"));
828
903
  }
829
- for (const chunk of chunks) {
830
- this.callKit.api.trackLogs(chunk);
831
- }
904
+ await chunks.reduce(async (previousPromise, chunk, index) => {
905
+ await previousPromise;
906
+ if (index > 0) {
907
+ await new Promise((resolve) => {
908
+ setTimeout(resolve, 1e3);
909
+ });
910
+ }
911
+ await this.callKit.api.trackLogs(chunk);
912
+ }, Promise.resolve());
832
913
  this.pendingTrackLogs = [];
833
914
  } catch (error) {
834
915
  console.error(error);
@@ -886,16 +967,22 @@ var Logger = class {
886
967
  }
887
968
  catchLog(msg, extra, level) {
888
969
  const now = /* @__PURE__ */ new Date();
970
+ const { enabled } = this.callKit.config.getTrackLogsConfig();
971
+ const { userInfo } = this.callKit.config.getConfig();
972
+ const content = {
973
+ ...extra?.content ?? {},
974
+ agentId: userInfo?.agentId,
975
+ sessionId: userInfo?.sessionId
976
+ };
889
977
  const log = {
890
978
  timestamp: now.toLocaleString().replace("T", " ").replace(".000Z", ""),
891
979
  level,
892
980
  message: msg,
893
981
  caller: extra?.caller,
894
982
  type: extra?.type,
895
- content: extra?.content ?? {}
983
+ content
896
984
  };
897
985
  const logString = transformLog(log);
898
- const { enabled } = this.callKit.config.getTrackLogsConfig();
899
986
  if (enabled) {
900
987
  this.pendingTrackLogs.push(logString);
901
988
  }
@@ -929,11 +1016,6 @@ var formatGetInviteData = (inviteData) => {
929
1016
  };
930
1017
 
931
1018
  // core/connect.ts
932
- var DEFAULT_RECONNECT_CONFIG = {
933
- maxAttempts: 3,
934
- delay: 500
935
- };
936
- var MAX_HEARTBEAT_COUNT = 6;
937
1019
  function convertObjectStringToJSON(input) {
938
1020
  const corrected = input.replace(/(\w+):\s*'(.*?)'/g, '"$1": "$2"').replace(/'/g, '"');
939
1021
  return corrected;
@@ -964,10 +1046,6 @@ var initUserMedia = () => {
964
1046
  };
965
1047
  var Connect = class {
966
1048
  callKit;
967
- /**
968
- *@description Reconnect config
969
- */
970
- reconnectConfig;
971
1049
  /**
972
1050
  *@description Whether muted
973
1051
  */
@@ -992,6 +1070,10 @@ var Connect = class {
992
1070
  *@description Whether it's a re-connected
993
1071
  */
994
1072
  isReConnected = false;
1073
+ /**
1074
+ *@description Whether it's a referring
1075
+ */
1076
+ isRefering = false;
995
1077
  // sipConnected = false;
996
1078
  /**
997
1079
  *@description Whether it's an outgoing call
@@ -1007,14 +1089,48 @@ var Connect = class {
1007
1089
  hasInvite = false;
1008
1090
  constructor(callKit) {
1009
1091
  this.callKit = callKit;
1010
- const { reconnect = {} } = this.callKit.config.getConfig();
1011
- this.reconnectConfig = {
1012
- ...DEFAULT_RECONNECT_CONFIG,
1013
- ...reconnect
1014
- };
1092
+ }
1093
+ get reconnectConfig() {
1094
+ return this.callKit.config.getReconnectConfig("sip");
1015
1095
  }
1016
1096
  // current call id for invite data
1017
1097
  currentCallId = null;
1098
+ getCurrentCallId() {
1099
+ return this.currentCallId;
1100
+ }
1101
+ setRefering(refering) {
1102
+ if (this.isRefering === refering)
1103
+ return;
1104
+ this.callKit.logger.info("setRefering", {
1105
+ caller: "Connect.setRefering",
1106
+ content: {
1107
+ refering
1108
+ }
1109
+ });
1110
+ this.isRefering = refering;
1111
+ }
1112
+ setIsReConnected(isReConnected) {
1113
+ if (this.isReConnected === isReConnected)
1114
+ return;
1115
+ this.callKit.logger.info("setIsReConnected", {
1116
+ caller: "Connect.setIsReConnected",
1117
+ content: {
1118
+ isReConnected
1119
+ }
1120
+ });
1121
+ this.isReConnected = isReConnected;
1122
+ }
1123
+ setOutgoing(outgoing) {
1124
+ if (this.isOutgoing === outgoing)
1125
+ return;
1126
+ this.callKit.logger.info("setOutgoing", {
1127
+ caller: "Connect.setOutgoing",
1128
+ content: {
1129
+ outgoing
1130
+ }
1131
+ });
1132
+ this.isOutgoing = outgoing;
1133
+ }
1018
1134
  setCallId(callId) {
1019
1135
  this.callKit.logger.info("setCallId", {
1020
1136
  caller: "Connect.setCallId",
@@ -1026,6 +1142,15 @@ var Connect = class {
1026
1142
  this.callKit.trigger(KitEvent.KIT_CALL_ID_CHANGE, callId);
1027
1143
  }
1028
1144
  async reset() {
1145
+ this.setOutgoing(false);
1146
+ this.isUnprompted = false;
1147
+ this.hasInvite = false;
1148
+ if (this.isRefering) {
1149
+ this.setRefering(false);
1150
+ }
1151
+ if (this.isReConnected) {
1152
+ this.setIsReConnected(false);
1153
+ }
1029
1154
  if (this.isHolding()) {
1030
1155
  await this.setHold(false);
1031
1156
  }
@@ -1045,9 +1170,6 @@ var Connect = class {
1045
1170
  this.mediaStream = void 0;
1046
1171
  this.userAgent = void 0;
1047
1172
  this.registerer = void 0;
1048
- this.isOutgoing = false;
1049
- this.isUnprompted = false;
1050
- this.hasInvite = false;
1051
1173
  if (this.mediaStream) {
1052
1174
  try {
1053
1175
  closeStream(this.mediaStream);
@@ -1064,7 +1186,6 @@ var Connect = class {
1064
1186
  }
1065
1187
  }
1066
1188
  this.setConnectStatus(CallStatus.init);
1067
- this.clearHeartbeat();
1068
1189
  }
1069
1190
  getAduioReference() {
1070
1191
  const { audioRef } = this.callKit.config.getConfig();
@@ -1129,28 +1250,6 @@ var Connect = class {
1129
1250
  isInit() {
1130
1251
  return this.connectStatus === CallStatus.init;
1131
1252
  }
1132
- heartbeatInterval;
1133
- heartbeatFlag = MAX_HEARTBEAT_COUNT;
1134
- clearHeartbeat() {
1135
- if (this.heartbeatInterval) {
1136
- clearInterval(this.heartbeatInterval);
1137
- this.heartbeatInterval = null;
1138
- }
1139
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1140
- }
1141
- startHeartbeat() {
1142
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1143
- this.clearHeartbeat();
1144
- this.heartbeatInterval = setInterval(() => {
1145
- this.heartbeatFlag -= 1;
1146
- if (this.heartbeatFlag <= 0) {
1147
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1148
- this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
1149
- event: "OPTIONS_HEARTBEAT_EXPIRED"
1150
- });
1151
- }
1152
- }, 1e3);
1153
- }
1154
1253
  socketTriggerHangup(callId) {
1155
1254
  if (!this.isCalling() || callId !== this.currentCallId)
1156
1255
  return;
@@ -1163,6 +1262,136 @@ var Connect = class {
1163
1262
  });
1164
1263
  this.callKit.hangup();
1165
1264
  }
1265
+ /**
1266
+ * Setup registerer and bind stateChange listener
1267
+ * @private
1268
+ */
1269
+ setupRegisterer() {
1270
+ if (!this.userAgent) {
1271
+ this.callKit.logger.warn("userAgent is not initialized", {
1272
+ caller: "Connect.setupRegisterer",
1273
+ content: {
1274
+ errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR
1275
+ }
1276
+ });
1277
+ return;
1278
+ }
1279
+ const { userInfo } = this.callKit.config.getConfig();
1280
+ const { userPart, fsIp, fsPort } = userInfo;
1281
+ const registererOptions = {};
1282
+ this.registerer = new Registerer(this.userAgent, registererOptions);
1283
+ this.registerer.stateChange.addListener((state) => {
1284
+ switch (state) {
1285
+ case RegistererState.Initial:
1286
+ this.callKit.logger.info("registerer stateChange Initial", {
1287
+ caller: "Connect.setupRegisterer.registererStateChange",
1288
+ type: "SIP",
1289
+ content: {
1290
+ registererState: state,
1291
+ isRegistered: this.isRegistered()
1292
+ }
1293
+ });
1294
+ this.setRegister(false);
1295
+ this.setConnectStatus(CallStatus.init);
1296
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1297
+ registererState: state,
1298
+ isRegistered: this.isRegistered()
1299
+ });
1300
+ break;
1301
+ case RegistererState.Registered:
1302
+ this.callKit.logger.info("registerer stateChange Registered", {
1303
+ caller: "Connect.setupRegisterer.registererStateChange",
1304
+ type: "SIP",
1305
+ content: {
1306
+ registererState: state,
1307
+ isRegistered: this.isRegistered()
1308
+ }
1309
+ });
1310
+ this.setRegister(true);
1311
+ if (this.isReConnected) {
1312
+ if (this.currentSession && (this.currentSession.state === SessionState.Established || this.currentSession.state === SessionState.Establishing) && this.isCalling()) {
1313
+ const selfUri = `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
1314
+ this.callKit.logger.info(
1315
+ "Reconnected, referring active session to self",
1316
+ {
1317
+ caller: "Connect.setupRegisterer.registererStateChange",
1318
+ type: "SIP",
1319
+ content: {
1320
+ selfUri,
1321
+ sessionState: this.currentSession.state,
1322
+ connectStatus: this.connectStatus
1323
+ }
1324
+ }
1325
+ );
1326
+ this.refer(selfUri).catch((err) => {
1327
+ this.callKit.logger.error(err, {
1328
+ caller: "Connect.setupRegisterer.registererStateChange",
1329
+ type: "SIP",
1330
+ content: {
1331
+ errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
1332
+ selfUri
1333
+ }
1334
+ });
1335
+ });
1336
+ } else {
1337
+ this.callKit.logger.warn(
1338
+ "Reconnected but no active session to refer",
1339
+ {
1340
+ caller: "Connect.setupRegisterer.registererStateChange",
1341
+ type: "SIP",
1342
+ content: {
1343
+ hasCurrentSession: !!this.currentSession,
1344
+ sessionState: this.currentSession?.state,
1345
+ connectStatus: this.connectStatus,
1346
+ isCalling: this.isCalling()
1347
+ }
1348
+ }
1349
+ );
1350
+ }
1351
+ this.setIsReConnected(false);
1352
+ }
1353
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1354
+ registererState: state,
1355
+ isRegistered: this.isRegistered()
1356
+ });
1357
+ break;
1358
+ case RegistererState.Terminated:
1359
+ this.callKit.logger.info("registerer stateChange Terminated", {
1360
+ caller: "Connect.setupRegisterer.registererStateChange",
1361
+ type: "SIP",
1362
+ content: {
1363
+ registererState: state,
1364
+ isRegistered: this.isRegistered()
1365
+ }
1366
+ });
1367
+ this.setRegister(false);
1368
+ this.setConnectStatus(CallStatus.init);
1369
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1370
+ registererState: state,
1371
+ isRegistered: this.isRegistered()
1372
+ });
1373
+ break;
1374
+ case RegistererState.Unregistered:
1375
+ this.callKit.logger.info("registerer stateChange Unregistered", {
1376
+ caller: "Connect.setupRegisterer.registererStateChange",
1377
+ type: "SIP",
1378
+ content: {
1379
+ isRegistered: this.isRegistered(),
1380
+ registererState: state
1381
+ }
1382
+ });
1383
+ this.setRegister(false);
1384
+ this.setConnectStatus(CallStatus.init);
1385
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1386
+ registererState: state,
1387
+ isRegistered: this.isRegistered()
1388
+ });
1389
+ break;
1390
+ default:
1391
+ break;
1392
+ }
1393
+ });
1394
+ }
1166
1395
  async register() {
1167
1396
  if (this.connectStatus !== CallStatus.init) {
1168
1397
  if (this.isRegistered()) {
@@ -1264,9 +1493,6 @@ var Connect = class {
1264
1493
  const core = userAgent.userAgentCore;
1265
1494
  const originalReceiveIncomingRequestFromTransport = core.receiveIncomingRequestFromTransport.bind(core);
1266
1495
  core.receiveIncomingRequestFromTransport = (request2) => {
1267
- if (request2.method === "OPTIONS") {
1268
- that.startHeartbeat();
1269
- }
1270
1496
  that.callKit.logger.info(`SIP Receive: ${request2?.method}`, {
1271
1497
  caller: "Connect.register.observeSocketStatus.receiveRequest",
1272
1498
  type: "SIP",
@@ -1276,6 +1502,20 @@ var Connect = class {
1276
1502
  });
1277
1503
  return originalReceiveIncomingRequestFromTransport(request2);
1278
1504
  };
1505
+ const originalReceiveIncomingResponseFromTransport = core.receiveIncomingResponseFromTransport.bind(core);
1506
+ core.receiveIncomingResponseFromTransport = (response) => {
1507
+ that.callKit.logger.info(
1508
+ `SIP Receive Response: ${response?.statusCode} ${response?.reasonPhrase}`,
1509
+ {
1510
+ caller: "Connect.register.observeSocketStatus.receiveResponse",
1511
+ type: "SIP",
1512
+ content: {
1513
+ response
1514
+ }
1515
+ }
1516
+ );
1517
+ return originalReceiveIncomingResponseFromTransport(response);
1518
+ };
1279
1519
  const { transport } = userAgent;
1280
1520
  if (transport) {
1281
1521
  const originalSend = transport.send.bind(transport);
@@ -1291,77 +1531,7 @@ var Connect = class {
1291
1531
  };
1292
1532
  }
1293
1533
  };
1294
- const registererOptions = {};
1295
- this.registerer = new Registerer(this.userAgent, registererOptions);
1296
- this.registerer.stateChange.addListener((state) => {
1297
- switch (state) {
1298
- case RegistererState.Initial:
1299
- this.callKit.logger.info("registerer stateChange Initial", {
1300
- caller: "Connect.register.registererStateChange",
1301
- type: "SIP",
1302
- content: {
1303
- registererState: state,
1304
- isRegistered: this.isRegistered()
1305
- }
1306
- });
1307
- this.setRegister(false);
1308
- this.setConnectStatus(CallStatus.init);
1309
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1310
- registererState: state,
1311
- isRegistered: this.isRegistered()
1312
- });
1313
- break;
1314
- case RegistererState.Registered:
1315
- this.callKit.logger.info("registerer stateChange Registered", {
1316
- caller: "Connect.register.registererStateChange",
1317
- type: "SIP",
1318
- content: {
1319
- registererState: state,
1320
- isRegistered: this.isRegistered()
1321
- }
1322
- });
1323
- this.setRegister(true);
1324
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1325
- registererState: state,
1326
- isRegistered: this.isRegistered()
1327
- });
1328
- break;
1329
- case RegistererState.Terminated:
1330
- this.callKit.logger.info("registerer stateChange Terminated", {
1331
- caller: "Connect.register.registererStateChange",
1332
- type: "SIP",
1333
- content: {
1334
- registererState: state,
1335
- isRegistered: this.isRegistered()
1336
- }
1337
- });
1338
- this.setRegister(false);
1339
- this.setConnectStatus(CallStatus.init);
1340
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1341
- registererState: state,
1342
- isRegistered: this.isRegistered()
1343
- });
1344
- break;
1345
- case RegistererState.Unregistered:
1346
- this.callKit.logger.info("registerer stateChange Unregistered", {
1347
- caller: "Connect.register.registererStateChange",
1348
- type: "SIP",
1349
- content: {
1350
- isRegistered: this.isRegistered(),
1351
- registererState: state
1352
- }
1353
- });
1354
- this.setRegister(false);
1355
- this.setConnectStatus(CallStatus.init);
1356
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1357
- registererState: state,
1358
- isRegistered: this.isRegistered()
1359
- });
1360
- break;
1361
- default:
1362
- break;
1363
- }
1364
- });
1534
+ this.setupRegisterer();
1365
1535
  this.userAgent.delegate = {
1366
1536
  onInvite: (invite) => {
1367
1537
  this.callKit.logger.info("connect onInvite", {
@@ -1369,7 +1539,8 @@ var Connect = class {
1369
1539
  caller: "Connect.register.onInvite",
1370
1540
  content: {
1371
1541
  invite,
1372
- isRegistered: this.isRegistered()
1542
+ isRegistered: this.isRegistered(),
1543
+ isOutgoing: this.isOutgoing
1373
1544
  }
1374
1545
  });
1375
1546
  this.currentSession = invite;
@@ -1447,7 +1618,9 @@ var Connect = class {
1447
1618
  });
1448
1619
  this.callKit.logger.info("get invite data", {
1449
1620
  caller: "Connect.register.onInvite",
1450
- content: xHeaders
1621
+ content: {
1622
+ headers: xHeaders
1623
+ }
1451
1624
  });
1452
1625
  return xHeaders;
1453
1626
  };
@@ -1468,9 +1641,16 @@ var Connect = class {
1468
1641
  } catch (error) {
1469
1642
  this.callKit.logger.info(error, {
1470
1643
  caller: "Connect.register.onInvite",
1471
- content: info
1644
+ content: {
1645
+ headers: info
1646
+ }
1472
1647
  });
1473
1648
  }
1649
+ if (this.isRefering) {
1650
+ this.currentSession.accept(options);
1651
+ this.setRefering(false);
1652
+ return;
1653
+ }
1474
1654
  if (this.isOutgoing) {
1475
1655
  this.currentSession.accept(options);
1476
1656
  this.callKit.trigger(KitEvent.KIT_OUTGOING_INVITE, {
@@ -1506,9 +1686,8 @@ var Connect = class {
1506
1686
  version: `${this.callKit.config.getConfig().version}`
1507
1687
  }
1508
1688
  });
1509
- await this.registerer.register().then(() => {
1510
- this.callKit.socket.send(SocketSendEvent.START);
1511
- }).catch(async (err) => {
1689
+ this.setupRegisterer();
1690
+ await this.registerer.register().catch(async (err) => {
1512
1691
  this.callKit.reset();
1513
1692
  this.callKit.logger.error(err?.message, {
1514
1693
  caller: "Connect.register",
@@ -1520,9 +1699,8 @@ var Connect = class {
1520
1699
  });
1521
1700
  },
1522
1701
  onDisconnect: (error) => {
1523
- console.log("onDisconnect", error);
1524
1702
  if (error) {
1525
- this.callKit.logger.info("SIP User Agent Disconnected with error", {
1703
+ this.callKit.logger.warn("SIP User Agent Disconnected with error", {
1526
1704
  caller: "Connect.register",
1527
1705
  type: "SIP",
1528
1706
  content: {
@@ -1532,21 +1710,12 @@ var Connect = class {
1532
1710
  });
1533
1711
  this.startReconnectTimer();
1534
1712
  } else {
1535
- this.callKit.logger.info("SIP User Agent Disconnected", {
1713
+ this.callKit.logger.warn("SIP User Agent Disconnected", {
1536
1714
  caller: "Connect.register",
1537
1715
  type: "SIP",
1538
1716
  content: {}
1539
1717
  });
1540
1718
  }
1541
- },
1542
- onRegister: () => {
1543
- this.callKit.logger.info("connect onRegister", {
1544
- caller: "Connect.register",
1545
- type: "SIP",
1546
- content: {
1547
- version: `V${this.callKit.config.getConfig().version}`
1548
- }
1549
- });
1550
1719
  }
1551
1720
  };
1552
1721
  observeSocketStatus(this.userAgent, {
@@ -1592,6 +1761,7 @@ var Connect = class {
1592
1761
  this.reconnectTimer = setTimeout(() => {
1593
1762
  if (this.reconnectTimer && this.callKit.config.isLogin()) {
1594
1763
  this.userAgent?.reconnect();
1764
+ this.setIsReConnected(true);
1595
1765
  this.callKit.logger.info("Reconnect attempt", {
1596
1766
  caller: "Connect.startReconnectTimer",
1597
1767
  type: "SIP",
@@ -1636,14 +1806,15 @@ var Connect = class {
1636
1806
  return;
1637
1807
  }
1638
1808
  await this.registerer.unregister({ all: true }).catch((err) => {
1639
- this.callKit.reset();
1640
- this.callKit.logger.error(err, {
1809
+ this.callKit.logger.warn(err, {
1641
1810
  caller: "Connect.unregister",
1642
1811
  type: "SIP",
1643
1812
  content: {
1644
1813
  errCode: ErrorCode.WEBRTC_CANCEL_REGISTER_ERROR
1645
1814
  }
1646
1815
  });
1816
+ }).finally(() => {
1817
+ this.setRegister(false);
1647
1818
  });
1648
1819
  await this.userAgent?.stop().catch((err) => {
1649
1820
  this.callKit.logger.warn(err, {
@@ -1656,20 +1827,20 @@ var Connect = class {
1656
1827
  });
1657
1828
  }
1658
1829
  async call(callback) {
1659
- this.callKit.logger.info("connect call", {
1660
- caller: "Connect.call",
1661
- type: "SIP",
1662
- content: {
1663
- callback
1664
- }
1665
- });
1666
- this.isOutgoing = true;
1830
+ this.setOutgoing(true);
1667
1831
  if (!this.isRegistered()) {
1668
1832
  await this.register();
1669
1833
  }
1670
1834
  this.setConnectStatus(CallStatus.connecting);
1671
1835
  this.callKit.trigger(KitEvent.CALL_CONNECTING, /* @__PURE__ */ new Date());
1672
1836
  const { userInfo } = this.callKit.config.getConfig();
1837
+ this.callKit.logger.info("connect call", {
1838
+ caller: "Connect.call",
1839
+ type: "SIP",
1840
+ content: {
1841
+ userInfo
1842
+ }
1843
+ });
1673
1844
  callback(userInfo);
1674
1845
  }
1675
1846
  /**
@@ -1677,6 +1848,8 @@ var Connect = class {
1677
1848
  * @param register
1678
1849
  */
1679
1850
  setRegister(register) {
1851
+ if (this.isRegister === register)
1852
+ return;
1680
1853
  this.callKit.logger.info("connect setRegister", {
1681
1854
  caller: "Connect.setRegister",
1682
1855
  type: "SIP",
@@ -1718,7 +1891,7 @@ var Connect = class {
1718
1891
  connectStatus: this.connectStatus
1719
1892
  }
1720
1893
  });
1721
- this.isOutgoing = false;
1894
+ this.setOutgoing(false);
1722
1895
  this.isUnprompted = isUnprompted;
1723
1896
  this.setHold(false);
1724
1897
  this.setMute(false);
@@ -1746,6 +1919,7 @@ var Connect = class {
1746
1919
  }
1747
1920
  this.setConnectStatus(CallStatus.init);
1748
1921
  this.callKit.trigger(KitEvent.CALL_END, /* @__PURE__ */ new Date());
1922
+ this.setCallId(null);
1749
1923
  } catch (err) {
1750
1924
  this.callKit.trigger(KitEvent.CALL_END, /* @__PURE__ */ new Date());
1751
1925
  this.callKit.reset();
@@ -1872,12 +2046,26 @@ var Connect = class {
1872
2046
  this.callKit.trigger(KitEvent.KIT_SET_MUTE, mute);
1873
2047
  }
1874
2048
  async refer(referTo, extra) {
2049
+ if (!this.currentSession) {
2050
+ const errorMsg = "Cannot refer: currentSession is not available";
2051
+ this.callKit.logger.warn(errorMsg, {
2052
+ caller: "Connect.refer",
2053
+ type: "SIP",
2054
+ content: {
2055
+ errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
2056
+ referTo
2057
+ }
2058
+ });
2059
+ return;
2060
+ }
2061
+ this.setRefering(true);
1875
2062
  this.callKit.logger.info("connect refer", {
1876
2063
  caller: "Connect.refer",
1877
2064
  type: "SIP",
1878
2065
  content: {
1879
2066
  referTo,
1880
- extra
2067
+ extra,
2068
+ sessionState: this.currentSession.state
1881
2069
  }
1882
2070
  });
1883
2071
  let target;
@@ -1889,13 +2077,7 @@ var Connect = class {
1889
2077
  };
1890
2078
 
1891
2079
  // core/socket.ts
1892
- var RECONNECT_CONFIG = {
1893
- enabled: true,
1894
- maxAttempts: 3,
1895
- delay: 1e3,
1896
- pingInterval: 3e4,
1897
- pingTimeout: 5e3
1898
- };
2080
+ var EXCLUDE_LOG_EVENTS = [SocketReceiveEvent.WAITING_QUEUE];
1899
2081
  var Socket = class {
1900
2082
  callKit;
1901
2083
  ws;
@@ -1912,7 +2094,7 @@ var Socket = class {
1912
2094
  /**
1913
2095
  * @description connect auth state
1914
2096
  * @default {
1915
- * satrtConfirm: false,
2097
+ * startConfirm: false,
1916
2098
  * isConnected: false,
1917
2099
  * isReconnecting: false,
1918
2100
  * isAuthenticated: false,
@@ -1920,14 +2102,13 @@ var Socket = class {
1920
2102
  * }
1921
2103
  */
1922
2104
  connectAuthState = {
1923
- satrtConfirm: false,
2105
+ startConfirm: false,
1924
2106
  isConnected: false,
1925
2107
  isReconnecting: false,
1926
- isAuthenticated: false,
1927
2108
  isError: false
1928
2109
  };
1929
- get satrtConfirm() {
1930
- return this.connectAuthState.satrtConfirm;
2110
+ get startConfirm() {
2111
+ return this.connectAuthState.startConfirm;
1931
2112
  }
1932
2113
  get isError() {
1933
2114
  return this.connectAuthState.isError;
@@ -1935,6 +2116,9 @@ var Socket = class {
1935
2116
  constructor(callKit) {
1936
2117
  this.callKit = callKit;
1937
2118
  }
2119
+ get reconnectConfig() {
2120
+ return this.callKit.config.getReconnectConfig("incall");
2121
+ }
1938
2122
  init() {
1939
2123
  const { socket } = this.callKit.config.getConfig();
1940
2124
  this.callKit.logger.info(`socket init: ${socket}`, {
@@ -1946,13 +2130,6 @@ var Socket = class {
1946
2130
  });
1947
2131
  this.connect(socket);
1948
2132
  }
1949
- getSocketConfig() {
1950
- const { reconnect } = this.callKit.config.getConfig();
1951
- return {
1952
- ...RECONNECT_CONFIG,
1953
- ...reconnect
1954
- };
1955
- }
1956
2133
  setConnectAuthState(key, value) {
1957
2134
  if (this.connectAuthState[key] === value)
1958
2135
  return;
@@ -1960,7 +2137,7 @@ var Socket = class {
1960
2137
  }
1961
2138
  handleDisconnect() {
1962
2139
  this.setConnectAuthState("isConnected", false);
1963
- const { enabled } = this.getSocketConfig();
2140
+ const { enabled } = this.reconnectConfig;
1964
2141
  if (!this.callKit.config.isLogin() || !enabled) {
1965
2142
  this.callKit.reset();
1966
2143
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
@@ -1971,6 +2148,9 @@ var Socket = class {
1971
2148
  if (this.connectAuthState.isReconnecting) {
1972
2149
  return;
1973
2150
  }
2151
+ if (this.connectAuthState.isError) {
2152
+ return;
2153
+ }
1974
2154
  this.attemptReconnect();
1975
2155
  }
1976
2156
  clearWebSocket() {
@@ -2010,6 +2190,7 @@ var Socket = class {
2010
2190
  this.setConnectAuthState("isConnected", true);
2011
2191
  this.lastPingTime = Date.now();
2012
2192
  this.checkPing();
2193
+ this.send(SocketSendEvent.START);
2013
2194
  if (this.connectAuthState.isReconnecting) {
2014
2195
  this.setConnectAuthState("isReconnecting", false);
2015
2196
  this.callKit.logger.info("reconnect success", {
@@ -2025,19 +2206,31 @@ var Socket = class {
2025
2206
  });
2026
2207
  }
2027
2208
  }
2209
+ cleanReconnectState() {
2210
+ this.reconnectAttempts = 0;
2211
+ if (this.reconnectTimer) {
2212
+ clearTimeout(this.reconnectTimer);
2213
+ this.reconnectTimer = void 0;
2214
+ }
2215
+ this.setConnectAuthState("isReconnecting", false);
2216
+ this.setConnectAuthState("isError", false);
2217
+ }
2028
2218
  resetConnectState() {
2029
2219
  this.connectAuthState = {
2030
- satrtConfirm: false,
2220
+ startConfirm: false,
2031
2221
  isConnected: false,
2032
2222
  isReconnecting: false,
2033
- isAuthenticated: false,
2034
2223
  isError: false
2035
2224
  };
2036
- this.reconnectAttempts = 0;
2037
- if (this.reconnectTimer) {
2038
- clearTimeout(this.reconnectTimer);
2039
- this.reconnectTimer = void 0;
2040
- }
2225
+ this.cleanReconnectState();
2226
+ this.callKit.logger.info("reset connect state", {
2227
+ caller: "Socket.resetConnectState",
2228
+ type: "INCALL",
2229
+ content: {
2230
+ reconnectAttempts: this.reconnectAttempts,
2231
+ connectAuthState: this.connectAuthState
2232
+ }
2233
+ });
2041
2234
  }
2042
2235
  onClose(ev) {
2043
2236
  this.callKit.logger.info("socket onClose", {
@@ -2071,9 +2264,9 @@ var Socket = class {
2071
2264
  }
2072
2265
  onMessage(ev) {
2073
2266
  const data = JSON.parse(ev.data);
2074
- let content = {};
2267
+ let content = data.data;
2075
2268
  try {
2076
- if (data.data) {
2269
+ if (typeof data.data === "string" && data.data) {
2077
2270
  content = JSON.parse(data.data);
2078
2271
  }
2079
2272
  } catch (error) {
@@ -2084,159 +2277,73 @@ var Socket = class {
2084
2277
  data: data.data
2085
2278
  }
2086
2279
  });
2087
- content = data.data;
2088
2280
  }
2089
- this.callKit.logger.info("socket onMessage", {
2090
- caller: "Socket.onMessage",
2091
- type: "INCALL",
2092
- content: {
2093
- data: content,
2094
- event: data.event
2095
- }
2096
- });
2097
- this.confirmAck(data);
2098
- if (data.event === SocketReceiveEvent.PONG) {
2099
- this.lastPingTime = Date.now();
2100
- this.setConnectAuthState("isAuthenticated", true);
2101
- this.callKit.logger.info("socket onMessage pong Authenticated", {
2281
+ if (!EXCLUDE_LOG_EVENTS.includes(data.event)) {
2282
+ this.callKit.logger.info(`socket onMessage: ${data.event}`, {
2102
2283
  caller: "Socket.onMessage",
2103
2284
  type: "INCALL",
2104
2285
  content: {
2105
2286
  data: content,
2106
- event: SocketReceiveEvent.PONG,
2107
- isAuthenticated: true
2287
+ event: data.event
2108
2288
  }
2109
2289
  });
2110
- this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2111
- event: "INCALL_AUTHENTICATED",
2112
- isAuthenticated: true
2113
- });
2290
+ }
2291
+ this.confirmAck(data);
2292
+ const callUuid = content?.callUuid || "";
2293
+ if (data.event === SocketReceiveEvent.PONG) {
2294
+ this.lastPingTime = Date.now();
2114
2295
  return;
2115
2296
  }
2116
2297
  if (data.event === SocketReceiveEvent.START_CONFIRM) {
2117
- this.callKit.logger.info("start confirm success", {
2118
- caller: "Socket.onMessage",
2119
- type: "INCALL",
2120
- content: {
2121
- data: content,
2122
- event: SocketReceiveEvent.START_CONFIRM
2123
- }
2124
- });
2125
- this.setConnectAuthState("satrtConfirm", true);
2126
- }
2127
- if (data.event === SocketReceiveEvent.CALL_SUCCESS) {
2128
- this.callKit.logger.info("call success", {
2129
- caller: "Socket.onMessage",
2130
- type: "INCALL",
2131
- content: {
2132
- data: content,
2133
- event: SocketReceiveEvent.CALL_SUCCESS
2134
- }
2135
- });
2136
- }
2137
- if (data.event === SocketReceiveEvent.CALL_FAILED) {
2138
- this.callKit.logger.info(data.msg, {
2139
- caller: "Socket.onMessage",
2140
- type: "INCALL",
2141
- content: {
2142
- data: content,
2143
- errCode: ErrorCode.SOCKET_CALL_ERROR
2144
- }
2145
- });
2298
+ this.setConnectAuthState("startConfirm", true);
2299
+ this.cleanReconnectState();
2146
2300
  }
2147
2301
  if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {
2148
- this.callKit.trigger(KitEvent.CALL_RINGING, /* @__PURE__ */ new Date());
2149
- this.callKit.logger.info(data.msg, {
2150
- caller: `Socket.onMessage:${data.event}`,
2151
- type: "INCALL",
2152
- content: {
2153
- data: content,
2154
- event: SocketReceiveEvent.CUSTOMER_RINGING
2155
- }
2302
+ this.callKit.trigger(KitEvent.CALL_RINGING, {
2303
+ time: /* @__PURE__ */ new Date(),
2304
+ callUuid
2156
2305
  });
2157
2306
  }
2158
2307
  if (data.event === SocketReceiveEvent.CUSTOMER_PICK_UP) {
2159
- this.callKit.logger.info(data.msg, {
2160
- caller: "Socket.onMessage",
2161
- type: "INCALL",
2162
- content: {
2163
- data: content,
2164
- event: SocketReceiveEvent.CUSTOMER_PICK_UP
2165
- }
2308
+ this.callKit.trigger(KitEvent.CALL_PICK_UP, {
2309
+ time: /* @__PURE__ */ new Date(),
2310
+ callUuid
2166
2311
  });
2167
- this.callKit.trigger(KitEvent.CALL_PICK_UP, /* @__PURE__ */ new Date());
2168
2312
  }
2169
2313
  if (data.event === SocketReceiveEvent.AGENT_PICK_UP) {
2170
- this.callKit.logger.info(data.msg, {
2171
- caller: "Socket.onMessage",
2172
- type: "INCALL",
2173
- content: {
2174
- data: content,
2175
- event: SocketReceiveEvent.AGENT_PICK_UP
2176
- }
2314
+ this.callKit.trigger(KitEvent.AGENT_PICK_UP, {
2315
+ time: /* @__PURE__ */ new Date(),
2316
+ callUuid
2177
2317
  });
2178
- this.callKit.trigger(KitEvent.AGENT_PICK_UP, /* @__PURE__ */ new Date());
2179
2318
  }
2180
2319
  if (data.event === SocketReceiveEvent.CUSTOMER_HANG_UP) {
2181
- this.callKit.logger.info(data.msg, {
2182
- caller: `Socket.onMessage:${data.event}`,
2183
- type: "INCALL",
2184
- content: {
2185
- data: content,
2186
- event: SocketReceiveEvent.CUSTOMER_HANG_UP
2187
- }
2320
+ this.callKit.trigger(KitEvent.CALL_HANG_UP, {
2321
+ time: /* @__PURE__ */ new Date(),
2322
+ callUuid
2188
2323
  });
2189
- this.callKit.trigger(KitEvent.CALL_HANG_UP, /* @__PURE__ */ new Date());
2190
- if (content?.callUuid) {
2191
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2324
+ if (callUuid) {
2325
+ this.callKit.connect.socketTriggerHangup(callUuid);
2192
2326
  }
2193
2327
  }
2194
2328
  if (data.event === SocketReceiveEvent.CUSTOMER_NO_ANSWER) {
2195
- this.callKit.logger.info(data.msg, {
2196
- caller: "Socket.onMessage",
2197
- type: "INCALL",
2198
- content: {
2199
- data: content,
2200
- event: SocketReceiveEvent.CUSTOMER_NO_ANSWER
2201
- }
2329
+ this.callKit.trigger(KitEvent.CALL_NO_ANSWER, {
2330
+ time: /* @__PURE__ */ new Date(),
2331
+ callUuid
2202
2332
  });
2203
- this.callKit.trigger(KitEvent.CALL_NO_ANSWER);
2204
- if (content?.callUuid) {
2205
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2333
+ if (callUuid) {
2334
+ this.callKit.connect.socketTriggerHangup(callUuid);
2206
2335
  }
2207
2336
  }
2208
2337
  if (data.event === SocketReceiveEvent.CALL_CDR) {
2209
- this.callKit.logger.info(data.msg, {
2210
- caller: `Socket.onMessage:${data.event}`,
2211
- type: "INCALL",
2212
- content: {
2213
- data: content,
2214
- event: SocketReceiveEvent.CALL_CDR
2215
- }
2216
- });
2217
- this.callKit.trigger(KitEvent.CALL_CDR, content);
2218
- }
2219
- if (data.event === SocketReceiveEvent.STOP_CONFIRM) {
2220
- this.callKit.logger.info(data.msg, {
2221
- caller: `Socket.onMessage:${data.event}`,
2222
- type: "INCALL",
2223
- content: {
2224
- data: content,
2225
- event: SocketReceiveEvent.STOP_CONFIRM
2226
- }
2338
+ this.callKit.trigger(KitEvent.CALL_CDR, {
2339
+ time: /* @__PURE__ */ new Date(),
2340
+ callUuid,
2341
+ ...content
2227
2342
  });
2228
2343
  }
2229
2344
  if (data.event === SocketReceiveEvent.CLOSE) {
2230
2345
  const { userInfo } = this.callKit.config.getConfig();
2231
- this.callKit.logger.info(data.msg, {
2232
- caller: `Socket.onMessage:${data.event}`,
2233
- type: "INCALL",
2234
- content: {
2235
- data: content,
2236
- event: SocketReceiveEvent.CLOSE
2237
- }
2238
- });
2239
- this.send(SocketSendEvent.END, { agentId: userInfo.agentId });
2346
+ this.send(SocketSendEvent.END, { agentId: userInfo.agentId, callUuid });
2240
2347
  }
2241
2348
  if (data.event === SocketReceiveEvent.ERROR) {
2242
2349
  this.setConnectAuthState("isError", true);
@@ -2246,7 +2353,8 @@ var Socket = class {
2246
2353
  type: "INCALL",
2247
2354
  content: {
2248
2355
  errCode: ErrorCode.SOKET_SERVER_ERROR,
2249
- data: content
2356
+ data: content,
2357
+ callUuid
2250
2358
  }
2251
2359
  });
2252
2360
  }
@@ -2258,24 +2366,29 @@ var Socket = class {
2258
2366
  type: "INCALL",
2259
2367
  content: {
2260
2368
  data: content,
2261
- event: SocketReceiveEvent.SESSION_ERROR
2369
+ event: SocketReceiveEvent.SESSION_ERROR,
2370
+ callUuid
2262
2371
  }
2263
2372
  });
2264
2373
  }
2265
2374
  if (data.event === SocketReceiveEvent.AGENT_NO_ANSWER) {
2266
- this.callKit.logger.info(data.msg, {
2267
- caller: `Socket.onMessage:${data.event}`,
2268
- type: "INCALL",
2269
- content: {
2270
- data: content,
2271
- event: SocketReceiveEvent.AGENT_NO_ANSWER
2272
- }
2273
- });
2274
- if (content?.callUuid) {
2275
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2375
+ if (callUuid) {
2376
+ this.callKit.connect.socketTriggerHangup(callUuid);
2276
2377
  }
2277
2378
  }
2278
- this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);
2379
+ if (data.event === SocketReceiveEvent.AGENT_HANG_UP) {
2380
+ if (callUuid) {
2381
+ this.callKit.connect.socketTriggerHangup(callUuid);
2382
+ }
2383
+ }
2384
+ this.callKit.trigger(
2385
+ KitEvent.SERVER_SOCKET_EVENT,
2386
+ {
2387
+ ...data,
2388
+ callUuid
2389
+ },
2390
+ true
2391
+ );
2279
2392
  }
2280
2393
  send(event, message) {
2281
2394
  if (!this.connectAuthState.isConnected) {
@@ -2323,32 +2436,18 @@ var Socket = class {
2323
2436
  caller: "Socket.send",
2324
2437
  type: "INCALL",
2325
2438
  content: {
2326
- ...msg
2439
+ ...msg,
2440
+ userInfo
2327
2441
  }
2328
2442
  });
2329
- switch (event) {
2330
- case SocketSendEvent.PING:
2331
- this.lastPingTime = Date.now();
2332
- this.ws?.send(JSON.stringify({ event, ...msg }));
2333
- break;
2334
- default:
2335
- this.ws?.send(JSON.stringify({ event, ...msg }));
2336
- break;
2337
- }
2443
+ this.ws?.send(JSON.stringify({ event, ...msg }));
2338
2444
  }
2339
2445
  ping() {
2340
2446
  if (!this.connectAuthState.isConnected)
2341
2447
  return;
2342
2448
  this.send(SocketSendEvent.PING);
2343
- this.callKit.logger.info(`socket ping`, {
2344
- caller: "Socket.ping",
2345
- type: "INCALL",
2346
- content: {
2347
- lastPingTime: this.lastPingTime
2348
- }
2349
- });
2350
2449
  const now = Date.now();
2351
- const { pingInterval, pingTimeout } = this.getSocketConfig();
2450
+ const { pingInterval, pingTimeout } = this.reconnectConfig;
2352
2451
  if (now - this.lastPingTime > pingInterval + pingTimeout) {
2353
2452
  if (this.ws && this.connectAuthState.isConnected) {
2354
2453
  this.ws.close(4001, "ping timeout");
@@ -2362,14 +2461,16 @@ var Socket = class {
2362
2461
  errCode: ErrorCode.SOCKET_PING_TIMEOUT
2363
2462
  }
2364
2463
  });
2464
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2465
+ event: "INCALL_PING_TIMEOUT"
2466
+ });
2365
2467
  }
2366
2468
  }
2367
2469
  checkPing() {
2368
2470
  if (this.pingTimer) {
2369
2471
  clearInterval(this.pingTimer);
2370
2472
  }
2371
- this.ping();
2372
- const { pingInterval } = this.getSocketConfig();
2473
+ const { pingInterval } = this.reconnectConfig;
2373
2474
  this.pingTimer = setInterval(() => {
2374
2475
  this.ping();
2375
2476
  }, pingInterval);
@@ -2378,20 +2479,19 @@ var Socket = class {
2378
2479
  * reset socket connection and all states
2379
2480
  */
2380
2481
  async reset(config) {
2381
- const { focus = false } = config || {};
2482
+ const { force = false } = config || {};
2382
2483
  if (this.pingTimer) {
2383
2484
  clearInterval(this.pingTimer);
2384
2485
  this.pingTimer = void 0;
2385
2486
  }
2386
- if (focus) {
2487
+ if (force) {
2387
2488
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2388
2489
  event: "INCALL_RESET"
2389
2490
  });
2390
2491
  this.resetConnectState();
2391
- this.setConnectAuthState("isConnected", false);
2392
2492
  }
2393
2493
  this.lastPingTime = void 0;
2394
- this.setConnectAuthState("satrtConfirm", false);
2494
+ this.setConnectAuthState("startConfirm", false);
2395
2495
  this.clearWebSocket();
2396
2496
  }
2397
2497
  attemptReconnect() {
@@ -2399,11 +2499,12 @@ var Socket = class {
2399
2499
  clearTimeout(this.reconnectTimer);
2400
2500
  this.reconnectTimer = void 0;
2401
2501
  }
2402
- const { maxAttempts } = this.getSocketConfig();
2502
+ const { maxAttempts } = this.reconnectConfig;
2403
2503
  if (this.reconnectAttempts >= maxAttempts) {
2404
2504
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2405
2505
  event: "INCALL_RECONNECT_ERROR"
2406
2506
  });
2507
+ this.setConnectAuthState("isError", true);
2407
2508
  this.callKit.reset();
2408
2509
  this.callKit.logger.error("Maximum reconnection attempts reached", {
2409
2510
  caller: "Socket.attemptReconnect",
@@ -2422,7 +2523,7 @@ var Socket = class {
2422
2523
  }
2423
2524
  this.setConnectAuthState("isReconnecting", true);
2424
2525
  this.reconnectAttempts += 1;
2425
- const { delay } = this.getSocketConfig();
2526
+ const { delay } = this.reconnectConfig;
2426
2527
  this.callKit.logger.info(
2427
2528
  `Preparing reconnection attempt ${this.reconnectAttempts}/${maxAttempts}, delay: ${delay}ms`,
2428
2529
  {
@@ -2457,17 +2558,34 @@ var CallKit = class {
2457
2558
  this.connect = new Connect(this);
2458
2559
  this.callCenter = new Call(this);
2459
2560
  this.socket = new Socket(this);
2460
- this.config.setConfig("log", options.log);
2461
- this.config.setConfig("trackLogs", options.trackLogs);
2462
- this.config.setConfig("audioRef", options.audioRef);
2463
- this.config.setConfig("host", options.host);
2561
+ this.logger = new Logger(this, options.log);
2562
+ if (options.log) {
2563
+ this.config.setConfig("log", options.log);
2564
+ }
2565
+ if (options.trackLogs) {
2566
+ this.config.setConfig("trackLogs", {
2567
+ ...trackLogsDefaultConfig,
2568
+ ...options.trackLogs
2569
+ });
2570
+ }
2571
+ if (options.audioRef) {
2572
+ this.config.setConfig("audioRef", options.audioRef);
2573
+ }
2574
+ if (options.host) {
2575
+ this.config.setConfig("host", options.host);
2576
+ }
2464
2577
  this.config.setConfig(
2465
2578
  "constrains",
2466
2579
  options.constrains || constrainsDefault
2467
2580
  );
2468
2581
  this.config.setConfig("socket", options.socket);
2469
- this.config.setConfig("reconnect", options.reconnect);
2470
- this.logger = new Logger(this, options.log);
2582
+ this.config.setConfig("reconnect", {
2583
+ sip: { ...SIP_RECONNECT_CONFIG, ...options.reconnect?.sip || {} },
2584
+ incall: {
2585
+ ...SOCKET_RECONNECT_CONFIG,
2586
+ ...options.reconnect?.incall || {}
2587
+ }
2588
+ });
2471
2589
  this.logger.info("callKit init", {
2472
2590
  caller: "CallKit.init",
2473
2591
  content: options
@@ -2515,7 +2633,8 @@ var CallKit = class {
2515
2633
  try {
2516
2634
  const user = await this.api.login({
2517
2635
  userName: username,
2518
- password: encryptionPassword
2636
+ password: encryptionPassword,
2637
+ timestamp: Date.now()
2519
2638
  });
2520
2639
  if (user) {
2521
2640
  this.config.setConfig("userInfo", {
@@ -2561,7 +2680,7 @@ var CallKit = class {
2561
2680
  if (this.config.isLogin()) {
2562
2681
  const { sessionId } = userInfo;
2563
2682
  try {
2564
- await this.api.loginOut({ sessionId });
2683
+ await this.api.loginOut({ sessionId, timestamp: Date.now() });
2565
2684
  } catch (error) {
2566
2685
  this.logger.warn(error, {
2567
2686
  caller: "CallKit.logout",
@@ -2573,8 +2692,9 @@ var CallKit = class {
2573
2692
  }
2574
2693
  if (isReset) {
2575
2694
  await this.reset();
2695
+ } else {
2696
+ this.config.reset("logout");
2576
2697
  }
2577
- this.trigger(KitEvent.KIT_LOGIN_CHANGE, false);
2578
2698
  }
2579
2699
  async call(extno = "", options = {
2580
2700
  sourceType: CallSourceType.phoneNum,
@@ -2707,7 +2827,7 @@ var CallKit = class {
2707
2827
  * set userstatus
2708
2828
  * @param status
2709
2829
  */
2710
- async setUserStatus(status) {
2830
+ async setUserStatus(status, extra = {}) {
2711
2831
  const { agentId } = this.config.getConfig().userInfo;
2712
2832
  this.logger.info("setUserStatus", {
2713
2833
  caller: "CallKit.setUserStatus",
@@ -2718,16 +2838,24 @@ var CallKit = class {
2718
2838
  });
2719
2839
  await this.api.updateUserStatus({
2720
2840
  agentId,
2721
- userStatus: status
2841
+ userStatus: status,
2842
+ timestamp: Date.now(),
2843
+ ...extra
2722
2844
  });
2723
2845
  }
2724
- async _reset(config) {
2725
- const { focus = false } = config || {};
2846
+ /**
2847
+ * reset callkit
2848
+ * @description recover the callkit to the initial state
2849
+ * @default force is false
2850
+ * @param config.force is true, the callkit reset socket connection and all states
2851
+ */
2852
+ async reset(config) {
2853
+ const { force = false } = config || {};
2726
2854
  this.logger.info("reset", {
2727
2855
  caller: "CallKit.reset",
2728
2856
  content: {
2729
2857
  connectStatus: this.connect.connectStatus,
2730
- focus
2858
+ force
2731
2859
  }
2732
2860
  });
2733
2861
  if (this.connect.isCalling()) {
@@ -2736,16 +2864,10 @@ var CallKit = class {
2736
2864
  await this.connect.reset();
2737
2865
  if (this.config.isLogin()) {
2738
2866
  await this.logout({ isReset: false });
2867
+ } else {
2868
+ await this.config.reset("reset");
2739
2869
  }
2740
- await this.config.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 });
2870
+ await this.socket.reset({ force });
2749
2871
  }
2750
2872
  on(event, callback) {
2751
2873
  this.listener.push({
@@ -2781,7 +2903,9 @@ var CallKit = class {
2781
2903
  if (!noLog) {
2782
2904
  this.logger.info(`Trigger Event: ${event}`, {
2783
2905
  caller: "CallKit.trigger",
2784
- content: data
2906
+ content: {
2907
+ data
2908
+ }
2785
2909
  });
2786
2910
  }
2787
2911
  this.listener.forEach((item) => {
@@ -2789,7 +2913,7 @@ var CallKit = class {
2789
2913
  try {
2790
2914
  item.callback(data);
2791
2915
  } catch (err) {
2792
- this.logger.error("Event callback error:", err, true);
2916
+ this.logger.error(`Event callback error: ${event}`, err, true);
2793
2917
  }
2794
2918
  }
2795
2919
  });