Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

simli-client

Package Overview
Dependencies
Maintainers
2
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

simli-client - npm Package Compare versions

Comparing version
1.2.15
to
1.2.16
+2
-0
dist/SimliClient.d.ts

@@ -15,2 +15,3 @@ interface SimliClientConfig {

videoReceivedTimeout: number | 15000;
enableSFU: boolean | true;
model: "fasttalk" | "artalk" | "";

@@ -70,2 +71,3 @@ }

private SimliURL;
private enableSFU;
isAvatarSpeaking: boolean;

@@ -72,0 +74,0 @@ enableConsoleLogs: boolean;

+32
-17

@@ -66,2 +66,3 @@ "use strict";

this.SimliURL = "";
this.enableSFU = true;
this.isAvatarSpeaking = false;

@@ -105,3 +106,3 @@ this.enableConsoleLogs = false;

var _a;
(_a = this.events.get(event)) === null || _a === void 0 ? void 0 : _a.forEach(callback => {
(_a = this.events.get(event)) === null || _a === void 0 ? void 0 : _a.forEach((callback) => {
callback(...args);

@@ -112,3 +113,4 @@ });

var _a, _b, _c, _d;
if ((!config.apiKey || config.apiKey === "") && (!config.session_token || config.session_token === "")) {
if ((!config.apiKey || config.apiKey === "") &&
(!config.session_token || config.session_token === "")) {
console.error("SIMLI: apiKey or session_token is required in config");

@@ -125,5 +127,8 @@ throw new Error("apiKey or session_token is required in config");

this.session_token = config.session_token;
this.MAX_RETRY_ATTEMPTS = (_b = config.maxRetryAttempts) !== null && _b !== void 0 ? _b : this.MAX_RETRY_ATTEMPTS;
this.MAX_RETRY_ATTEMPTS =
(_b = config.maxRetryAttempts) !== null && _b !== void 0 ? _b : this.MAX_RETRY_ATTEMPTS;
this.RETRY_DELAY = (_c = config.retryDelay_ms) !== null && _c !== void 0 ? _c : this.RETRY_DELAY;
this.VIDEO_TIMEOUT = (_d = config.videoReceivedTimeout) !== null && _d !== void 0 ? _d : this.VIDEO_TIMEOUT;
if (config.enableSFU)
this.enableSFU = config.enableSFU;
if (config.model !== "") {

@@ -177,3 +182,3 @@ this.model = config.model;

if (attempt < this.MAX_RETRY_ATTEMPTS) {
await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY));
await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY));
return this.getIceServers(apiKey, SimliURL, attempt + 1);

@@ -293,3 +298,3 @@ }

maxIdleTime: this.maxIdleTime,
model: this.model
model: this.model,
};

@@ -304,3 +309,3 @@ // Get All POST request related data at the same time

}
const url = `ws${this.SimliURL}/StartWebRTCSession`;
const url = `ws${this.SimliURL}/StartWebRTCSession?enableSFU=${this.enableSFU}`;
const ws = new WebSocket(url);

@@ -327,4 +332,8 @@ this.webSocket = ws;

this.setupConnectionStateHandler();
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.addTransceiver("audio", { direction: "recvonly" });
(_b = this.pc) === null || _b === void 0 ? void 0 : _b.addTransceiver("video", { direction: "recvonly" });
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.addTransceiver("audio", {
direction: "recvonly",
});
(_b = this.pc) === null || _b === void 0 ? void 0 : _b.addTransceiver("video", {
direction: "recvonly",
});
await this.negotiate();

@@ -352,3 +361,3 @@ }

await this.cleanup();
await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY));
await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY));
this.retryAttempt += 1;

@@ -391,3 +400,4 @@ return this.start(iceServers, this.retryAttempt);

