@ermis-network/ermis-chat-sdk 1.0.2 → 1.0.3
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/bin/init-call.js +52 -0
- package/dist/index.browser.cjs +164 -92
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.full-bundle.min.js +15 -15
- package/dist/index.browser.full-bundle.min.js.map +1 -1
- package/dist/index.browser.mjs +163 -92
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +164 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +26 -7
- package/dist/index.d.ts +26 -7
- package/dist/index.mjs +163 -92
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -2
- package/public/call_incoming.mp3 +0 -0
- package/public/call_outgoing.mp3 +0 -0
- package/public/ermis_call_node_wasm_bg.wasm +0 -0
- package/src/ermis_call_node.ts +77 -47
- package/src/index.ts +2 -1
- package/src/signal_message.ts +121 -71
package/bin/init-call.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// Absolute path to the files inside the installed package
|
|
6
|
+
const sourceWasm = path.join(__dirname, '../public/ermis_call_node_wasm_bg.wasm');
|
|
7
|
+
const sourceIncomingMp3 = path.join(__dirname, '../public/call_incoming.mp3');
|
|
8
|
+
const sourceOutgoingMp3 = path.join(__dirname, '../public/call_outgoing.mp3');
|
|
9
|
+
|
|
10
|
+
// Execution directory (always the root of the consumer's project)
|
|
11
|
+
const targetDir = path.join(process.cwd(), 'public');
|
|
12
|
+
const targetWasm = path.join(targetDir, 'ermis_call_node_wasm_bg.wasm');
|
|
13
|
+
const targetIncomingMp3 = path.join(targetDir, 'call_incoming.mp3');
|
|
14
|
+
const targetOutgoingMp3 = path.join(targetDir, 'call_outgoing.mp3');
|
|
15
|
+
|
|
16
|
+
console.log('🔄 Configuring WebAssembly & Audio files for Ermis Direct Call feature...');
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(sourceWasm)) {
|
|
19
|
+
console.error('❌ Error: Could not find the original Wasm file in the SDK package.');
|
|
20
|
+
console.error('Search path:', sourceWasm);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Create the public directory if it doesn't exist in the consumer project
|
|
25
|
+
if (!fs.existsSync(targetDir)) {
|
|
26
|
+
console.log('Creating public directory...');
|
|
27
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
fs.copyFileSync(sourceWasm, targetWasm);
|
|
32
|
+
console.log('✅ Successfully copied ermis_call_node_wasm_bg.wasm to your public/ directory!');
|
|
33
|
+
|
|
34
|
+
if (fs.existsSync(sourceIncomingMp3)) {
|
|
35
|
+
fs.copyFileSync(sourceIncomingMp3, targetIncomingMp3);
|
|
36
|
+
console.log('✅ Successfully copied call_incoming.mp3 to your public/ directory!');
|
|
37
|
+
} else {
|
|
38
|
+
console.warn('⚠️ Warning: call_incoming.mp3 not found in SDK, skipping copy.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (fs.existsSync(sourceOutgoingMp3)) {
|
|
42
|
+
fs.copyFileSync(sourceOutgoingMp3, targetOutgoingMp3);
|
|
43
|
+
console.log('✅ Successfully copied call_outgoing.mp3 to your public/ directory!');
|
|
44
|
+
} else {
|
|
45
|
+
console.warn('⚠️ Warning: call_outgoing.mp3 not found in SDK, skipping copy.');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log('You can now enable the Direct Call feature in your application.');
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('❌ An error occurred while copying the file:', error.message);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
package/dist/index.browser.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CallAction: () => CallAction,
|
|
34
34
|
CallStatus: () => CallStatus,
|
|
35
|
+
CallType: () => CallType,
|
|
35
36
|
Channel: () => Channel,
|
|
36
37
|
ChannelState: () => ChannelState,
|
|
37
38
|
ClientState: () => ClientState,
|
|
@@ -3666,7 +3667,7 @@ var ErmisChat = class _ErmisChat {
|
|
|
3666
3667
|
return pinExpires;
|
|
3667
3668
|
}
|
|
3668
3669
|
getUserAgent() {
|
|
3669
|
-
return this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? "node" : "browser"}-${"1.0.
|
|
3670
|
+
return this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? "node" : "browser"}-${"1.0.3"}`;
|
|
3670
3671
|
}
|
|
3671
3672
|
setUserAgent(userAgent) {
|
|
3672
3673
|
this.userAgent = userAgent;
|
|
@@ -6376,21 +6377,38 @@ var ErmisCallNode = class {
|
|
|
6376
6377
|
const mediaConstraints = await this.getMediaConstraints();
|
|
6377
6378
|
try {
|
|
6378
6379
|
const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6380
|
+
return this.applyLocalStream(stream);
|
|
6381
|
+
} catch (error) {
|
|
6382
|
+
console.warn("Error getting user media:", error?.message);
|
|
6383
|
+
if (this.callType === "video" && mediaConstraints.video) {
|
|
6384
|
+
try {
|
|
6385
|
+
const audioOnlyStream = await navigator.mediaDevices.getUserMedia({
|
|
6386
|
+
audio: mediaConstraints.audio,
|
|
6387
|
+
video: false
|
|
6388
|
+
});
|
|
6389
|
+
this.setConnectionMessage("Camera not available, using audio only");
|
|
6390
|
+
return this.applyLocalStream(audioOnlyStream);
|
|
6391
|
+
} catch {
|
|
6392
|
+
}
|
|
6383
6393
|
}
|
|
6384
|
-
if (this.
|
|
6385
|
-
this.
|
|
6394
|
+
if (typeof this.onError === "function") {
|
|
6395
|
+
this.onError("No microphone or camera found. Please check your device.");
|
|
6386
6396
|
}
|
|
6387
|
-
this.localStream = stream;
|
|
6388
|
-
return stream;
|
|
6389
|
-
} catch (error) {
|
|
6390
|
-
console.error("Error getting user media:", error);
|
|
6391
6397
|
return null;
|
|
6392
6398
|
}
|
|
6393
6399
|
}
|
|
6400
|
+
applyLocalStream(stream) {
|
|
6401
|
+
if (this.callStatus === "ended" /* ENDED */) {
|
|
6402
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
6403
|
+
this.destroy();
|
|
6404
|
+
return;
|
|
6405
|
+
}
|
|
6406
|
+
if (this.onLocalStream) {
|
|
6407
|
+
this.onLocalStream(stream);
|
|
6408
|
+
}
|
|
6409
|
+
this.localStream = stream;
|
|
6410
|
+
return stream;
|
|
6411
|
+
}
|
|
6394
6412
|
setConnectionMessage(message) {
|
|
6395
6413
|
if (typeof this.onConnectionMessageChange === "function") {
|
|
6396
6414
|
this.onConnectionMessageChange(message);
|
|
@@ -6435,20 +6453,10 @@ var ErmisCallNode = class {
|
|
|
6435
6453
|
this.isDestroyed = false;
|
|
6436
6454
|
this.callStatus = "";
|
|
6437
6455
|
this.callType = is_video ? "video" : "audio";
|
|
6438
|
-
await this.startLocalStream();
|
|
6439
|
-
if (this.callStatus === "ended" /* ENDED */) return;
|
|
6440
6456
|
this.setUserInfo(cid, eventUserId);
|
|
6441
6457
|
this.setCallStatus("ringing" /* RINGING */);
|
|
6442
6458
|
this.cid = cid || "";
|
|
6443
6459
|
this.metadata = metadata || {};
|
|
6444
|
-
console.log("----metadata---", metadata);
|
|
6445
|
-
if (eventUserId !== this.userID) {
|
|
6446
|
-
await this.initialize();
|
|
6447
|
-
}
|
|
6448
|
-
if (this.localStream && this.mediaSender && this.mediaReceiver) {
|
|
6449
|
-
this.mediaSender?.initEncoders(this.localStream);
|
|
6450
|
-
this.mediaReceiver?.initDecoders(this.callType);
|
|
6451
|
-
}
|
|
6452
6460
|
if (typeof this.onCallEvent === "function") {
|
|
6453
6461
|
this.onCallEvent({
|
|
6454
6462
|
type: eventUserId !== this.userID ? "incoming" : "outgoing",
|
|
@@ -6459,6 +6467,15 @@ var ErmisCallNode = class {
|
|
|
6459
6467
|
metadata: this.metadata
|
|
6460
6468
|
});
|
|
6461
6469
|
}
|
|
6470
|
+
await this.startLocalStream();
|
|
6471
|
+
if (this.callStatus === "ended" /* ENDED */) return;
|
|
6472
|
+
if (eventUserId !== this.userID) {
|
|
6473
|
+
await this.initialize();
|
|
6474
|
+
}
|
|
6475
|
+
if (this.localStream && this.mediaSender && this.mediaReceiver) {
|
|
6476
|
+
this.mediaSender?.initEncoders(this.localStream);
|
|
6477
|
+
this.mediaReceiver?.initDecoders(this.callType);
|
|
6478
|
+
}
|
|
6462
6479
|
if (eventUserId === this.userID) {
|
|
6463
6480
|
if (this.missCallTimeout) clearTimeout(this.missCallTimeout);
|
|
6464
6481
|
this.missCallTimeout = setTimeout(async () => {
|
|
@@ -6719,21 +6736,30 @@ var ErmisCallNode = class {
|
|
|
6719
6736
|
}
|
|
6720
6737
|
async stopScreenShare() {
|
|
6721
6738
|
const mediaConstraints = await this.getMediaConstraints();
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6739
|
+
try {
|
|
6740
|
+
const cameraStream = await navigator.mediaDevices.getUserMedia({
|
|
6741
|
+
video: mediaConstraints.video,
|
|
6742
|
+
audio: false
|
|
6743
|
+
});
|
|
6744
|
+
const cameraTrack = cameraStream.getVideoTracks()[0];
|
|
6745
|
+
if (this.localStream) {
|
|
6746
|
+
this.localStream.getVideoTracks().forEach((track) => {
|
|
6747
|
+
track.stop();
|
|
6748
|
+
this.localStream?.removeTrack(track);
|
|
6749
|
+
});
|
|
6750
|
+
this.localStream.addTrack(cameraTrack);
|
|
6751
|
+
} else {
|
|
6752
|
+
this.localStream = cameraStream;
|
|
6753
|
+
}
|
|
6754
|
+
if (this.onLocalStream) {
|
|
6755
|
+
this.onLocalStream(this.localStream);
|
|
6756
|
+
this.mediaSender?.replaceVideoTrack(this.localStream.getVideoTracks()[0]);
|
|
6757
|
+
}
|
|
6758
|
+
if (typeof this.onScreenShareChange === "function") {
|
|
6759
|
+
this.onScreenShareChange(false);
|
|
6760
|
+
}
|
|
6761
|
+
} catch (error) {
|
|
6762
|
+
console.error("Error stopping screen share and reverting to camera:", error);
|
|
6737
6763
|
}
|
|
6738
6764
|
}
|
|
6739
6765
|
async toggleMic(enabled) {
|
|
@@ -7000,7 +7026,7 @@ var ErmisAuthProvider = class {
|
|
|
7000
7026
|
return data;
|
|
7001
7027
|
}
|
|
7002
7028
|
getUserAgent() {
|
|
7003
|
-
return this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? "node" : "browser"}-${"1.0.
|
|
7029
|
+
return this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? "node" : "browser"}-${"1.0.3"}`;
|
|
7004
7030
|
}
|
|
7005
7031
|
setUserAgent(userAgent) {
|
|
7006
7032
|
this.userAgent = userAgent;
|
|
@@ -7233,71 +7259,117 @@ function parseSystemMessage(value, userMap) {
|
|
|
7233
7259
|
}
|
|
7234
7260
|
|
|
7235
7261
|
// src/signal_message.ts
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7262
|
+
var CallType = {
|
|
7263
|
+
AUDIO: "audio",
|
|
7264
|
+
VIDEO: "video"
|
|
7265
|
+
};
|
|
7266
|
+
function formatDuration(durationMs) {
|
|
7267
|
+
if (!durationMs) return "";
|
|
7268
|
+
const ms = parseInt(durationMs, 10);
|
|
7269
|
+
if (isNaN(ms) || ms <= 0) return "";
|
|
7270
|
+
const totalSeconds = Math.floor(ms / 1e3);
|
|
7271
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
7272
|
+
const seconds = totalSeconds % 60;
|
|
7273
|
+
return `${minutes} min, ${seconds} sec`;
|
|
7245
7274
|
}
|
|
7246
|
-
function parseSignalMessage(value,
|
|
7247
|
-
if (!value || typeof value !== "string") return
|
|
7275
|
+
function parseSignalMessage(value, myUserId) {
|
|
7276
|
+
if (!value || typeof value !== "string") return null;
|
|
7248
7277
|
const trimmed = value.trim();
|
|
7249
|
-
if (!trimmed) return
|
|
7278
|
+
if (!trimmed) return null;
|
|
7250
7279
|
const parts = trimmed.split(" ");
|
|
7251
|
-
const
|
|
7252
|
-
const
|
|
7253
|
-
const
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
case
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
case
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7280
|
+
const number = parseInt(parts[0], 10);
|
|
7281
|
+
const callerId = parts[1] ?? "";
|
|
7282
|
+
const isMe = myUserId === callerId;
|
|
7283
|
+
let enderId = "";
|
|
7284
|
+
let duration = "";
|
|
7285
|
+
let callType = "";
|
|
7286
|
+
let color = "";
|
|
7287
|
+
if (number === 3 || number === 6) {
|
|
7288
|
+
enderId = parts[2] ?? "";
|
|
7289
|
+
duration = parts[3] === "0" ? "" : parts[3] ?? "";
|
|
7290
|
+
}
|
|
7291
|
+
let text;
|
|
7292
|
+
switch (number) {
|
|
7293
|
+
case 1:
|
|
7294
|
+
text = isMe ? "Calling..." : "Incoming audio call...";
|
|
7295
|
+
callType = CallType.AUDIO;
|
|
7296
|
+
color = "#54D62C";
|
|
7297
|
+
break;
|
|
7298
|
+
case 2:
|
|
7299
|
+
text = isMe ? "Outgoing audio call" : "You missed audio call";
|
|
7300
|
+
callType = CallType.AUDIO;
|
|
7301
|
+
color = "#FF4842";
|
|
7302
|
+
break;
|
|
7303
|
+
case 3:
|
|
7304
|
+
if (duration) {
|
|
7305
|
+
text = isMe ? "Outgoing audio call" : "Incoming audio call";
|
|
7306
|
+
color = "#54D62C";
|
|
7307
|
+
} else {
|
|
7308
|
+
if (enderId === myUserId) {
|
|
7309
|
+
text = "You cancel audio call";
|
|
7310
|
+
} else {
|
|
7311
|
+
text = "You missed audio call";
|
|
7312
|
+
}
|
|
7313
|
+
color = "#FF4842";
|
|
7314
|
+
}
|
|
7315
|
+
callType = CallType.AUDIO;
|
|
7316
|
+
break;
|
|
7317
|
+
case 4:
|
|
7318
|
+
text = isMe ? "Calling..." : "Incoming video call...";
|
|
7319
|
+
callType = CallType.VIDEO;
|
|
7320
|
+
color = "#54D62C";
|
|
7321
|
+
break;
|
|
7322
|
+
case 5:
|
|
7323
|
+
text = isMe ? "Outgoing video call" : "You missed video call";
|
|
7324
|
+
callType = CallType.VIDEO;
|
|
7325
|
+
color = "#FF4842";
|
|
7326
|
+
break;
|
|
7327
|
+
case 6:
|
|
7328
|
+
if (duration) {
|
|
7329
|
+
text = isMe ? "Outgoing video call" : "Incoming video call";
|
|
7330
|
+
color = "#54D62C";
|
|
7331
|
+
} else {
|
|
7332
|
+
if (enderId === myUserId) {
|
|
7333
|
+
text = "You cancel video call";
|
|
7334
|
+
} else {
|
|
7335
|
+
text = "You missed video call";
|
|
7336
|
+
}
|
|
7337
|
+
color = "#FF4842";
|
|
7338
|
+
}
|
|
7339
|
+
callType = CallType.VIDEO;
|
|
7340
|
+
break;
|
|
7341
|
+
case 7:
|
|
7342
|
+
text = isMe ? "Recipient rejected audio call" : "You rejected audio call";
|
|
7343
|
+
callType = CallType.AUDIO;
|
|
7344
|
+
color = "#FF4842";
|
|
7345
|
+
break;
|
|
7346
|
+
case 8:
|
|
7347
|
+
text = isMe ? "Recipient rejected video call" : "You rejected video call";
|
|
7348
|
+
callType = CallType.VIDEO;
|
|
7349
|
+
color = "#FF4842";
|
|
7350
|
+
break;
|
|
7351
|
+
case 9:
|
|
7352
|
+
text = isMe ? "Recipient was busy" : "You missed audio call";
|
|
7353
|
+
callType = CallType.AUDIO;
|
|
7354
|
+
color = "#FF4842";
|
|
7355
|
+
break;
|
|
7356
|
+
case 10:
|
|
7357
|
+
text = isMe ? "Recipient was busy" : "You missed video call";
|
|
7358
|
+
callType = CallType.VIDEO;
|
|
7359
|
+
color = "#FF4842";
|
|
7360
|
+
break;
|
|
7293
7361
|
default:
|
|
7294
|
-
|
|
7362
|
+
text = trimmed;
|
|
7363
|
+
callType = "";
|
|
7364
|
+
color = "";
|
|
7295
7365
|
}
|
|
7366
|
+
return { text, duration: formatDuration(duration), callType, color };
|
|
7296
7367
|
}
|
|
7297
7368
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7298
7369
|
0 && (module.exports = {
|
|
7299
7370
|
CallAction,
|
|
7300
7371
|
CallStatus,
|
|
7372
|
+
CallType,
|
|
7301
7373
|
Channel,
|
|
7302
7374
|
ChannelState,
|
|
7303
7375
|
ClientState,
|