@16x/webphone-sdk 3.2.5 → 3.2.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.2.7 - 2026-10-08
4
+
5
+ - Treat ICE probe timeouts as unknown instead of permanently marking servers unavailable; preserve
6
+ the original ICE pool for later re-probing.
7
+ - Keep ICE probing in the background so it does not block dialing. Use recently available ICE
8
+ servers for new calls with a five-minute cache, and re-probe after network recovery, SIP
9
+ reconnection, ICE failure, or cache expiry.
10
+ - Add bounded retry backoff and diagnostics for probe state, unknown/unavailable URL counts, cache
11
+ age, and the ICE configuration selected for the next call.
12
+
13
+ ## 3.2.6 - 2026-10-07
14
+
15
+ - Fix the multi-egress-office dial delay at its root: a dead STUN/TURN-UDP endpoint dragged JsSIP's
16
+ non-trickle ICE gathering through the browser retransmission tables (~40s measured with both
17
+ STUN binding and TURN allocation retrying in parallel) even though a usable TURN-TCP relay
18
+ candidate was already available at ~150ms.
19
+ - Attach an ICE gathering timeout to every outgoing/incoming session: call JsSIP's built-in
20
+ `icecandidate` `ready()` shortcut as soon as an srflx/relay candidate arrives, and force-close
21
+ the local SDP with the most recent ready callback after 3s so INVITE/200 OK never waits for
22
+ dead servers (mirrors ccbar BUG-013).
23
+ - Add URL-level ICE server probing after each successful registration (`iceServerQuality`):
24
+ every stun/turn/turns URL is probed with its own PeerConnection (credentials inherited);
25
+ URLs that yield no srflx/relay are dropped from the dial-time pcConfig. Healthy networks keep
26
+ the original list unchanged (zero behavior change); when every URL fails the list becomes
27
+ host-only so the INVITE still goes out immediately. Attribution must be per-URL because relay
28
+ candidates always report `protocol: udp` (it describes the relayed port, not the client
29
+ transport) and mixing dead and live URLs in one probe drags them all to timeout.
30
+ - `getDiagnostics()` now includes an `ice.probe` summary (runs / lastMs / udpOk / tcpRelayOk /
31
+ convergedServers) from the tab-local adapter (absent in SharedWorker mode).
32
+ - Correct the `warmIceCandidatePool` comment: `iceCandidatePoolSize` is per-RTCPeerConnection,
33
+ so warmed candidates cannot transfer to call connections — the timeout + convergence above
34
+ are the actual safeguards. `answer()` now also passes `iceCandidatePoolSize`.
35
+
3
36
  ## 3.2.5 - 2026-10-06
4
37
 
5
38
  - Keep held-call state synchronized with the call controls so resume, hangup, and DTMF remain available after a hold transition.