var _a, _b;
if (this.webSocket && this.webSocket.readyState === this.webSocket.OPEN) {
if (this.webSocket &&
this.webSocket.readyState === this.webSocket.OPEN) {
const message = "ping " + Date.now();

@@ -443,3 +453,4 @@ this.pingSendTimes.set(message, Date.now());

try {
if (this.webSocket && this.webSocket.readyState === this.webSocket.OPEN) {
if (this.webSocket &&
this.webSocket.readyState === this.webSocket.OPEN) {
(_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.send(sessionToken);

@@ -541,3 +552,3 @@ }

.then(() => this.start())
.catch(error => {
.catch((error) => {
if (this.enableConsoleLogs)

@@ -614,3 +625,5 @@ console.error("SIMLI: Reconnection failed:", error);

audioContext.audioWorklet
.addModule(URL.createObjectURL(new Blob([AudioProcessor], { type: "application/javascript" })))
.addModule(URL.createObjectURL(new Blob([AudioProcessor], {
type: "application/javascript",
})))
.then(() => {

@@ -629,3 +642,3 @@ this.audioWorklet = new AudioWorkletNode(audioContext, "audio-processor");

})
.catch(error => {
.catch((error) => {
if (this.enableConsoleLogs)

@@ -653,3 +666,4 @@ console.error("SIMLI: Failed to initialize AudioWorklet:", error);

const timeBetweenSends = currentTime - this.lastSendTime;
if (timeBetweenSends > 100) { // Log only if significant delay
if (timeBetweenSends > 100) {
// Log only if significant delay
if (this.enableConsoleLogs)

@@ -690,3 +704,4 @@ console.log("SIMLI: Time between sends:", timeBetweenSends);

const timeBetweenSends = currentTime - this.lastSendTime;
if (timeBetweenSends > 100) { // Log only if significant delay
if (timeBetweenSends > 100) {
// Log only if significant delay
if (this.enableConsoleLogs)

@@ -739,3 +754,3 @@ console.log("SIMLI: Time between sends:", timeBetweenSends);

while (!this.localDescription) {
await new Promise(resolve => setTimeout(resolve, 50));
await new Promise((resolve) => setTimeout(resolve, 50));
}

@@ -742,0 +757,0 @@ await ws.send(JSON.stringify(this.localDescription));

@@ -29,3 +29,3 @@ // src/index.ts

registerProcessor('audio-processor', AudioProcessor);
`
`;

@@ -50,2 +50,3 @@ // Custom event handler types

videoReceivedTimeout: number | 15000;
enableSFU: boolean | true;
model: "fasttalk" | "artalk" | "";

@@ -61,7 +62,7 @@ }

maxIdleTime: number;
model: "fasttalk" | "artalk"
model: "fasttalk" | "artalk";
}
interface SimliSessionToken {
session_token: string
session_token: string;
}

@@ -108,2 +109,3 @@ interface SimliClientEvents {

private SimliURL: string = "";
private enableSFU: boolean = true;
public isAvatarSpeaking: boolean = false;

@@ -139,3 +141,3 @@ public enableConsoleLogs: boolean = false;

): void {
this.events.get(event)?.forEach(callback => {
this.events.get(event)?.forEach((callback) => {
callback(...args);

@@ -146,4 +148,9 @@ });

public Initialize(config: SimliClientConfig) {
if ((!config.apiKey || config.apiKey === "") && (!config.session_token || config.session_token === "")) {
console.error("SIMLI: apiKey or session_token is required in config");
if (
(!config.apiKey || config.apiKey === "") &&
(!config.session_token || config.session_token === "")
) {
console.error(
"SIMLI: apiKey or session_token is required in config"
);
throw new Error("apiKey or session_token is required in config");

@@ -159,5 +166,8 @@ }

this.session_token = config.session_token;
this.MAX_RETRY_ATTEMPTS = config.maxRetryAttempts ?? this.MAX_RETRY_ATTEMPTS;
this.MAX_RETRY_ATTEMPTS =
config.maxRetryAttempts ?? this.MAX_RETRY_ATTEMPTS;
this.RETRY_DELAY = config.retryDelay_ms ?? this.RETRY_DELAY;
this.VIDEO_TIMEOUT = config.videoReceivedTimeout ?? this.VIDEO_TIMEOUT;
if (config.enableSFU)
this.enableSFU = config.enableSFU;
if (config.model !== "") {

@@ -168,4 +178,3 @@ this.model = config.model;

this.SimliURL = "s://api.simli.ai";
}
else {
} else {
this.SimliURL = config.SimliURL;

@@ -177,6 +186,10 @@ }

if (!(this.videoRef instanceof HTMLVideoElement)) {
console.error("SIMLI: videoRef is required in config as HTMLVideoElement");
console.error(
"SIMLI: videoRef is required in config as HTMLVideoElement"
);
}
if (!(this.audioRef instanceof HTMLAudioElement)) {
console.error("SIMLI: audioRef is required in config as HTMLAudioElement");
console.error(
"SIMLI: audioRef is required in config as HTMLAudioElement"
);
}

@@ -191,3 +204,7 @@ console.log("SIMLI: simli-client@1.2.15 initialized");

public async getIceServers(apiKey: string, SimliURL: string, attempt = 1): Promise<RTCIceServer[]> {
public async getIceServers(
apiKey: string,
SimliURL: string,
attempt = 1
): Promise<RTCIceServer[]> {
try {

@@ -202,3 +219,9 @@ const url = `http${SimliURL}/getIceServers`;

new Promise((_, reject) =>
setTimeout(() => reject(new Error("SIMLI: ICE server request timeout")), 5000)
setTimeout(
() =>
reject(
new Error("SIMLI: ICE server request timeout")
),
5000
)
),

@@ -208,3 +231,5 @@ ]);

if (!response.ok) {
throw new Error(`SIMLI: HTTP error! status: ${response.status}`);
throw new Error(
`SIMLI: HTTP error! status: ${response.status}`
);
}

@@ -218,10 +243,17 @@

} catch (error) {
if (this.enableConsoleLogs) console.warn(`SIMLI: ICE servers fetch attempt ${attempt} failed:`, error);
if (this.enableConsoleLogs)
console.warn(
`SIMLI: ICE servers fetch attempt ${attempt} failed:`,
error
);
if (attempt < this.MAX_RETRY_ATTEMPTS) {
await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY));
await new Promise((resolve) =>
setTimeout(resolve, this.RETRY_DELAY)
);
return this.getIceServers(apiKey, SimliURL, attempt + 1);
}
if (this.enableConsoleLogs) console.log("SIMLI: Using fallback STUN server");
if (this.enableConsoleLogs)
console.log("SIMLI: Using fallback STUN server");
return [{ urls: ["stun:stun.l.google.com:19302"] }];

@@ -231,6 +263,8 @@ }

private async createPeerConnection(iceServers: RTCIceServer[] = [], videoReceivedPromise: () => void) {
private async createPeerConnection(
iceServers: RTCIceServer[] = [],
videoReceivedPromise: () => void
) {
if (this.pc) {
this.pc.close()
this.pc.close();
}

@@ -241,3 +275,4 @@ const config = {

};
if (this.enableConsoleLogs) console.log("SIMLI: Server running: ", config.iceServers);
if (this.enableConsoleLogs)
console.log("SIMLI: Server running: ", config.iceServers);

@@ -255,13 +290,20 @@ this.pc = new window.RTCPeerConnection(config);

this.pc.addEventListener("icegatheringstatechange", () => {
if (this.enableConsoleLogs) console.log("SIMLI: ICE gathering state changed: ", this.pc?.iceGatheringState);
if (this.enableConsoleLogs)
console.log(
"SIMLI: ICE gathering state changed: ",
this.pc?.iceGatheringState
);
});
this.pc.addEventListener("iceconnectionstatechange", () => {
if (this.enableConsoleLogs) console.log("SIMLI: ICE connection state changed: ", this.pc?.iceConnectionState);
if (this.enableConsoleLogs)
console.log(
"SIMLI: ICE connection state changed: ",
this.pc?.iceConnectionState
);
if (this.pc?.iceConnectionState === "failed") {
if (this.retryAttempt < this.MAX_RETRY_ATTEMPTS) {
this.retryAttempt += 1;
this.start(this.inputIceServers, this.retryAttempt)
}
else {
this.start(this.inputIceServers, this.retryAttempt);
} else {
this.handleConnectionFailure("ICE connection failed");

@@ -273,12 +315,17 @@ }

this.pc.addEventListener("signalingstatechange", () => {
if (this.enableConsoleLogs) console.log("SIMLI: Signaling state changed: ", this.pc?.signalingState);
if (this.enableConsoleLogs)
console.log(
"SIMLI: Signaling state changed: ",
this.pc?.signalingState
);
});
this.pc.addEventListener("track", (evt) => {
if (this.enableConsoleLogs) console.log("SIMLI: Track event: ", evt.track.kind);
if (this.enableConsoleLogs)
console.log("SIMLI: Track event: ", evt.track.kind);
if (evt.track.kind === "video" && this.videoRef) {
this.videoRef.srcObject = evt.streams[0];
this.videoRef.requestVideoFrameCallback(() => {
videoReceivedResolve()
})
videoReceivedResolve();
});
} else if (evt.track.kind === "audio" && this.audioRef) {

@@ -303,3 +350,7 @@ this.audioRef.srcObject = evt.streams[0];

this.pc.addEventListener("connectionstatechange", () => {
if (this.enableConsoleLogs) console.log("SIMLI: Connection state changed to:", this.pc?.connectionState);
if (this.enableConsoleLogs)
console.log(
"SIMLI: Connection state changed to:",
this.pc?.connectionState
);

@@ -325,6 +376,7 @@ switch (this.pc?.connectionState) {

async start(
iceServers: RTCIceServer[] = [], retryAttempt = 1
iceServers: RTCIceServer[] = [],
retryAttempt = 1
): Promise<void> {
try {
await this.cleanup()
await this.cleanup();
this.clearTimeouts();

@@ -334,6 +386,5 @@ // Set overall connection timeout

this.handleConnectionTimeout();
}, this.CONNECTION_TIMEOUT_MS)
}, this.CONNECTION_TIMEOUT_MS);
this.inputIceServers = iceServers
this.inputIceServers = iceServers;
if (iceServers.length === 0) {

@@ -348,15 +399,13 @@ const metadata = {

maxIdleTime: this.maxIdleTime,
model: this.model
model: this.model,
};
// Get All POST request related data at the same time
const sessionRunData = await Promise.all(
[
this.getIceServers(this.apiKey, this.SimliURL),
this.createSessionToken(this.SimliURL, metadata),
]
)
iceServers = sessionRunData[0]
this.session_token = sessionRunData[1].session_token
const sessionRunData = await Promise.all([
this.getIceServers(this.apiKey, this.SimliURL),
this.createSessionToken(this.SimliURL, metadata),
]);
iceServers = sessionRunData[0];
this.session_token = sessionRunData[1].session_token;
}
const url = `ws${this.SimliURL}/StartWebRTCSession`;
const url = `ws${this.SimliURL}/StartWebRTCSession?enableSFU=${this.enableSFU}`;
const ws = new WebSocket(url);

@@ -366,3 +415,3 @@ this.webSocket = ws;

if (!this.webSocket) {
return
return;
}

@@ -375,40 +424,69 @@ this.setupWebSocketListeners(this.webSocket, resolve);

new Promise((_, reject) =>
setTimeout(() => reject(new Error("SIMLI: WebSocket connection timeout")), 5000)
setTimeout(
() =>
reject(
new Error("SIMLI: WebSocket connection timeout")
),
5000
)
),
]);
const videoReceivedPromise = new Promise<void>(async (resolve, reject) => {
try {
await this.createPeerConnection(iceServers, resolve);
const parameters = { ordered: true };
this.dc = this.pc!.createDataChannel("chat", parameters);
const videoReceivedPromise = new Promise<void>(
async (resolve, reject) => {
try {
await this.createPeerConnection(iceServers, resolve);
const parameters = { ordered: true };
this.dc = this.pc!.createDataChannel(
"chat",
parameters
);
this.setupDataChannelListeners();
this.setupConnectionStateHandler();
this.pc?.addTransceiver("audio", { direction: "recvonly" });
this.pc?.addTransceiver("video", { direction: "recvonly" });
await this.negotiate();
this.setupDataChannelListeners();
this.setupConnectionStateHandler();
this.pc?.addTransceiver("audio", {
direction: "recvonly",
});
this.pc?.addTransceiver("video", {
direction: "recvonly",
});
await this.negotiate();
} catch (error) {
reject();
}
}
catch (error) {
reject()
}
})
);
await Promise.race([
videoReceivedPromise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error("SIMLI: Video connection timeout")), this.VIDEO_TIMEOUT)
setTimeout(
() =>
reject(
new Error("SIMLI: Video connection timeout")
),
this.VIDEO_TIMEOUT
)
),
]);
console.log("CONNECTED")
console.log("CONNECTED");
// Clear timeout if connection successful
this.clearTimeouts();
} catch (error) {
if (this.enableConsoleLogs) console.error(`SIMLI: Connection attempt ${retryAttempt} failed:`, error);
if (this.enableConsoleLogs)
console.error(
`SIMLI: Connection attempt ${retryAttempt} failed:`,
error
);
this.clearTimeouts();
if (this.retryAttempt < this.MAX_RETRY_ATTEMPTS) {
if (this.enableConsoleLogs) console.log(`SIMLI: Retrying connection... Attempt ${retryAttempt + 1}`);
if (this.enableConsoleLogs)
console.log(
`SIMLI: Retrying connection... Attempt ${retryAttempt + 1
}`
);
await this.cleanup();
await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY));
await new Promise((resolve) =>
setTimeout(resolve, this.RETRY_DELAY)
);
this.retryAttempt += 1;

@@ -418,3 +496,6 @@ return this.start(iceServers, this.retryAttempt);

this.emit("failed", `Failed to connect after ${this.MAX_RETRY_ATTEMPTS} attempts`);
this.emit(
"failed",
`Failed to connect after ${this.MAX_RETRY_ATTEMPTS} attempts`
);
throw error;

@@ -428,3 +509,4 @@ }

this.dc.addEventListener("close", () => {
if (this.enableConsoleLogs) console.log("SIMLI: Data channel closed");
if (this.enableConsoleLogs)
console.log("SIMLI: Data channel closed");
this.emit("disconnected");

@@ -435,3 +517,4 @@ this.stopDataChannelInterval();

this.dc.addEventListener("error", (error) => {
if (this.enableConsoleLogs) console.error("SIMLI: Data channel error:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Data channel error:", error);
this.emit("disconnected");

@@ -457,3 +540,6 @@ this.handleConnectionFailure("Data channel error");

private sendPingMessage() {
if (this.webSocket && this.webSocket.readyState === this.webSocket.OPEN) {
if (
this.webSocket &&
this.webSocket.readyState === this.webSocket.OPEN
) {
const message = "ping " + Date.now();

@@ -464,3 +550,4 @@ this.pingSendTimes.set(message, Date.now());

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to send message:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Failed to send message:", error);
this.stopDataChannelInterval();

@@ -470,8 +557,10 @@ this.handleConnectionFailure("Failed to send ping message");

} else {
if (this.enableConsoleLogs) console.warn(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState
);
if (this.enableConsoleLogs)
console.warn(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState
);
if (this.errorReason !== null) {
if (this.enableConsoleLogs) console.error("SIMLI: Error Reason: ", this.errorReason);
if (this.enableConsoleLogs)
console.error("SIMLI: Error Reason: ", this.errorReason);
}

@@ -482,16 +571,18 @@ this.stopDataChannelInterval();

public async createSessionToken(SimliURL: string, metadata: SimliSessionRequest): Promise<SimliSessionToken> {
if (this.session_token && this.session_token !== "") { return { session_token: this.session_token } }
public async createSessionToken(
SimliURL: string,
metadata: SimliSessionRequest
): Promise<SimliSessionToken> {
if (this.session_token && this.session_token !== "") {
return { session_token: this.session_token };
}
try {
const url = `http${SimliURL}/startAudioToVideoSession`;
const response = await fetch(
url,
{
method: "POST",
body: JSON.stringify(metadata),
headers: {
"Content-Type": "application/json",
},
}
);
const response = await fetch(url, {
method: "POST",
body: JSON.stringify(metadata),
headers: {
"Content-Type": "application/json",
},
});

@@ -506,3 +597,5 @@ if (!response.ok) {

} catch (error) {
this.handleConnectionFailure(`Session initialization failed: ${error}`);
this.handleConnectionFailure(
`Session initialization failed: ${error}`
);
throw error;

@@ -513,9 +606,16 @@ }

try {
if (this.webSocket && this.webSocket.readyState === this.webSocket.OPEN) {
if (
this.webSocket &&
this.webSocket.readyState === this.webSocket.OPEN
) {
this.webSocket?.send(sessionToken);
} else {
throw new Error("WebSocket not open when trying to send session token");
throw new Error(
"WebSocket not open when trying to send session token"
);
}
} catch (error) {
this.handleConnectionFailure(`Session initialization failed: ${error}`);
this.handleConnectionFailure(
`Session initialization failed: ${error}`
);
throw error;

@@ -541,13 +641,15 @@ }

// Wait for answer with timeout
let timeoutId: NodeJS.Timeout;
this.answer = null
this.answer = null;
await Promise.race([
new Promise<void>((resolve, reject) => {
timeoutId = setTimeout(() => reject(new Error("Answer timeout A")), 10000);
timeoutId = setTimeout(
() => reject(new Error("Answer timeout A")),
10000
);
const checkAnswer = async () => {
if (!this.pc) {
reject()
return
reject();
return;
}

@@ -557,3 +659,5 @@ if (this.answer) {

resolve();
await this.pc!.setRemoteDescription(new RTCSessionDescription(this.answer));
await this.pc!.setRemoteDescription(
new RTCSessionDescription(this.answer)
);
} else {

@@ -566,6 +670,8 @@ setTimeout(checkAnswer, 100);

new Promise((_, reject) =>
setTimeout(() => reject(new Error("SIMLI: Answer timeout B")), 10000)
setTimeout(
() => reject(new Error("SIMLI: Answer timeout B")),
10000
)
),
]);
} catch (error) {

@@ -610,3 +716,4 @@ this.handleConnectionFailure(`SIMLI: Negotiation failed: ${error}`);

this.errorReason = reason;
if (this.enableConsoleLogs) console.error("SIMLI: connection failure:", reason);
if (this.enableConsoleLogs)
console.error("SIMLI: connection failure:", reason);
this.emit("failed", reason);

@@ -622,7 +729,11 @@ this.cleanup();

if (this.sessionInitialized) {
if (this.enableConsoleLogs) console.log("SIMLI: Connection lost, attempting to reconnect...");
if (this.enableConsoleLogs)
console.log(
"SIMLI: Connection lost, attempting to reconnect..."
);
this.cleanup()
.then(() => this.start())
.catch(error => {
if (this.enableConsoleLogs) console.error("SIMLI: Reconnection failed:", error);
.catch((error) => {
if (this.enableConsoleLogs)
console.error("SIMLI: Reconnection failed:", error);
this.emit("failed", "Reconnection failed");

@@ -634,6 +745,4 @@ });

private async cleanup() {
if (this.videoRef)
this.videoRef.srcObject = null
if (this.audioRef)
this.audioRef.srcObject = null
if (this.videoRef) this.videoRef.srcObject = null;
if (this.audioRef) this.audioRef.srcObject = null;

@@ -680,7 +789,6 @@ if (this.webSocket) {

this.stopDataChannelInterval();
this.answer = null
this.answer = null;
if (this.config) {
this.Initialize(this.config);
}
}

@@ -704,3 +812,7 @@

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to initialize audio stream:", error);
if (this.enableConsoleLogs)
console.error(
"SIMLI: Failed to initialize audio stream:",
error
);
this.emit("failed", "Audio initialization failed");

@@ -717,3 +829,5 @@ }

URL.createObjectURL(
new Blob([AudioProcessor], { type: "application/javascript" })
new Blob([AudioProcessor], {
type: "application/javascript",
})
)

@@ -735,8 +849,14 @@ )

if (event.data.type === "audioData") {
this.sendAudioData(new Uint8Array(event.data.data.buffer));
this.sendAudioData(
new Uint8Array(event.data.data.buffer)
);
}
};
})
.catch(error => {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to initialize AudioWorklet:", error);
.catch((error) => {
if (this.enableConsoleLogs)
console.error(
"SIMLI: Failed to initialize AudioWorklet:",
error
);
this.emit("failed", "AudioWorklet initialization failed");

@@ -748,3 +868,6 @@ });

if (!this.sessionInitialized) {
if (this.enableConsoleLogs) console.log("SIMLI: Session not initialized. Ignoring audio data.");
if (this.enableConsoleLogs)
console.log(
"SIMLI: Session not initialized. Ignoring audio data."
);
return;

@@ -754,8 +877,9 @@ }

if (this.webSocket?.readyState !== WebSocket.OPEN) {
if (this.enableConsoleLogs) console.error(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState,
"Error Reason:",
this.errorReason
);
if (this.enableConsoleLogs)
console.error(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState,
"Error Reason:",
this.errorReason
);
return;

@@ -769,4 +893,9 @@ }

const timeBetweenSends = currentTime - this.lastSendTime;
if (timeBetweenSends > 100) { // Log only if significant delay
if (this.enableConsoleLogs) console.log("SIMLI: Time between sends:", timeBetweenSends);
if (timeBetweenSends > 100) {
// Log only if significant delay
if (this.enableConsoleLogs)
console.log(
"SIMLI: Time between sends:",
timeBetweenSends
);
}

@@ -776,3 +905,4 @@ }

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to send audio data:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Failed to send audio data:", error);
this.handleConnectionFailure("Failed to send audio data");

@@ -784,3 +914,6 @@ }

if (!this.sessionInitialized) {
if (this.enableConsoleLogs) console.log("SIMLI: Session not initialized. Ignoring audio data.");
if (this.enableConsoleLogs)
console.log(
"SIMLI: Session not initialized. Ignoring audio data."
);
return;

@@ -790,8 +923,9 @@ }

if (this.webSocket?.readyState !== WebSocket.OPEN) {
if (this.enableConsoleLogs) console.error(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState,
"Error Reason:",
this.errorReason
);
if (this.enableConsoleLogs)
console.error(
"SIMLI: WebSocket is not open. Current state:",
this.webSocket?.readyState,
"Error Reason:",
this.errorReason
);
return;

@@ -812,4 +946,9 @@ }

const timeBetweenSends = currentTime - this.lastSendTime;
if (timeBetweenSends > 100) { // Log only if significant delay
if (this.enableConsoleLogs) console.log("SIMLI: Time between sends:", timeBetweenSends);
if (timeBetweenSends > 100) {
// Log only if significant delay
if (this.enableConsoleLogs)
console.log(
"SIMLI: Time between sends:",
timeBetweenSends
);
}

@@ -819,3 +958,4 @@ }

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to send audio data:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Failed to send audio data:", error);
this.handleConnectionFailure("Failed to send audio data");

@@ -826,5 +966,5 @@ }

close() {
if (this.enableConsoleLogs) console.log("SIMLI: Closing SimliClient connection");
if (this.webSocket)
this.webSocket.send("DONE")
if (this.enableConsoleLogs)
console.log("SIMLI: Closing SimliClient connection");
if (this.webSocket) this.webSocket.send("DONE");
this.emit("disconnected");

@@ -835,3 +975,4 @@

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Error during cleanup:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Error during cleanup:", error);
}

@@ -845,6 +986,8 @@ }

} catch (error) {
if (this.enableConsoleLogs) console.error("SIMLI: Failed to clear buffer:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: Failed to clear buffer:", error);
}
} else {
if (this.enableConsoleLogs) console.warn("SIMLI: Cannot clear buffer: WebSocket not open");
if (this.enableConsoleLogs)
console.warn("SIMLI: Cannot clear buffer: WebSocket not open");
}

@@ -877,8 +1020,10 @@ };

private setupWebSocketListeners(ws: WebSocket, wsConnectResolve: () => void) {
private setupWebSocketListeners(
ws: WebSocket,
wsConnectResolve: () => void
) {
ws.addEventListener("open", async () => {
wsConnectResolve();
while (!this.localDescription) {
await new Promise(resolve => setTimeout(resolve, 50));
await new Promise((resolve) => setTimeout(resolve, 50));
}

@@ -897,5 +1042,8 @@ await ws.send(JSON.stringify(this.localDescription));

if (!this.session_token || this.session_token === "") {
await this.sendSessionToken((await this.createSessionToken(this.SimliURL, metadata)).session_token)
}
else {
await this.sendSessionToken(
(
await this.createSessionToken(this.SimliURL, metadata)
).session_token
);
} else {
await this.sendSessionToken(this.session_token);

@@ -906,6 +1054,5 @@ }

ws.addEventListener("message", async (evt) => {
if (this.enableConsoleLogs) console.log("SIMLI: Received message: ", evt.data);
if (this.enableConsoleLogs)
console.log("SIMLI: Received message: ", evt.data);
try {

@@ -916,10 +1063,16 @@ if (evt.data === "START") {

this.emit("connected");
console.log("START")
console.log(new Date().getTime())
console.log("START");
console.log(new Date().getTime());
} else if (evt.data === "STOP") {
this.close();
} else if (evt.data.startsWith("pong")) {
const pingTime = this.pingSendTimes.get(evt.data.replace("pong", "ping"));
const pingTime = this.pingSendTimes.get(
evt.data.replace("pong", "ping")
);
if (pingTime) {
if (this.enableConsoleLogs) console.log("SIMLI: Simli Latency: ", Date.now() - pingTime);
if (this.enableConsoleLogs)
console.log(
"SIMLI: Simli Latency: ",
Date.now() - pingTime
);
}

@@ -941,10 +1094,14 @@ } else if (evt.data === "ACK") {

} catch (e) {
if (this.enableConsoleLogs) console.warn("SIMLI: Error processing WebSocket message:", e);
if (this.enableConsoleLogs)
console.warn(
"SIMLI: Error processing WebSocket message:",
e
);
}
});
ws.addEventListener("error", (error) => {
if (this.enableConsoleLogs) console.error("SIMLI: WebSocket error:", error);
if (this.enableConsoleLogs)
console.error("SIMLI: WebSocket error:", error);
this.emit("disconnected");
this.handleConnectionFailure("WebSocket error");
});

@@ -960,2 +1117,1 @@

export { SimliClient, SimliClientConfig, SimliClientEvents };
{
"name": "simli-client",
"version": "1.2.15",
"description": "Simli WebRTC Client",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "jest"
},
"keywords": [
"simli",
"webrtc",
"faces",
"ai"
],
"author": "Simli",
"license": "MIT",
"files": [
"/dist",
"/lib"
],
"repository": {
"type": "git",
"url": "git+https://github.com/simliai/simli-client.git"
},
"bugs": {
"url": "https://github.com/simliai/simli-client/issues"
},
"homepage": "https://github.com/simliai/simli-client#readme",
"devDependencies": {
"@types/node": "^20.14.11",
"@types/react": "^18.3.3",
"terser-webpack-plugin": "^5.3.11",
"ts-loader": "^9.5.2",
"typescript": "^5.7.3"
}
"name": "simli-client",
"version": "1.2.16",
"description": "Simli WebRTC Client",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "jest"
},
"keywords": [
"simli",
"webrtc",
"faces",
"ai"
],
"author": "Simli",
"license": "MIT",
"files": [
"/dist",
"/lib"
],
"repository": {
"type": "git",
"url": "git+https://github.com/simliai/simli-client.git"
},
"bugs": {
"url": "https://github.com/simliai/simli-client/issues"
},
"homepage": "https://github.com/simliai/simli-client#readme",
"devDependencies": {
"@types/node": "^20.14.11",
"@types/react": "^18.3.3",
"terser-webpack-plugin": "^5.3.11",
"ts-loader": "^9.5.2",
"typescript": "^5.7.3"
}
}