@tmsoft/webphone 5.0.9 → 5.0.11
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 +6 -1
- package/dist/assets/sipSharedWorker-Bk0APY9t.js +3 -0
- package/dist/assets/sipSharedWorker-HqRmUaB2.js +3 -0
- package/dist/src/components/WebPhone.vue.d.ts +3 -0
- package/dist/webphone.component.js +33 -33
- package/dist/webphone.es.js +404 -242
- package/dist/webphone.umd.js +12 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,8 @@ import { WebPhone } from '@tmsoft/webphone'
|
|
|
47
47
|
| `contacts` | `WebPhoneContact[]` | No | `[]` | Contact list |
|
|
48
48
|
| `initialKeypadVisible` | `boolean` | No | `true` | Initial keypad visibility |
|
|
49
49
|
| `enablePictureInPicture` | `boolean` | No | `true` | Enables Document Picture-in-Picture |
|
|
50
|
-
| `maskNumber` | `boolean` | No | `false` | Masks the displayed call number
|
|
50
|
+
| `maskNumber` | `boolean` | No | `false` | Masks the displayed call number, leaving only its last 4 characters visible (for example, `******4567`); extensions listed in `extensions` are never masked |
|
|
51
|
+
| `extensions` | `string[]` | No | `[]` | Numbers of the internal extensions, of any length. They are not masked when `maskNumber` is on |
|
|
51
52
|
| `earlyMedia` | `boolean` | No | `false` | Enables audio from provisional SIP responses with SDP for outbound, non-forking calls |
|
|
52
53
|
| `onAnswer` | `(video: boolean) => void \| Promise<void>` | No | — | Custom handler for answer action (incoming call) |
|
|
53
54
|
| `onHangup` | `() => void \| Promise<void>` | No | — | Called when hangup is requested; SIP hangup is always sent by the component |
|
|
@@ -55,6 +56,10 @@ import { WebPhone } from '@tmsoft/webphone'
|
|
|
55
56
|
|
|
56
57
|
> \* Either `host` or `wsUrl` must be provided.
|
|
57
58
|
|
|
59
|
+
### Transporte WSS y pestañas suspendidas
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
58
63
|
## Modes
|
|
59
64
|
|
|
60
65
|
| 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())}})();
|
|
@@ -20,6 +20,8 @@ type __VLS_Props = {
|
|
|
20
20
|
initialKeypadVisible?: boolean;
|
|
21
21
|
enablePictureInPicture?: boolean;
|
|
22
22
|
maskNumber?: boolean;
|
|
23
|
+
/** Números de las extensiones internas: no se enmascaran. */
|
|
24
|
+
extensions?: string[];
|
|
23
25
|
earlyMedia?: boolean;
|
|
24
26
|
onAnswer?: (video: boolean) => void | Promise<void>;
|
|
25
27
|
onHangup?: () => void | Promise<void>;
|
|
@@ -46,6 +48,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
|
|
|
46
48
|
earlyMedia: boolean;
|
|
47
49
|
mode: "webcall" | "call" | "video";
|
|
48
50
|
maskNumber: boolean;
|
|
51
|
+
extensions: string[];
|
|
49
52
|
position: WebPhonePosition;
|
|
50
53
|
initialKeypadVisible: boolean;
|
|
51
54
|
enablePictureInPicture: boolean;
|