@@ -1 +1 @@
1
- const e=require("./redact-Bq26pObO.cjs");var t=`3.2.5`,n=class{capacity;entries=[];constructor(e){if(this.capacity=e,!Number.isInteger(e)||e<=0)throw RangeError(`RingBuffer capacity must be a positive integer`)}push(e){this.entries.length===this.capacity&&this.entries.shift(),this.entries.push(e)}toArray(){return[...this.entries]}},r=`@16x/webphone-sdk`,i=200,a=class{dependencies;logs=new n(i);now;constructor(e){this.dependencies=e,this.now=e.now??(()=>new Date)}log(t,n,r){this.logs.push({timestamp:this.now().toISOString(),level:t,message:e.t(n),...r===void 0?{}:{context:e.n(r)}})}async getReport(n={}){let i=n.includeRecentLogs!==!1,a=n.includeDeviceNames===!0,u=n.maskPhoneNumbers!==!1,d=this.dependencies.getSnapshot(),f=this.dependencies.getPermission===void 0?d.permission:await o(this.dependencies.getPermission,d.permission),p=a?await s(this.dependencies.getDeviceNames):void 0,m=l(c(this.dependencies.getUserAgent)),h={generatedAt:this.now().toISOString(),sdk:{name:r,version:t},browser:m.browser,os:m.os,...d,permission:f,recentLogs:i?this.logs.toArray():[],...p===void 0?{}:{deviceNames:p}};return e.n(h,{maskPhoneNumbers:u})}};async function o(e,t){try{return await e()}catch{return t}}async function s(e){if(e===void 0)return[];try{return[...await e()]}catch{return[]}}function c(e){if(e!==void 0)try{return e()}catch{return``}return typeof navigator>`u`?``:navigator.userAgent}function l(e){return{browser:u(e),os:d(e)}}function u(e){for(let[t,n]of[[`Edge`,/Edg\/([\d.]+)/],[`Chrome`,/(?:Chrome|CriOS)\/([\d.]+)/],[`Firefox`,/(?:Firefox|FxiOS)\/([\d.]+)/],[`Safari`,/Version\/([\d.]+).*Safari/]]){let r=e.match(n);if(r?.[1]!==void 0)return{name:t,version:r[1]}}return{name:`unknown`,version:``}}function d(e){let t=e.match(/(?:iPhone|iPad).*OS ([\d_]+)/);if(t?.[1]!==void 0)return{name:`iOS`,version:t[1].replaceAll(`_`,`.`)};let n=e.match(/Android ([\d.]+)/);if(n?.[1]!==void 0)return{name:`Android`,version:n[1]};let r=e.match(/Windows NT ([\d.]+)/);if(r?.[1]!==void 0)return{name:`Windows`,version:r[1]};let i=e.match(/Mac OS X ([\d_]+)/);return i?.[1]===void 0?/Linux/.test(e)?{name:`Linux`,version:``}:{name:`unknown`,version:``}:{name:`macOS`,version:i[1].replaceAll(`_`,`.`)}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return a}});
1
+ const e=require("./redact-Bq26pObO.cjs");var t=`3.2.7`,n=class{capacity;entries=[];constructor(e){if(this.capacity=e,!Number.isInteger(e)||e<=0)throw RangeError(`RingBuffer capacity must be a positive integer`)}push(e){this.entries.length===this.capacity&&this.entries.shift(),this.entries.push(e)}toArray(){return[...this.entries]}},r=`@16x/webphone-sdk`,i=200,a=class{dependencies;logs=new n(i);now;constructor(e){this.dependencies=e,this.now=e.now??(()=>new Date)}log(t,n,r){this.logs.push({timestamp:this.now().toISOString(),level:t,message:e.t(n),...r===void 0?{}:{context:e.n(r)}})}async getReport(n={}){let i=n.includeRecentLogs!==!1,a=n.includeDeviceNames===!0,u=n.maskPhoneNumbers!==!1,d=this.dependencies.getSnapshot(),f=this.dependencies.getPermission===void 0?d.permission:await o(this.dependencies.getPermission,d.permission),p=a?await s(this.dependencies.getDeviceNames):void 0,m=l(c(this.dependencies.getUserAgent)),h={generatedAt:this.now().toISOString(),sdk:{name:r,version:t},browser:m.browser,os:m.os,...d,permission:f,recentLogs:i?this.logs.toArray():[],...p===void 0?{}:{deviceNames:p}};return e.n(h,{maskPhoneNumbers:u})}};async function o(e,t){try{return await e()}catch{return t}}async function s(e){if(e===void 0)return[];try{return[...await e()]}catch{return[]}}function c(e){if(e!==void 0)try{return e()}catch{return``}return typeof navigator>`u`?``:navigator.userAgent}function l(e){return{browser:u(e),os:d(e)}}function u(e){for(let[t,n]of[[`Edge`,/Edg\/([\d.]+)/],[`Chrome`,/(?:Chrome|CriOS)\/([\d.]+)/],[`Firefox`,/(?:Firefox|FxiOS)\/([\d.]+)/],[`Safari`,/Version\/([\d.]+).*Safari/]]){let r=e.match(n);if(r?.[1]!==void 0)return{name:t,version:r[1]}}return{name:`unknown`,version:``}}function d(e){let t=e.match(/(?:iPhone|iPad).*OS ([\d_]+)/);if(t?.[1]!==void 0)return{name:`iOS`,version:t[1].replaceAll(`_`,`.`)};let n=e.match(/Android ([\d.]+)/);if(n?.[1]!==void 0)return{name:`Android`,version:n[1]};let r=e.match(/Windows NT ([\d.]+)/);if(r?.[1]!==void 0)return{name:`Windows`,version:r[1]};let i=e.match(/Mac OS X ([\d_]+)/);return i?.[1]===void 0?/Linux/.test(e)?{name:`Linux`,version:``}:{name:`unknown`,version:``}:{name:`macOS`,version:i[1].replaceAll(`_`,`.`)}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return a}});
@@ -1,6 +1,6 @@
1
1
  import { n as e, t } from "./redact-DB3CMbsK.js";
2
2
  //#region src/version.ts
3
- var n = "3.2.5", r = class {
3
+ var n = "3.2.7", r = class {
4
4
  capacity;
5
5
  entries = [];
6
6
  constructor(e) {