@tmsoft/webphone 5.0.8 → 5.0.10

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/README.md CHANGED
@@ -55,6 +55,10 @@ import { WebPhone } from '@tmsoft/webphone'
55
55
 
56
56
  > \* Either `host` or `wsUrl` must be provided.
57
57
 
58
+ ### Transporte WSS y pestañas suspendidas
59
+
60
+ Cuando el navegador soporta `SharedWorker`, la conexión WSS y sus keep-alives SIP se mantienen dentro de un worker servido desde el mismo origen, mientras SIP.js conserva la gestión de WebRTC en la pestaña. En navegadores sin `SharedWorker`, o si la política CSP bloquea el worker, se usa el transporte WebSocket nativo de SIP.js.
61
+
58
62
  ## Modes
59
63
 
60
64
  | Mode | Description |
@@ -0,0 +1,3 @@
1
+ (function(){const o=new Map,a=(t,e)=>t.postMessage(e),c=(t,e)=>{for(const r of t.clients.values())a(r,e)},n=t=>{t.timer&&(clearInterval(t.timer),t.timer=null)},l=t=>{n(t);const e=t.socket;t.socket=null,e&&e.readyState!==WebSocket.CLOSED&&e.close(1e3,"No active SIP clients")},d=t=>{n(t),!(t.keepAliveInterval<=0)&&(t.timer=setInterval(()=>{if(t.socket?.readyState===WebSocket.OPEN)try{t.socket.send(`\r
2
+ \r
3
+ `)}catch{}},t.keepAliveInterval*1e3))},i=(t,e)=>{if(e.socket&&e.socket.readyState!==WebSocket.CLOSED&&e.socket.readyState!==WebSocket.CLOSING)return;e.socket=null;let r;try{r=new WebSocket(e.server,"sip"),r.binaryType="arraybuffer"}catch(s){c(e,{type:"error",error:s instanceof Error?s.message:"WebSocket construction failed"});return}e.socket=r,r.addEventListener("open",()=>{e.socket===r&&(d(e),c(e,{type:"connected"}))}),r.addEventListener("message",s=>{e.socket===r&&(typeof s.data=="string"?c(e,{type:"message",data:s.data}):s.data instanceof ArrayBuffer&&c(e,{type:"message",data:new TextDecoder().decode(s.data)}))}),r.addEventListener("close",s=>{e.socket===r&&(n(e),e.socket=null,c(e,{type:"disconnected",error:s.reason||`WebSocket closed (${s.code})`}),e.clients.size===0&&o.delete(t))})},k=(t,e)=>{let r=o.get(e.connectionId);r||(r={server:e.server,keepAliveInterval:e.keepAliveInterval,socket:null,timer:null,clients:new Map},o.set(e.connectionId,r)),r.clients.set(e.clientId,t),r.socket?.readyState===WebSocket.OPEN?a(t,{type:"connected"}):i(e.connectionId,r)},f=t=>{const e=o.get(t.connectionId),r=e?.clients.get(t.clientId);if(!(!e||!r)){if(e.socket?.readyState!==WebSocket.OPEN){a(r,{type:"error",error:"WebSocket is not connected"});return}try{e.socket.send(t.data)}catch(s){a(r,{type:"error",error:s instanceof Error?s.message:"WebSocket send failed"})}}},p=t=>{const e=o.get(t.connectionId);e&&(e.clients.delete(t.clientId),e.clients.size===0&&(l(e),o.delete(t.connectionId)))},y=globalThis;y.onconnect=t=>{const e=t.data.ports[0];e&&(e.addEventListener("message",r=>{const s=r.data;s.type==="connect"?k(e,s):s.type==="send"?f(s):p(s)}),e.start())}})();
@@ -0,0 +1,3 @@
1
+ (function(){let e=new Map,t=(e,t)=>e.postMessage(t),n=(e,n)=>{for(let r of e.clients.values())t(r,n)},r=e=>{e.timer&&=(clearInterval(e.timer),null)},i=e=>{r(e);let t=e.socket;e.socket=null,t&&t.readyState!==WebSocket.CLOSED&&t.close(1e3,`No active SIP clients`)},a=e=>{r(e),!(e.keepAliveInterval<=0)&&(e.timer=setInterval(()=>{if(e.socket?.readyState===WebSocket.OPEN)try{e.socket.send(`\r
2
+ \r
3
+ `)}catch{}},e.keepAliveInterval*1e3))},o=(t,i)=>{if(i.socket&&i.socket.readyState!==WebSocket.CLOSED&&i.socket.readyState!==WebSocket.CLOSING)return;i.socket=null;let o;try{o=new WebSocket(i.server,`sip`),o.binaryType=`arraybuffer`}catch(e){n(i,{type:`error`,error:e instanceof Error?e.message:`WebSocket construction failed`});return}i.socket=o,o.addEventListener(`open`,()=>{i.socket===o&&(a(i),n(i,{type:`connected`}))}),o.addEventListener(`message`,e=>{i.socket===o&&(typeof e.data==`string`?n(i,{type:`message`,data:e.data}):e.data instanceof ArrayBuffer&&n(i,{type:`message`,data:new TextDecoder().decode(e.data)}))}),o.addEventListener(`close`,a=>{i.socket===o&&(r(i),i.socket=null,n(i,{type:`disconnected`,error:a.reason||`WebSocket closed (${a.code})`}),i.clients.size===0&&e.delete(t))})},s=(n,r)=>{let i=e.get(r.connectionId);i||(i={server:r.server,keepAliveInterval:r.keepAliveInterval,socket:null,timer:null,clients:new Map},e.set(r.connectionId,i)),i.clients.set(r.clientId,n),i.socket?.readyState===WebSocket.OPEN?t(n,{type:`connected`}):o(r.connectionId,i)},c=n=>{let r=e.get(n.connectionId),i=r?.clients.get(n.clientId);if(!(!r||!i)){if(r.socket?.readyState!==WebSocket.OPEN){t(i,{type:`error`,error:`WebSocket is not connected`});return}try{r.socket.send(n.data)}catch(e){t(i,{type:`error`,error:e instanceof Error?e.message:`WebSocket send failed`})}}},l=t=>{let n=e.get(t.connectionId);n&&(n.clients.delete(t.clientId),n.clients.size===0&&(i(n),e.delete(t.connectionId)))},u=globalThis;u.onconnect=e=>{let t=e.data.ports[0];t&&(t.addEventListener(`message`,e=>{let n=e.data;n.type===`connect`?s(t,n):n.type===`send`?c(n):l(n)}),t.start())}})();