@craftedxp/voice-js 0.4.1 → 0.4.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/browser.mjs CHANGED
@@ -916,8 +916,49 @@ async function createWebRtcCall(opts) {
916
916
  const gateway = opts.webrtcGatewayBase || "";
917
917
  const offerUrl = gateway ? `${gateway}/webrtc/offer?token=${encodeURIComponent(opts.token)}` : `${opts.apiBase}/v1/agents/${encodeURIComponent(opts.agentId)}/webrtc/offer?token=${encodeURIComponent(opts.token)}`;
918
918
  const iceUrl = gateway ? `${gateway}/webrtc/ice?token=${encodeURIComponent(opts.token)}` : `${opts.apiBase}/v1/agents/${encodeURIComponent(opts.agentId)}/webrtc/ice?token=${encodeURIComponent(opts.token)}`;
919
+ const teardown = () => {
920
+ if (ended) return;
921
+ ended = true;
922
+ try {
923
+ mic.getTracks().forEach((t) => t.stop());
924
+ } catch {
925
+ }
926
+ try {
927
+ pc.close();
928
+ } catch {
929
+ }
930
+ try {
931
+ audioEl.remove();
932
+ } catch {
933
+ }
934
+ fireState("ended");
935
+ opts.onEnd?.();
936
+ };
937
+ let callId = null;
938
+ const pendingCandidates = [];
939
+ const postCandidate = (candidate) => {
940
+ void fetch(iceUrl, {
941
+ method: "POST",
942
+ headers: { "content-type": "application/json" },
943
+ body: JSON.stringify({ callId, candidate })
944
+ }).catch(() => {
945
+ });
946
+ };
947
+ pc.onicecandidate = (e) => {
948
+ if (!e.candidate) return;
949
+ if (callId) postCandidate(e.candidate);
950
+ else pendingCandidates.push(e.candidate);
951
+ };
952
+ pc.onconnectionstatechange = () => {
953
+ const s = pc.connectionState;
954
+ if (s === "connected") fireState("listening");
955
+ if (s === "failed" || s === "disconnected") {
956
+ opts.onError?.({ code: "socket_error", message: `webrtc connection ${s}` });
957
+ teardown();
958
+ }
959
+ if (s === "closed" && !ended) teardown();
960
+ };
919
961
  await pc.setLocalDescription(await pc.createOffer());
920
- let callId;
921
962
  try {
922
963
  const offerRes = await fetch(offerUrl, {
923
964
  method: "POST",
@@ -936,6 +977,7 @@ async function createWebRtcCall(opts) {
936
977
  const body = await offerRes.json();
937
978
  callId = body.callId;
938
979
  await pc.setRemoteDescription({ type: "answer", sdp: body.sdp });
980
+ while (pendingCandidates.length > 0) postCandidate(pendingCandidates.shift());
939
981
  } catch (err) {
940
982
  if (!ended) {
941
983
  opts.onError?.({
@@ -949,42 +991,6 @@ async function createWebRtcCall(opts) {
949
991
  }
950
992
  throw err;
951
993
  }
952
- pc.onicecandidate = (e) => {
953
- if (!e.candidate) return;
954
- void fetch(iceUrl, {
955
- method: "POST",
956
- headers: { "content-type": "application/json" },
957
- body: JSON.stringify({ callId, candidate: e.candidate })
958
- }).catch(() => {
959
- });
960
- };
961
- pc.onconnectionstatechange = () => {
962
- const s = pc.connectionState;
963
- if (s === "connected") fireState("listening");
964
- if (s === "failed" || s === "disconnected") {
965
- opts.onError?.({ code: "socket_error", message: `webrtc connection ${s}` });
966
- teardown();
967
- }
968
- if (s === "closed" && !ended) teardown();
969
- };
970
- const teardown = () => {
971
- if (ended) return;
972
- ended = true;
973
- try {
974
- mic.getTracks().forEach((t) => t.stop());
975
- } catch {
976
- }
977
- try {
978
- pc.close();
979
- } catch {
980
- }
981
- try {
982
- audioEl.remove();
983
- } catch {
984
- }
985
- fireState("ended");
986
- opts.onEnd?.();
987
- };
988
994
  return {
989
995
  get state() {
990
996
  return proto.state;