@koi-design/callkit 2.0.6-beta.1 → 2.1.0-beta.2

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
@@ -62,7 +62,8 @@ var Api = class {
62
62
  if (this.isLogining) {
63
63
  this.callKit.logger.info("login is already in progress cancel", {
64
64
  caller: "Api.login",
65
- content: { userName: params.userName }
65
+ type: "API",
66
+ content: { userName: params.userName, timestamp: params.timestamp }
66
67
  });
67
68
  return;
68
69
  }
@@ -81,8 +82,9 @@ var Api = class {
81
82
  async loginOut(params) {
82
83
  if (this.isLoginOuting) {
83
84
  this.callKit.logger.info("loginOut is already in progress cancel", {
85
+ type: "API",
84
86
  caller: "Api.loginOut",
85
- content: { sessionId: params.sessionId }
87
+ content: { sessionId: params.sessionId, timestamp: params.timestamp }
86
88
  });
87
89
  return;
88
90
  }
@@ -99,12 +101,23 @@ var Api = class {
99
101
  }
100
102
  }
101
103
  async trackLogs(log) {
102
- return this.post(
103
- { url: "/agent/user/sdkLog", method: "post", data: { content: [log] } },
104
- {
105
- useFormData: true
106
- }
107
- );
104
+ try {
105
+ const { userInfo, host } = this.callKit.config.getConfig();
106
+ const { sessionId } = userInfo;
107
+ const formData = new FormData();
108
+ formData.append("content", JSON.stringify([log]));
109
+ const config = {
110
+ url: `${host}/agent/user/sdkLog`,
111
+ method: "post",
112
+ data: formData,
113
+ headers: {
114
+ ...sessionId ? { sessionId } : {}
115
+ }
116
+ };
117
+ await axios_default(config).catch(() => {
118
+ });
119
+ } catch (error) {
120
+ }
108
121
  }
109
122
  /**
110
123
  *
@@ -118,7 +131,7 @@ var Api = class {
118
131
  data: params
119
132
  });
120
133
  }
121
- async post(config, extra = {}) {
134
+ async post(config, extra = { skipLog: false }) {
122
135
  const { userInfo, host } = this.callKit.config.getConfig();
123
136
  const { sessionId } = userInfo;
124
137
  config.url = `${host}${config.url}`;
@@ -142,30 +155,34 @@ var Api = class {
142
155
  config.headers.sessionId = sessionId;
143
156
  }
144
157
  const startTime = Date.now();
145
- this.callKit.logger.info("API Request Start", {
146
- type: "API",
147
- caller: "API.Request",
148
- content: {
149
- url: config.url,
150
- headers: config.headers,
151
- data: config.data,
152
- extra,
153
- startTime
154
- }
155
- });
158
+ if (!extra.skipLog) {
159
+ this.callKit.logger.info("API Request Start", {
160
+ type: "API",
161
+ caller: "API.Request",
162
+ content: {
163
+ url: config.url,
164
+ headers: config.headers,
165
+ data: config.data,
166
+ extra,
167
+ startTime
168
+ }
169
+ });
170
+ }
156
171
  const res = await axios_default(config).catch(() => {
157
- this.callKit.config.reset();
172
+ this.callKit.config.reset("api request error");
158
173
  });
159
174
  const endTime = Date.now();
160
- this.callKit.logger.info("API Request Finish", {
161
- type: "API",
162
- caller: "API.Request",
163
- content: {
164
- url: config.url,
165
- duration: `${endTime - startTime}ms`,
166
- response: res
167
- }
168
- });
175
+ if (!extra.skipLog) {
176
+ this.callKit.logger.info("API Request Finish", {
177
+ type: "API",
178
+ caller: "API.Request",
179
+ content: {
180
+ url: config.url,
181
+ duration: `${endTime - startTime}ms`,
182
+ response: res
183
+ }
184
+ });
185
+ }
169
186
  if (!res) {
170
187
  this.callKit.reset();
171
188
  throw new Error("Network error");
@@ -175,7 +192,7 @@ var Api = class {
175
192
  return data;
176
193
  }
177
194
  if (code === "100013") {
178
- this.callKit.config.reset();
195
+ this.callKit.config.reset("api request error");
179
196
  }
180
197
  throw new Error(message ?? "Request failed");
181
198
  }
@@ -508,7 +525,8 @@ var SocketReceiveEvent = {
508
525
  * Error
509
526
  */
510
527
  ERROR: "ERROR",
511
- SESSION_ERROR: "SESSION_ERROR"
528
+ SESSION_ERROR: "SESSION_ERROR",
529
+ WAITING_QUEUE: "WAITING_QUEUE"
512
530
  };
513
531
  var EncryptionMethod = {
514
532
  NONE: "NONE",
@@ -531,7 +549,7 @@ var CallSourceType = {
531
549
  var trackLogsDefaultConfig = {
532
550
  enabled: false,
533
551
  interval: 5e3,
534
- maxSize: 8192
552
+ maxSize: 4096
535
553
  };
536
554
  var SOCKET_RECONNECT_CONFIG = {
537
555
  enabled: true,
@@ -543,9 +561,7 @@ var SOCKET_RECONNECT_CONFIG = {
543
561
  var SIP_RECONNECT_CONFIG = {
544
562
  enabled: true,
545
563
  maxAttempts: 3,
546
- delay: 1e3,
547
- enableMessageKeepalive: false,
548
- messageKeepaliveInterval: 3e4
564
+ delay: 1e3
549
565
  };
550
566
 
551
567
  // core/call.ts
@@ -689,13 +705,13 @@ var Call = class {
689
705
  // package.json
690
706
  var package_default = {
691
707
  name: "@koi-design/callkit",
692
- version: "2.0.6-beta.1",
708
+ version: "2.1.0-beta.2",
693
709
  description: "callkit",
694
710
  author: "koi",
695
711
  license: "ISC",
696
712
  scripts: {
697
713
  build: "tsup",
698
- sraet: "vite",
714
+ start: "vite",
699
715
  dev: "tsup --watch",
700
716
  lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
701
717
  release: "tsup && node scripts/pkg.js"
@@ -795,7 +811,12 @@ var Config = class {
795
811
  }
796
812
  });
797
813
  };
798
- reset = async () => {
814
+ reset = async (form) => {
815
+ this.callKit.logger.info(`Reset User Info ${form}`, {
816
+ caller: "Config.reset",
817
+ type: "OTHER",
818
+ content: {}
819
+ });
799
820
  if (this.isLogin()) {
800
821
  this.config.userInfo = {
801
822
  wsUrl: "",
@@ -890,7 +911,7 @@ var Logger = class {
890
911
  this.flushTrackLogs();
891
912
  }, interval);
892
913
  }
893
- flushTrackLogs() {
914
+ async flushTrackLogs() {
894
915
  if (this.pendingTrackLogs.length === 0) {
895
916
  return;
896
917
  }
@@ -899,25 +920,22 @@ var Logger = class {
899
920
  try {
900
921
  const chunks = [];
901
922
  let currentChunk = [];
902
- let currentSize = 0;
903
923
  for (const log of this.pendingTrackLogs) {
904
- const logSize = getByteSize(log);
905
- const separator = currentChunk.length > 0 ? "\n" : "";
906
- const separatorSize = getByteSize(separator);
907
- if (currentSize + logSize + separatorSize > maxSize && currentChunk.length > 0) {
924
+ const testChunk = currentChunk.length > 0 ? `${currentChunk.join("\n")}
925
+ ${log}` : log;
926
+ const actualSize = getByteSize(JSON.stringify([testChunk]));
927
+ if (actualSize > maxSize && currentChunk.length > 0) {
908
928
  chunks.push(currentChunk.join("\n"));
909
929
  currentChunk = [log];
910
- currentSize = logSize;
911
930
  } else {
912
931
  currentChunk.push(log);
913
- currentSize += logSize + separatorSize;
914
932
  }
915
933
  }
916
934
  if (currentChunk.length > 0) {
917
935
  chunks.push(currentChunk.join("\n"));
918
936
  }
919
937
  for (const chunk of chunks) {
920
- this.callKit.api.trackLogs(chunk);
938
+ await this.callKit.api.trackLogs(chunk);
921
939
  }
922
940
  this.pendingTrackLogs = [];
923
941
  } catch (error) {
@@ -976,16 +994,22 @@ var Logger = class {
976
994
  }
977
995
  catchLog(msg, extra, level) {
978
996
  const now = /* @__PURE__ */ new Date();
997
+ const { enabled } = this.callKit.config.getTrackLogsConfig();
998
+ const { userInfo } = this.callKit.config.getConfig();
999
+ const content = {
1000
+ ...extra?.content ?? {},
1001
+ agentId: userInfo?.agentId,
1002
+ sessionId: userInfo?.sessionId
1003
+ };
979
1004
  const log = {
980
1005
  timestamp: now.toLocaleString().replace("T", " ").replace(".000Z", ""),
981
1006
  level,
982
1007
  message: msg,
983
1008
  caller: extra?.caller,
984
1009
  type: extra?.type,
985
- content: extra?.content ?? {}
1010
+ content
986
1011
  };
987
1012
  const logString = transformLog(log);
988
- const { enabled } = this.callKit.config.getTrackLogsConfig();
989
1013
  if (enabled) {
990
1014
  this.pendingTrackLogs.push(logString);
991
1015
  }
@@ -1013,7 +1037,6 @@ var formatGetInviteData = (inviteData) => {
1013
1037
  };
1014
1038
 
1015
1039
  // core/connect.ts
1016
- var MAX_HEARTBEAT_COUNT = 6;
1017
1040
  function convertObjectStringToJSON(input) {
1018
1041
  const corrected = input.replace(/(\w+):\s*'(.*?)'/g, '"$1": "$2"').replace(/'/g, '"');
1019
1042
  return corrected;
@@ -1068,6 +1091,10 @@ var Connect = class {
1068
1091
  *@description Whether it's a re-connected
1069
1092
  */
1070
1093
  isReConnected = false;
1094
+ /**
1095
+ *@description Whether it's a referring
1096
+ */
1097
+ isRefering = false;
1071
1098
  // sipConnected = false;
1072
1099
  /**
1073
1100
  *@description Whether it's an outgoing call
@@ -1089,6 +1116,42 @@ var Connect = class {
1089
1116
  }
1090
1117
  // current call id for invite data
1091
1118
  currentCallId = null;
1119
+ getCurrentCallId() {
1120
+ return this.currentCallId;
1121
+ }
1122
+ setRefering(refering) {
1123
+ if (this.isRefering === refering)
1124
+ return;
1125
+ this.callKit.logger.info("setRefering", {
1126
+ caller: "Connect.setRefering",
1127
+ content: {
1128
+ refering
1129
+ }
1130
+ });
1131
+ this.isRefering = refering;
1132
+ }
1133
+ setIsReConnected(isReConnected) {
1134
+ if (this.isReConnected === isReConnected)
1135
+ return;
1136
+ this.callKit.logger.info("setIsReConnected", {
1137
+ caller: "Connect.setIsReConnected",
1138
+ content: {
1139
+ isReConnected
1140
+ }
1141
+ });
1142
+ this.isReConnected = isReConnected;
1143
+ }
1144
+ setOutgoing(outgoing) {
1145
+ if (this.isOutgoing === outgoing)
1146
+ return;
1147
+ this.callKit.logger.info("setOutgoing", {
1148
+ caller: "Connect.setOutgoing",
1149
+ content: {
1150
+ outgoing
1151
+ }
1152
+ });
1153
+ this.isOutgoing = outgoing;
1154
+ }
1092
1155
  setCallId(callId) {
1093
1156
  this.callKit.logger.info("setCallId", {
1094
1157
  caller: "Connect.setCallId",
@@ -1100,9 +1163,15 @@ var Connect = class {
1100
1163
  this.callKit.trigger(KitEvent.KIT_CALL_ID_CHANGE, callId);
1101
1164
  }
1102
1165
  async reset() {
1103
- this.isOutgoing = false;
1166
+ this.setOutgoing(false);
1104
1167
  this.isUnprompted = false;
1105
1168
  this.hasInvite = false;
1169
+ if (this.isRefering) {
1170
+ this.setRefering(false);
1171
+ }
1172
+ if (this.isReConnected) {
1173
+ this.setIsReConnected(false);
1174
+ }
1106
1175
  if (this.isHolding()) {
1107
1176
  await this.setHold(false);
1108
1177
  }
@@ -1138,8 +1207,6 @@ var Connect = class {
1138
1207
  }
1139
1208
  }
1140
1209
  this.setConnectStatus(CallStatus.init);
1141
- this.clearHeartbeat();
1142
- this.stopMessageKeepalive();
1143
1210
  }
1144
1211
  getAduioReference() {
1145
1212
  const { audioRef } = this.callKit.config.getConfig();
@@ -1204,73 +1271,6 @@ var Connect = class {
1204
1271
  isInit() {
1205
1272
  return this.connectStatus === CallStatus.init;
1206
1273
  }
1207
- heartbeatInterval;
1208
- heartbeatFlag = MAX_HEARTBEAT_COUNT;
1209
- messageKeepaliveTimer;
1210
- clearHeartbeat() {
1211
- if (this.heartbeatInterval) {
1212
- clearInterval(this.heartbeatInterval);
1213
- this.heartbeatInterval = null;
1214
- }
1215
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1216
- }
1217
- startHeartbeat() {
1218
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1219
- this.clearHeartbeat();
1220
- this.heartbeatInterval = setInterval(() => {
1221
- this.heartbeatFlag -= 1;
1222
- if (this.heartbeatFlag <= 0) {
1223
- this.heartbeatFlag = MAX_HEARTBEAT_COUNT;
1224
- this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
1225
- event: "OPTIONS_HEARTBEAT_EXPIRED"
1226
- });
1227
- }
1228
- }, 1e3);
1229
- }
1230
- stopMessageKeepalive() {
1231
- if (this.messageKeepaliveTimer) {
1232
- clearInterval(this.messageKeepaliveTimer);
1233
- this.messageKeepaliveTimer = void 0;
1234
- }
1235
- }
1236
- startMessageKeepalive() {
1237
- const { enableMessageKeepalive, messageKeepaliveInterval } = this.reconnectConfig;
1238
- if (!enableMessageKeepalive)
1239
- return;
1240
- this.stopMessageKeepalive();
1241
- this.messageKeepaliveTimer = setInterval(() => {
1242
- this.sendKeepaliveMessage();
1243
- }, messageKeepaliveInterval);
1244
- }
1245
- async sendKeepaliveMessage() {
1246
- try {
1247
- if (!this.isRegistered() || !this.userAgent)
1248
- return;
1249
- const { userInfo } = this.callKit.config.getConfig();
1250
- const { userPart, fsIp, fsPort } = userInfo || {};
1251
- const target = import_sip.UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`);
1252
- if (!target)
1253
- return;
1254
- const messager = new import_sip.Messager(this.userAgent, target, "");
1255
- await messager.message();
1256
- this.callKit.logger.info("MESSAGE keepalive ok", {
1257
- caller: "Connect.sendKeepaliveMessage",
1258
- type: "SIP",
1259
- content: {}
1260
- });
1261
- } catch (err) {
1262
- this.callKit.logger.error(err, {
1263
- caller: "Connect.sendKeepaliveMessage",
1264
- type: "SIP",
1265
- content: {}
1266
- });
1267
- this.stopMessageKeepalive();
1268
- this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
1269
- event: "MESSAGE_KEEPALIVE_FAILED"
1270
- });
1271
- this.startReconnectTimer();
1272
- }
1273
- }
1274
1274
  socketTriggerHangup(callId) {
1275
1275
  if (!this.isCalling() || callId !== this.currentCallId)
1276
1276
  return;
@@ -1283,6 +1283,136 @@ var Connect = class {
1283
1283
  });
1284
1284
  this.callKit.hangup();
1285
1285
  }
1286
+ /**
1287
+ * Setup registerer and bind stateChange listener
1288
+ * @private
1289
+ */
1290
+ setupRegisterer() {
1291
+ if (!this.userAgent) {
1292
+ this.callKit.logger.warn("userAgent is not initialized", {
1293
+ caller: "Connect.setupRegisterer",
1294
+ content: {
1295
+ errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR
1296
+ }
1297
+ });
1298
+ return;
1299
+ }
1300
+ const { userInfo } = this.callKit.config.getConfig();
1301
+ const { userPart, fsIp, fsPort } = userInfo;
1302
+ const registererOptions = {};
1303
+ this.registerer = new import_sip.Registerer(this.userAgent, registererOptions);
1304
+ this.registerer.stateChange.addListener((state) => {
1305
+ switch (state) {
1306
+ case import_sip.RegistererState.Initial:
1307
+ this.callKit.logger.info("registerer stateChange Initial", {
1308
+ caller: "Connect.setupRegisterer.registererStateChange",
1309
+ type: "SIP",
1310
+ content: {
1311
+ registererState: state,
1312
+ isRegistered: this.isRegistered()
1313
+ }
1314
+ });
1315
+ this.setRegister(false);
1316
+ this.setConnectStatus(CallStatus.init);
1317
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1318
+ registererState: state,
1319
+ isRegistered: this.isRegistered()
1320
+ });
1321
+ break;
1322
+ case import_sip.RegistererState.Registered:
1323
+ this.callKit.logger.info("registerer stateChange Registered", {
1324
+ caller: "Connect.setupRegisterer.registererStateChange",
1325
+ type: "SIP",
1326
+ content: {
1327
+ registererState: state,
1328
+ isRegistered: this.isRegistered()
1329
+ }
1330
+ });
1331
+ this.setRegister(true);
1332
+ if (this.isReConnected) {
1333
+ if (this.currentSession && (this.currentSession.state === import_sip.SessionState.Established || this.currentSession.state === import_sip.SessionState.Establishing) && this.isCalling()) {
1334
+ const selfUri = `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
1335
+ this.callKit.logger.info(
1336
+ "Reconnected, referring active session to self",
1337
+ {
1338
+ caller: "Connect.setupRegisterer.registererStateChange",
1339
+ type: "SIP",
1340
+ content: {
1341
+ selfUri,
1342
+ sessionState: this.currentSession.state,
1343
+ connectStatus: this.connectStatus
1344
+ }
1345
+ }
1346
+ );
1347
+ this.refer(selfUri).catch((err) => {
1348
+ this.callKit.logger.error(err, {
1349
+ caller: "Connect.setupRegisterer.registererStateChange",
1350
+ type: "SIP",
1351
+ content: {
1352
+ errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
1353
+ selfUri
1354
+ }
1355
+ });
1356
+ });
1357
+ } else {
1358
+ this.callKit.logger.warn(
1359
+ "Reconnected but no active session to refer",
1360
+ {
1361
+ caller: "Connect.setupRegisterer.registererStateChange",
1362
+ type: "SIP",
1363
+ content: {
1364
+ hasCurrentSession: !!this.currentSession,
1365
+ sessionState: this.currentSession?.state,
1366
+ connectStatus: this.connectStatus,
1367
+ isCalling: this.isCalling()
1368
+ }
1369
+ }
1370
+ );
1371
+ }
1372
+ this.setIsReConnected(false);
1373
+ }
1374
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1375
+ registererState: state,
1376
+ isRegistered: this.isRegistered()
1377
+ });
1378
+ break;
1379
+ case import_sip.RegistererState.Terminated:
1380
+ this.callKit.logger.info("registerer stateChange Terminated", {
1381
+ caller: "Connect.setupRegisterer.registererStateChange",
1382
+ type: "SIP",
1383
+ content: {
1384
+ registererState: state,
1385
+ isRegistered: this.isRegistered()
1386
+ }
1387
+ });
1388
+ this.setRegister(false);
1389
+ this.setConnectStatus(CallStatus.init);
1390
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1391
+ registererState: state,
1392
+ isRegistered: this.isRegistered()
1393
+ });
1394
+ break;
1395
+ case import_sip.RegistererState.Unregistered:
1396
+ this.callKit.logger.info("registerer stateChange Unregistered", {
1397
+ caller: "Connect.setupRegisterer.registererStateChange",
1398
+ type: "SIP",
1399
+ content: {
1400
+ isRegistered: this.isRegistered(),
1401
+ registererState: state
1402
+ }
1403
+ });
1404
+ this.setRegister(false);
1405
+ this.setConnectStatus(CallStatus.init);
1406
+ this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1407
+ registererState: state,
1408
+ isRegistered: this.isRegistered()
1409
+ });
1410
+ break;
1411
+ default:
1412
+ break;
1413
+ }
1414
+ });
1415
+ }
1286
1416
  async register() {
1287
1417
  if (this.connectStatus !== CallStatus.init) {
1288
1418
  if (this.isRegistered()) {
@@ -1323,7 +1453,7 @@ var Connect = class {
1323
1453
  this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);
1324
1454
  return this.mediaStream;
1325
1455
  };
1326
- const { userPart, fsIp, fsPort, iceInfo, wsUrl, fsUserId, fsPassword } = userInfo;
1456
+ const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;
1327
1457
  const connectConfig = {
1328
1458
  uri: import_sip.UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),
1329
1459
  displayName: userPart,
@@ -1341,9 +1471,7 @@ var Connect = class {
1341
1471
  peerConnectionConfiguration: {
1342
1472
  iceServers: JSON.parse(convertObjectStringToJSON(iceInfo))
1343
1473
  }
1344
- },
1345
- authorizationUsername: fsUserId || userPart,
1346
- authorizationPassword: fsPassword
1474
+ }
1347
1475
  };
1348
1476
  this.callKit.logger.info("connect connectConfig", {
1349
1477
  caller: "Connect.register",
@@ -1386,9 +1514,6 @@ var Connect = class {
1386
1514
  const core = userAgent.userAgentCore;
1387
1515
  const originalReceiveIncomingRequestFromTransport = core.receiveIncomingRequestFromTransport.bind(core);
1388
1516
  core.receiveIncomingRequestFromTransport = (request2) => {
1389
- if (request2.method === "OPTIONS") {
1390
- that.startHeartbeat();
1391
- }
1392
1517
  that.callKit.logger.info(`SIP Receive: ${request2?.method}`, {
1393
1518
  caller: "Connect.register.observeSocketStatus.receiveRequest",
1394
1519
  type: "SIP",
@@ -1398,6 +1523,20 @@ var Connect = class {
1398
1523
  });
1399
1524
  return originalReceiveIncomingRequestFromTransport(request2);
1400
1525
  };
1526
+ const originalReceiveIncomingResponseFromTransport = core.receiveIncomingResponseFromTransport.bind(core);
1527
+ core.receiveIncomingResponseFromTransport = (response) => {
1528
+ that.callKit.logger.info(
1529
+ `SIP Receive Response: ${response?.statusCode} ${response?.reasonPhrase}`,
1530
+ {
1531
+ caller: "Connect.register.observeSocketStatus.receiveResponse",
1532
+ type: "SIP",
1533
+ content: {
1534
+ response
1535
+ }
1536
+ }
1537
+ );
1538
+ return originalReceiveIncomingResponseFromTransport(response);
1539
+ };
1401
1540
  const { transport } = userAgent;
1402
1541
  if (transport) {
1403
1542
  const originalSend = transport.send.bind(transport);
@@ -1413,81 +1552,7 @@ var Connect = class {
1413
1552
  };
1414
1553
  }
1415
1554
  };
1416
- const registererOptions = {};
1417
- this.registerer = new import_sip.Registerer(this.userAgent, registererOptions);
1418
- this.registerer.stateChange.addListener((state) => {
1419
- switch (state) {
1420
- case import_sip.RegistererState.Initial:
1421
- this.callKit.logger.info("registerer stateChange Initial", {
1422
- caller: "Connect.register.registererStateChange",
1423
- type: "SIP",
1424
- content: {
1425
- registererState: state,
1426
- isRegistered: this.isRegistered()
1427
- }
1428
- });
1429
- this.setRegister(false);
1430
- this.setConnectStatus(CallStatus.init);
1431
- this.stopMessageKeepalive();
1432
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1433
- registererState: state,
1434
- isRegistered: this.isRegistered()
1435
- });
1436
- break;
1437
- case import_sip.RegistererState.Registered:
1438
- this.callKit.logger.info("registerer stateChange Registered", {
1439
- caller: "Connect.register.registererStateChange",
1440
- type: "SIP",
1441
- content: {
1442
- registererState: state,
1443
- isRegistered: this.isRegistered()
1444
- }
1445
- });
1446
- this.setRegister(true);
1447
- this.startMessageKeepalive();
1448
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1449
- registererState: state,
1450
- isRegistered: this.isRegistered()
1451
- });
1452
- break;
1453
- case import_sip.RegistererState.Terminated:
1454
- this.callKit.logger.info("registerer stateChange Terminated", {
1455
- caller: "Connect.register.registererStateChange",
1456
- type: "SIP",
1457
- content: {
1458
- registererState: state,
1459
- isRegistered: this.isRegistered()
1460
- }
1461
- });
1462
- this.setRegister(false);
1463
- this.setConnectStatus(CallStatus.init);
1464
- this.stopMessageKeepalive();
1465
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1466
- registererState: state,
1467
- isRegistered: this.isRegistered()
1468
- });
1469
- break;
1470
- case import_sip.RegistererState.Unregistered:
1471
- this.callKit.logger.info("registerer stateChange Unregistered", {
1472
- caller: "Connect.register.registererStateChange",
1473
- type: "SIP",
1474
- content: {
1475
- isRegistered: this.isRegistered(),
1476
- registererState: state
1477
- }
1478
- });
1479
- this.setRegister(false);
1480
- this.setConnectStatus(CallStatus.init);
1481
- this.stopMessageKeepalive();
1482
- this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
1483
- registererState: state,
1484
- isRegistered: this.isRegistered()
1485
- });
1486
- break;
1487
- default:
1488
- break;
1489
- }
1490
- });
1555
+ this.setupRegisterer();
1491
1556
  this.userAgent.delegate = {
1492
1557
  onInvite: (invite) => {
1493
1558
  this.callKit.logger.info("connect onInvite", {
@@ -1495,7 +1560,8 @@ var Connect = class {
1495
1560
  caller: "Connect.register.onInvite",
1496
1561
  content: {
1497
1562
  invite,
1498
- isRegistered: this.isRegistered()
1563
+ isRegistered: this.isRegistered(),
1564
+ isOutgoing: this.isOutgoing
1499
1565
  }
1500
1566
  });
1501
1567
  this.currentSession = invite;
@@ -1573,7 +1639,9 @@ var Connect = class {
1573
1639
  });
1574
1640
  this.callKit.logger.info("get invite data", {
1575
1641
  caller: "Connect.register.onInvite",
1576
- content: xHeaders
1642
+ content: {
1643
+ headers: xHeaders
1644
+ }
1577
1645
  });
1578
1646
  return xHeaders;
1579
1647
  };
@@ -1594,9 +1662,16 @@ var Connect = class {
1594
1662
  } catch (error) {
1595
1663
  this.callKit.logger.info(error, {
1596
1664
  caller: "Connect.register.onInvite",
1597
- content: info
1665
+ content: {
1666
+ headers: info
1667
+ }
1598
1668
  });
1599
1669
  }
1670
+ if (this.isRefering) {
1671
+ this.currentSession.accept(options);
1672
+ this.setRefering(false);
1673
+ return;
1674
+ }
1600
1675
  if (this.isOutgoing) {
1601
1676
  this.currentSession.accept(options);
1602
1677
  this.callKit.trigger(KitEvent.KIT_OUTGOING_INVITE, {
@@ -1632,10 +1707,8 @@ var Connect = class {
1632
1707
  version: `${this.callKit.config.getConfig().version}`
1633
1708
  }
1634
1709
  });
1635
- try {
1636
- await this.registerer.register();
1637
- this.startMessageKeepalive();
1638
- } catch (err) {
1710
+ this.setupRegisterer();
1711
+ await this.registerer.register().catch(async (err) => {
1639
1712
  this.callKit.reset();
1640
1713
  this.callKit.logger.error(err?.message, {
1641
1714
  caller: "Connect.register",
@@ -1644,12 +1717,11 @@ var Connect = class {
1644
1717
  errCode: ErrorCode.WEBRTC_REGISTER_ERROR
1645
1718
  }
1646
1719
  });
1647
- }
1720
+ });
1648
1721
  },
1649
1722
  onDisconnect: (error) => {
1650
- this.stopMessageKeepalive();
1651
1723
  if (error) {
1652
- this.callKit.logger.info("SIP User Agent Disconnected with error", {
1724
+ this.callKit.logger.warn("SIP User Agent Disconnected with error", {
1653
1725
  caller: "Connect.register",
1654
1726
  type: "SIP",
1655
1727
  content: {
@@ -1659,21 +1731,12 @@ var Connect = class {
1659
1731
  });
1660
1732
  this.startReconnectTimer();
1661
1733
  } else {
1662
- this.callKit.logger.info("SIP User Agent Disconnected", {
1734
+ this.callKit.logger.warn("SIP User Agent Disconnected", {
1663
1735
  caller: "Connect.register",
1664
1736
  type: "SIP",
1665
1737
  content: {}
1666
1738
  });
1667
1739
  }
1668
- },
1669
- onRegister: () => {
1670
- this.callKit.logger.info("connect onRegister", {
1671
- caller: "Connect.register",
1672
- type: "SIP",
1673
- content: {
1674
- version: `V${this.callKit.config.getConfig().version}`
1675
- }
1676
- });
1677
1740
  }
1678
1741
  };
1679
1742
  observeSocketStatus(this.userAgent, {
@@ -1719,6 +1782,7 @@ var Connect = class {
1719
1782
  this.reconnectTimer = setTimeout(() => {
1720
1783
  if (this.reconnectTimer && this.callKit.config.isLogin()) {
1721
1784
  this.userAgent?.reconnect();
1785
+ this.setIsReConnected(true);
1722
1786
  this.callKit.logger.info("Reconnect attempt", {
1723
1787
  caller: "Connect.startReconnectTimer",
1724
1788
  type: "SIP",
@@ -1743,7 +1807,6 @@ var Connect = class {
1743
1807
  }
1744
1808
  async stop() {
1745
1809
  await this.userAgent.stop();
1746
- this.stopMessageKeepalive();
1747
1810
  }
1748
1811
  async unregister() {
1749
1812
  this.callKit.logger.info("connect unregister", {
@@ -1753,7 +1816,6 @@ var Connect = class {
1753
1816
  isRegistered: this.isRegistered()
1754
1817
  }
1755
1818
  });
1756
- this.stopMessageKeepalive();
1757
1819
  if (!this.isRegistered() || !this.registerer) {
1758
1820
  this.callKit.logger.warn("No registerer to unregister.", {
1759
1821
  caller: "Connect.unregister",
@@ -1786,20 +1848,20 @@ var Connect = class {
1786
1848
  });
1787
1849
  }
1788
1850
  async call(callback) {
1789
- this.callKit.logger.info("connect call", {
1790
- caller: "Connect.call",
1791
- type: "SIP",
1792
- content: {
1793
- callback
1794
- }
1795
- });
1796
- this.isOutgoing = true;
1851
+ this.setOutgoing(true);
1797
1852
  if (!this.isRegistered()) {
1798
1853
  await this.register();
1799
1854
  }
1800
1855
  this.setConnectStatus(CallStatus.connecting);
1801
1856
  this.callKit.trigger(KitEvent.CALL_CONNECTING, /* @__PURE__ */ new Date());
1802
1857
  const { userInfo } = this.callKit.config.getConfig();
1858
+ this.callKit.logger.info("connect call", {
1859
+ caller: "Connect.call",
1860
+ type: "SIP",
1861
+ content: {
1862
+ userInfo
1863
+ }
1864
+ });
1803
1865
  callback(userInfo);
1804
1866
  }
1805
1867
  /**
@@ -1850,7 +1912,7 @@ var Connect = class {
1850
1912
  connectStatus: this.connectStatus
1851
1913
  }
1852
1914
  });
1853
- this.isOutgoing = false;
1915
+ this.setOutgoing(false);
1854
1916
  this.isUnprompted = isUnprompted;
1855
1917
  this.setHold(false);
1856
1918
  this.setMute(false);
@@ -1878,6 +1940,7 @@ var Connect = class {
1878
1940
  }
1879
1941
  this.setConnectStatus(CallStatus.init);
1880
1942
  this.callKit.trigger(KitEvent.CALL_END, /* @__PURE__ */ new Date());
1943
+ this.setCallId(null);
1881
1944
  } catch (err) {
1882
1945
  this.callKit.trigger(KitEvent.CALL_END, /* @__PURE__ */ new Date());
1883
1946
  this.callKit.reset();
@@ -2004,12 +2067,26 @@ var Connect = class {
2004
2067
  this.callKit.trigger(KitEvent.KIT_SET_MUTE, mute);
2005
2068
  }
2006
2069
  async refer(referTo, extra) {
2070
+ if (!this.currentSession) {
2071
+ const errorMsg = "Cannot refer: currentSession is not available";
2072
+ this.callKit.logger.warn(errorMsg, {
2073
+ caller: "Connect.refer",
2074
+ type: "SIP",
2075
+ content: {
2076
+ errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
2077
+ referTo
2078
+ }
2079
+ });
2080
+ return;
2081
+ }
2082
+ this.setRefering(true);
2007
2083
  this.callKit.logger.info("connect refer", {
2008
2084
  caller: "Connect.refer",
2009
2085
  type: "SIP",
2010
2086
  content: {
2011
2087
  referTo,
2012
- extra
2088
+ extra,
2089
+ sessionState: this.currentSession.state
2013
2090
  }
2014
2091
  });
2015
2092
  let target;
@@ -2021,6 +2098,7 @@ var Connect = class {
2021
2098
  };
2022
2099
 
2023
2100
  // core/socket.ts
2101
+ var EXCLUDE_LOG_EVENTS = [SocketReceiveEvent.WAITING_QUEUE];
2024
2102
  var Socket = class {
2025
2103
  callKit;
2026
2104
  ws;
@@ -2207,9 +2285,9 @@ var Socket = class {
2207
2285
  }
2208
2286
  onMessage(ev) {
2209
2287
  const data = JSON.parse(ev.data);
2210
- let content = {};
2288
+ let content = data.data;
2211
2289
  try {
2212
- if (data.data) {
2290
+ if (typeof data.data === "string" && data.data) {
2213
2291
  content = JSON.parse(data.data);
2214
2292
  }
2215
2293
  } catch (error) {
@@ -2220,17 +2298,19 @@ var Socket = class {
2220
2298
  data: data.data
2221
2299
  }
2222
2300
  });
2223
- content = data.data;
2224
2301
  }
2225
- this.callKit.logger.info(`socket onMessage: ${data.event}`, {
2226
- caller: "Socket.onMessage",
2227
- type: "INCALL",
2228
- content: {
2229
- data: content,
2230
- event: data.event
2231
- }
2232
- });
2302
+ if (!EXCLUDE_LOG_EVENTS.includes(data.event)) {
2303
+ this.callKit.logger.info(`socket onMessage: ${data.event}`, {
2304
+ caller: "Socket.onMessage",
2305
+ type: "INCALL",
2306
+ content: {
2307
+ data: content,
2308
+ event: data.event
2309
+ }
2310
+ });
2311
+ }
2233
2312
  this.confirmAck(data);
2313
+ const callUuid = content?.callUuid || "";
2234
2314
  if (data.event === SocketReceiveEvent.PONG) {
2235
2315
  this.lastPingTime = Date.now();
2236
2316
  return;
@@ -2240,32 +2320,51 @@ var Socket = class {
2240
2320
  this.cleanReconnectState();
2241
2321
  }
2242
2322
  if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {
2243
- this.callKit.trigger(KitEvent.CALL_RINGING, /* @__PURE__ */ new Date());
2323
+ this.callKit.trigger(KitEvent.CALL_RINGING, {
2324
+ time: /* @__PURE__ */ new Date(),
2325
+ callUuid
2326
+ });
2244
2327
  }
2245
2328
  if (data.event === SocketReceiveEvent.CUSTOMER_PICK_UP) {
2246
- this.callKit.trigger(KitEvent.CALL_PICK_UP, /* @__PURE__ */ new Date());
2329
+ this.callKit.trigger(KitEvent.CALL_PICK_UP, {
2330
+ time: /* @__PURE__ */ new Date(),
2331
+ callUuid
2332
+ });
2247
2333
  }
2248
2334
  if (data.event === SocketReceiveEvent.AGENT_PICK_UP) {
2249
- this.callKit.trigger(KitEvent.AGENT_PICK_UP, /* @__PURE__ */ new Date());
2335
+ this.callKit.trigger(KitEvent.AGENT_PICK_UP, {
2336
+ time: /* @__PURE__ */ new Date(),
2337
+ callUuid
2338
+ });
2250
2339
  }
2251
2340
  if (data.event === SocketReceiveEvent.CUSTOMER_HANG_UP) {
2252
- this.callKit.trigger(KitEvent.CALL_HANG_UP, /* @__PURE__ */ new Date());
2253
- if (content?.callUuid) {
2254
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2341
+ this.callKit.trigger(KitEvent.CALL_HANG_UP, {
2342
+ time: /* @__PURE__ */ new Date(),
2343
+ callUuid
2344
+ });
2345
+ if (callUuid) {
2346
+ this.callKit.connect.socketTriggerHangup(callUuid);
2255
2347
  }
2256
2348
  }
2257
2349
  if (data.event === SocketReceiveEvent.CUSTOMER_NO_ANSWER) {
2258
- this.callKit.trigger(KitEvent.CALL_NO_ANSWER);
2259
- if (content?.callUuid) {
2260
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2350
+ this.callKit.trigger(KitEvent.CALL_NO_ANSWER, {
2351
+ time: /* @__PURE__ */ new Date(),
2352
+ callUuid
2353
+ });
2354
+ if (callUuid) {
2355
+ this.callKit.connect.socketTriggerHangup(callUuid);
2261
2356
  }
2262
2357
  }
2263
2358
  if (data.event === SocketReceiveEvent.CALL_CDR) {
2264
- this.callKit.trigger(KitEvent.CALL_CDR, content);
2359
+ this.callKit.trigger(KitEvent.CALL_CDR, {
2360
+ time: /* @__PURE__ */ new Date(),
2361
+ callUuid,
2362
+ ...content
2363
+ });
2265
2364
  }
2266
2365
  if (data.event === SocketReceiveEvent.CLOSE) {
2267
2366
  const { userInfo } = this.callKit.config.getConfig();
2268
- this.send(SocketSendEvent.END, { agentId: userInfo.agentId });
2367
+ this.send(SocketSendEvent.END, { agentId: userInfo.agentId, callUuid });
2269
2368
  }
2270
2369
  if (data.event === SocketReceiveEvent.ERROR) {
2271
2370
  this.setConnectAuthState("isError", true);
@@ -2275,7 +2374,8 @@ var Socket = class {
2275
2374
  type: "INCALL",
2276
2375
  content: {
2277
2376
  errCode: ErrorCode.SOKET_SERVER_ERROR,
2278
- data: content
2377
+ data: content,
2378
+ callUuid
2279
2379
  }
2280
2380
  });
2281
2381
  }
@@ -2287,21 +2387,29 @@ var Socket = class {
2287
2387
  type: "INCALL",
2288
2388
  content: {
2289
2389
  data: content,
2290
- event: SocketReceiveEvent.SESSION_ERROR
2390
+ event: SocketReceiveEvent.SESSION_ERROR,
2391
+ callUuid
2291
2392
  }
2292
2393
  });
2293
2394
  }
2294
2395
  if (data.event === SocketReceiveEvent.AGENT_NO_ANSWER) {
2295
- if (content?.callUuid) {
2296
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2396
+ if (callUuid) {
2397
+ this.callKit.connect.socketTriggerHangup(callUuid);
2297
2398
  }
2298
2399
  }
2299
2400
  if (data.event === SocketReceiveEvent.AGENT_HANG_UP) {
2300
- if (content?.callUuid) {
2301
- this.callKit.connect.socketTriggerHangup(content.callUuid);
2401
+ if (callUuid) {
2402
+ this.callKit.connect.socketTriggerHangup(callUuid);
2302
2403
  }
2303
2404
  }
2304
- this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);
2405
+ this.callKit.trigger(
2406
+ KitEvent.SERVER_SOCKET_EVENT,
2407
+ {
2408
+ ...data,
2409
+ callUuid
2410
+ },
2411
+ true
2412
+ );
2305
2413
  }
2306
2414
  send(event, message) {
2307
2415
  if (!this.connectAuthState.isConnected) {
@@ -2349,18 +2457,11 @@ var Socket = class {
2349
2457
  caller: "Socket.send",
2350
2458
  type: "INCALL",
2351
2459
  content: {
2352
- ...msg
2460
+ ...msg,
2461
+ userInfo
2353
2462
  }
2354
2463
  });
2355
- switch (event) {
2356
- case SocketSendEvent.PING:
2357
- this.lastPingTime = Date.now();
2358
- this.ws?.send(JSON.stringify({ event, ...msg }));
2359
- break;
2360
- default:
2361
- this.ws?.send(JSON.stringify({ event, ...msg }));
2362
- break;
2363
- }
2464
+ this.ws?.send(JSON.stringify({ event, ...msg }));
2364
2465
  }
2365
2466
  ping() {
2366
2467
  if (!this.connectAuthState.isConnected)
@@ -2381,13 +2482,15 @@ var Socket = class {
2381
2482
  errCode: ErrorCode.SOCKET_PING_TIMEOUT
2382
2483
  }
2383
2484
  });
2485
+ this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2486
+ event: "INCALL_PING_TIMEOUT"
2487
+ });
2384
2488
  }
2385
2489
  }
2386
2490
  checkPing() {
2387
2491
  if (this.pingTimer) {
2388
2492
  clearInterval(this.pingTimer);
2389
2493
  }
2390
- this.ping();
2391
2494
  const { pingInterval } = this.reconnectConfig;
2392
2495
  this.pingTimer = setInterval(() => {
2393
2496
  this.ping();
@@ -2422,6 +2525,7 @@ var Socket = class {
2422
2525
  this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
2423
2526
  event: "INCALL_RECONNECT_ERROR"
2424
2527
  });
2528
+ this.setConnectAuthState("isError", true);
2425
2529
  this.callKit.reset();
2426
2530
  this.callKit.logger.error("Maximum reconnection attempts reached", {
2427
2531
  caller: "Socket.attemptReconnect",
@@ -2550,7 +2654,8 @@ var CallKit = class {
2550
2654
  try {
2551
2655
  const user = await this.api.login({
2552
2656
  userName: username,
2553
- password: encryptionPassword
2657
+ password: encryptionPassword,
2658
+ timestamp: Date.now()
2554
2659
  });
2555
2660
  if (user) {
2556
2661
  this.config.setConfig("userInfo", {
@@ -2596,7 +2701,7 @@ var CallKit = class {
2596
2701
  if (this.config.isLogin()) {
2597
2702
  const { sessionId } = userInfo;
2598
2703
  try {
2599
- await this.api.loginOut({ sessionId });
2704
+ await this.api.loginOut({ sessionId, timestamp: Date.now() });
2600
2705
  } catch (error) {
2601
2706
  this.logger.warn(error, {
2602
2707
  caller: "CallKit.logout",
@@ -2609,7 +2714,7 @@ var CallKit = class {
2609
2714
  if (isReset) {
2610
2715
  await this.reset();
2611
2716
  } else {
2612
- this.config.reset();
2717
+ this.config.reset("logout");
2613
2718
  }
2614
2719
  }
2615
2720
  async call(extno = "", options = {
@@ -2743,7 +2848,7 @@ var CallKit = class {
2743
2848
  * set userstatus
2744
2849
  * @param status
2745
2850
  */
2746
- async setUserStatus(status) {
2851
+ async setUserStatus(status, extra = {}) {
2747
2852
  const { agentId } = this.config.getConfig().userInfo;
2748
2853
  this.logger.info("setUserStatus", {
2749
2854
  caller: "CallKit.setUserStatus",
@@ -2754,7 +2859,9 @@ var CallKit = class {
2754
2859
  });
2755
2860
  await this.api.updateUserStatus({
2756
2861
  agentId,
2757
- userStatus: status
2862
+ userStatus: status,
2863
+ timestamp: Date.now(),
2864
+ ...extra
2758
2865
  });
2759
2866
  }
2760
2867
  /**
@@ -2779,7 +2886,7 @@ var CallKit = class {
2779
2886
  if (this.config.isLogin()) {
2780
2887
  await this.logout({ isReset: false });
2781
2888
  } else {
2782
- await this.config.reset();
2889
+ await this.config.reset("reset");
2783
2890
  }
2784
2891
  await this.socket.reset({ force });
2785
2892
  }
@@ -2817,7 +2924,9 @@ var CallKit = class {
2817
2924
  if (!noLog) {
2818
2925
  this.logger.info(`Trigger Event: ${event}`, {
2819
2926
  caller: "CallKit.trigger",
2820
- content: data
2927
+ content: {
2928
+ data
2929
+ }
2821
2930
  });
2822
2931
  }
2823
2932
  this.listener.forEach((item) => {
@@ -2825,7 +2934,7 @@ var CallKit = class {
2825
2934
  try {
2826
2935
  item.callback(data);
2827
2936
  } catch (err) {
2828
- this.logger.error("Event callback error:", err, true);
2937
+ this.logger.error(`Event callback error: ${event}`, err, true);
2829
2938
  }
2830
2939
  }
2831
2940
  });