@16x/webphone-sdk 3.2.6 → 3.2.8
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 +19 -0
- package/dist/{Diagnostics-5p1QKAQp.cjs → Diagnostics-B0kPq1DA.cjs} +1 -1
- package/dist/{Diagnostics-B_v3Ais8.js → Diagnostics-C2iTL_c-.js} +1 -1
- package/dist/{JsSipAdapter-BHtCsy_S.js → JsSipAdapter-B8ueIoBA.js} +241 -104
- package/dist/JsSipAdapter-l97xq1ao.cjs +1 -0
- package/dist/core/CCBarClient.d.ts +5 -0
- package/dist/core/CallManager.d.ts +5 -0
- package/dist/diagnostics/Diagnostics.d.ts +6 -0
- package/dist/diagnostics/index.cjs +1 -1
- package/dist/diagnostics/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/index.umd.js +1 -1
- package/dist/legacy/index.cjs +1 -1
- package/dist/legacy/index.js +1 -1
- package/dist/legacySessionProvider-B4uTsst_.cjs +1 -0
- package/dist/{legacySessionProvider-DIPSh55z.js → legacySessionProvider-CiyiokZ_.js} +111 -47
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/JsSipAdapter-BB-SusrS.cjs +0 -1
- package/dist/legacySessionProvider-BlkuIB83.cjs +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.8
|
|
4
|
+
|
|
5
|
+
修复平台抖动后 dial 永久不可自愈(CALL_NOT_CONNECTED):
|
|
6
|
+
|
|
7
|
+
- `ReconnectManager` 新增 `isRecovered` 校验:recover() 成功返回不再被当作连接已恢复,未恢复按失败继续退避。
|
|
8
|
+
- `recoverInvalidSession` 重建失败不再 `reconnect.cancel()` 永久取消重连循环(3.2.7 事故主根因),保持封顶退避重试。
|
|
9
|
+
- `recoverConnection` 在会话被清空后改走 `performConnect` 全新建会话;在途通话超过 120s 宽限后强制终态(终态事件不可达时)。
|
|
10
|
+
- 媒体释放屏障增加 5s 超时,防止永不 settle 的释放操作锁死重连。
|
|
11
|
+
|
|
12
|
+
## 3.2.7 - 2026-10-08
|
|
13
|
+
|
|
14
|
+
- Treat ICE probe timeouts as unknown instead of permanently marking servers unavailable; preserve
|
|
15
|
+
the original ICE pool for later re-probing.
|
|
16
|
+
- Keep ICE probing in the background so it does not block dialing. Use recently available ICE
|
|
17
|
+
servers for new calls with a five-minute cache, and re-probe after network recovery, SIP
|
|
18
|
+
reconnection, ICE failure, or cache expiry.
|
|
19
|
+
- Add bounded retry backoff and diagnostics for probe state, unknown/unavailable URL counts, cache
|
|
20
|
+
age, and the ICE configuration selected for the next call.
|
|
21
|
+
|
|
3
22
|
## 3.2.6 - 2026-10-07
|
|
4
23
|
|
|
5
24
|
- Fix the multi-egress-office dial delay at its root: a dead STUN/TURN-UDP endpoint dragged JsSIP's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require("./redact-Bq26pObO.cjs");var t=`3.2.
|
|
1
|
+
const e=require("./redact-Bq26pObO.cjs");var t=`3.2.8`,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}});
|
|
@@ -42,56 +42,100 @@ function t(e) {
|
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
44
|
//#region src/sip/iceServerQuality.ts
|
|
45
|
-
var n = 2e3
|
|
46
|
-
|
|
45
|
+
var n = 2e3, r = [
|
|
46
|
+
5e3,
|
|
47
|
+
15e3,
|
|
48
|
+
6e4
|
|
49
|
+
];
|
|
50
|
+
function i() {
|
|
51
|
+
return {
|
|
52
|
+
runs: 0,
|
|
53
|
+
lastMs: null,
|
|
54
|
+
udpOk: !1,
|
|
55
|
+
tcpRelayOk: !1,
|
|
56
|
+
convergedServers: null,
|
|
57
|
+
unchanged: null,
|
|
58
|
+
status: "idle",
|
|
59
|
+
lastProbeAt: null,
|
|
60
|
+
cacheAgeMs: null,
|
|
61
|
+
unknownCount: 0,
|
|
62
|
+
unavailableCount: 0,
|
|
63
|
+
dialMode: "original"
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function a(e) {
|
|
47
67
|
if (!e) return "";
|
|
48
68
|
let t = String(e.type ?? "");
|
|
49
69
|
return t === "" ? / typ (\w+)/.exec(String(e.candidate ?? ""))?.[1] ?? "" : t;
|
|
50
70
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
71
|
+
function o(e) {
|
|
72
|
+
return /^turns:/i.test(e) ? "tls" : /transport=tcp/i.test(e) ? "tcp" : "udp";
|
|
73
|
+
}
|
|
74
|
+
function s(e, t) {
|
|
75
|
+
let n = t.flatMap((e) => (Array.isArray(e.urls) ? e.urls : [e.urls]).map((t) => [String(t), e])), r = new Map(n), i = [];
|
|
76
|
+
for (let t of e) {
|
|
77
|
+
let e = Array.isArray(t.urls) ? t.urls : [t.urls];
|
|
78
|
+
for (let t of e) {
|
|
79
|
+
let e = r.get(String(t));
|
|
80
|
+
e && i.push({
|
|
81
|
+
...e,
|
|
82
|
+
urls: [t]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return i;
|
|
87
|
+
}
|
|
88
|
+
function c(e, t = {}) {
|
|
89
|
+
let r = Number.isFinite(t.timeoutMs) && t.timeoutMs > 0 ? t.timeoutMs : n;
|
|
90
|
+
if (!Array.isArray(e)) return Promise.resolve([]);
|
|
91
|
+
let i = [];
|
|
55
92
|
for (let t of e) {
|
|
56
93
|
if (!t) continue;
|
|
57
94
|
let e = Array.isArray(t.urls) ? t.urls : [t.urls];
|
|
58
95
|
for (let n of e) {
|
|
59
96
|
let e = String(n ?? "").trim();
|
|
60
|
-
/^(stun|turn|turns):/i.test(e) &&
|
|
97
|
+
/^(stun|turn|turns):/i.test(e) && i.push({
|
|
61
98
|
url: e,
|
|
62
99
|
entry: t
|
|
63
100
|
});
|
|
64
101
|
}
|
|
65
102
|
}
|
|
66
|
-
return Promise.all(
|
|
67
|
-
let n = !1,
|
|
103
|
+
return Promise.all(i.map((e) => new Promise((t) => {
|
|
104
|
+
let n = !1, i = !1, s, c = o(e.url), l = (r, i) => {
|
|
68
105
|
if (!n) {
|
|
69
|
-
n = !0, clearTimeout(
|
|
106
|
+
n = !0, clearTimeout(u);
|
|
70
107
|
try {
|
|
71
|
-
|
|
108
|
+
s?.close();
|
|
72
109
|
} catch {}
|
|
73
110
|
t({
|
|
74
111
|
url: e.url,
|
|
75
|
-
|
|
76
|
-
|
|
112
|
+
status: r,
|
|
113
|
+
transport: c,
|
|
114
|
+
reason: i
|
|
77
115
|
});
|
|
78
116
|
}
|
|
79
|
-
},
|
|
117
|
+
}, u = setTimeout(() => l(i ? "unavailable" : "unknown", i ? "server-error" : "timeout"), r);
|
|
80
118
|
try {
|
|
119
|
+
if (typeof RTCPeerConnection > "u") {
|
|
120
|
+
l("unknown", "local-error");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
81
123
|
let t = { urls: [e.url] };
|
|
82
|
-
e.entry.username && (t.username = e.entry.username), e.entry.credential && (t.credential = e.entry.credential),
|
|
124
|
+
e.entry.username && (t.username = e.entry.username), e.entry.credential && (t.credential = e.entry.credential), s = new RTCPeerConnection({ iceServers: [t] }), s.createDataChannel("webphone-ice-probe"), s.onicecandidate = (e) => {
|
|
83
125
|
if (!e || !e.candidate) return;
|
|
84
|
-
let t =
|
|
85
|
-
(t === "srflx" || t === "relay") &&
|
|
86
|
-
},
|
|
126
|
+
let t = a(e.candidate);
|
|
127
|
+
(t === "srflx" || t === "relay") && l("available", "candidate");
|
|
128
|
+
}, s.onicecandidateerror = (t) => {
|
|
129
|
+
t?.url && t.url === e.url && (i = !0);
|
|
130
|
+
}, s.createOffer().then((e) => s?.setLocalDescription(e)).catch(() => l("unknown", "local-error"));
|
|
87
131
|
} catch {
|
|
88
|
-
|
|
132
|
+
l("unknown", "local-error");
|
|
89
133
|
}
|
|
90
134
|
})));
|
|
91
135
|
}
|
|
92
|
-
function
|
|
136
|
+
function l(e, t) {
|
|
93
137
|
let n = /* @__PURE__ */ new Map();
|
|
94
|
-
for (let e of t) e && e.url && n.set(String(e.url), e.
|
|
138
|
+
for (let e of t) e && e.url && n.set(String(e.url), e.status === "available");
|
|
95
139
|
let r = [];
|
|
96
140
|
for (let t of e ?? []) {
|
|
97
141
|
if (!t) continue;
|
|
@@ -105,77 +149,147 @@ function a(e, t) {
|
|
|
105
149
|
}
|
|
106
150
|
return r;
|
|
107
151
|
}
|
|
108
|
-
var
|
|
109
|
-
|
|
152
|
+
var u = class {
|
|
153
|
+
availableList;
|
|
154
|
+
lastGoodList;
|
|
155
|
+
lastGoodAt;
|
|
110
156
|
lastResults = [];
|
|
111
|
-
snapshotState =
|
|
112
|
-
runs: 0,
|
|
113
|
-
lastMs: null,
|
|
114
|
-
udpOk: !1,
|
|
115
|
-
tcpRelayOk: !1,
|
|
116
|
-
convergedServers: null,
|
|
117
|
-
unchanged: null
|
|
118
|
-
};
|
|
157
|
+
snapshotState = i();
|
|
119
158
|
running = !1;
|
|
120
159
|
seq = 0;
|
|
121
|
-
|
|
122
|
-
|
|
160
|
+
consecutiveFailures = 0;
|
|
161
|
+
lastAttemptAt;
|
|
162
|
+
retryTimer;
|
|
163
|
+
pendingRequest;
|
|
164
|
+
serversForDial(e, t = Date.now()) {
|
|
165
|
+
if (!e) return;
|
|
166
|
+
if (!this.lastResults.length) return this.setDialMode("original"), e;
|
|
167
|
+
let n = this.lastGoodAt === void 0 ? null : Math.max(0, t - this.lastGoodAt);
|
|
168
|
+
this.snapshotState = {
|
|
169
|
+
...this.snapshotState,
|
|
170
|
+
cacheAgeMs: n
|
|
171
|
+
};
|
|
172
|
+
let r = n !== null && n > 3e5, i = this.snapshotState.lastProbeAt === null ? null : Math.max(0, t - this.snapshotState.lastProbeAt);
|
|
173
|
+
if (r || i !== null && i > 3e5) return this.snapshotState = {
|
|
174
|
+
...this.snapshotState,
|
|
175
|
+
status: "stale",
|
|
176
|
+
cacheAgeMs: n ?? i
|
|
177
|
+
}, this.assess(e, "ttl-expired"), this.availableList && this.availableList.length > 0 ? (this.setDialMode("original"), e) : (this.setDialMode("host-only"), []);
|
|
178
|
+
if (!r && this.availableList && this.availableList.length > 0) return this.setDialMode("known-available"), this.availableList.map((e) => ({
|
|
179
|
+
...e,
|
|
180
|
+
urls: Array.isArray(e.urls) ? [...e.urls] : e.urls
|
|
181
|
+
}));
|
|
182
|
+
if (this.lastGoodList && n !== null && n <= 3e5) {
|
|
183
|
+
let t = s(this.lastGoodList, e);
|
|
184
|
+
if (t.length > 0) return this.setDialMode("last-known-good"), t;
|
|
185
|
+
}
|
|
186
|
+
return this.setDialMode("host-only"), [];
|
|
123
187
|
}
|
|
124
188
|
snapshot() {
|
|
125
189
|
return this.snapshotState;
|
|
126
190
|
}
|
|
127
191
|
reset() {
|
|
128
|
-
this.seq++, this.running = !1, this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
tcpRelayOk: !1,
|
|
133
|
-
convergedServers: null,
|
|
134
|
-
unchanged: null
|
|
135
|
-
};
|
|
192
|
+
this.retryTimer !== void 0 && clearTimeout(this.retryTimer), this.retryTimer = void 0, this.pendingRequest = void 0, this.seq++, this.running = !1, this.availableList = void 0, this.lastGoodList = void 0, this.lastGoodAt = void 0, this.lastResults = [], this.consecutiveFailures = 0, this.lastAttemptAt = void 0, this.snapshotState = i();
|
|
193
|
+
}
|
|
194
|
+
cancelInFlight() {
|
|
195
|
+
this.seq++, this.running = !1, this.retryTimer !== void 0 && clearTimeout(this.retryTimer), this.retryTimer = void 0, this.pendingRequest = void 0;
|
|
136
196
|
}
|
|
137
|
-
assess(e, t =
|
|
138
|
-
if (e === void 0
|
|
139
|
-
|
|
197
|
+
assess(e, t = "initial-registration") {
|
|
198
|
+
if (e === void 0) return;
|
|
199
|
+
if (e.length === 0) {
|
|
200
|
+
this.reset();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (this.running) {
|
|
204
|
+
t !== "initial-registration" && (this.pendingRequest = {
|
|
205
|
+
servers: e,
|
|
206
|
+
trigger: t
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
let n = Date.now();
|
|
211
|
+
if (t !== "initial-registration" && this.consecutiveFailures > 0 && this.lastAttemptAt !== void 0) {
|
|
212
|
+
let i = r[Math.min(this.consecutiveFailures - 1, r.length - 1)] - (n - this.lastAttemptAt);
|
|
213
|
+
if (i > 0) {
|
|
214
|
+
this.pendingRequest = {
|
|
215
|
+
servers: e,
|
|
216
|
+
trigger: t
|
|
217
|
+
}, this.retryTimer === void 0 && (this.retryTimer = setTimeout(() => {
|
|
218
|
+
this.retryTimer = void 0;
|
|
219
|
+
let e = this.pendingRequest;
|
|
220
|
+
this.pendingRequest = void 0, e && this.assess(e.servers, e.trigger);
|
|
221
|
+
}, i));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
let i = e.map((e) => ({
|
|
140
226
|
...e,
|
|
141
227
|
urls: Array.isArray(e.urls) ? [...e.urls] : [e.urls]
|
|
142
228
|
}));
|
|
143
|
-
if (
|
|
144
|
-
let
|
|
145
|
-
this.running = !0
|
|
229
|
+
if (!i.some((e) => (Array.isArray(e.urls) ? e.urls : [e.urls]).some((e) => /^(stun|turn|turns):/i.test(String(e ?? ""))))) return;
|
|
230
|
+
let a = ++this.seq;
|
|
231
|
+
this.running = !0, this.lastAttemptAt = n, this.availableList = void 0, this.snapshotState = {
|
|
232
|
+
...this.snapshotState,
|
|
233
|
+
status: t === "ttl-expired" ? "stale" : "probing"
|
|
234
|
+
};
|
|
146
235
|
let o = Date.now();
|
|
147
|
-
i
|
|
148
|
-
if (
|
|
236
|
+
c(i).then((e) => {
|
|
237
|
+
if (a !== this.seq) return;
|
|
149
238
|
this.lastResults = e;
|
|
150
|
-
let t =
|
|
151
|
-
this.
|
|
239
|
+
let t = i, n = l(t, e);
|
|
240
|
+
this.availableList = n.length > 0 ? n : void 0, this.availableList && (this.lastGoodList = n.map((e) => ({
|
|
241
|
+
...e,
|
|
242
|
+
urls: Array.isArray(e.urls) ? [...e.urls] : e.urls
|
|
243
|
+
})), this.lastGoodAt = Date.now());
|
|
244
|
+
let s = e.filter((e) => e.status === "unknown").length, c = e.filter((e) => e.status === "unavailable").length;
|
|
245
|
+
this.consecutiveFailures = n.length === 0 ? this.consecutiveFailures + 1 : 0, n.length === 0 && this.consecutiveFailures <= r.length && this.pendingRequest === void 0 && (this.pendingRequest = {
|
|
246
|
+
servers: i,
|
|
247
|
+
trigger: "retry-backoff"
|
|
248
|
+
}), this.snapshotState = {
|
|
152
249
|
runs: this.snapshotState.runs + 1,
|
|
153
250
|
lastMs: Date.now() - o,
|
|
154
|
-
udpOk: e.some((e) => e.
|
|
155
|
-
tcpRelayOk: e.some((e) => e.
|
|
156
|
-
convergedServers:
|
|
157
|
-
unchanged: JSON.stringify(
|
|
251
|
+
udpOk: e.some((e) => e.status === "available" && e.transport === "udp"),
|
|
252
|
+
tcpRelayOk: e.some((e) => e.status === "available" && (e.transport === "tcp" || e.transport === "tls")),
|
|
253
|
+
convergedServers: n.length,
|
|
254
|
+
unchanged: JSON.stringify(n) === JSON.stringify(t),
|
|
255
|
+
status: s + c > 0 ? "degraded" : "healthy",
|
|
256
|
+
lastProbeAt: Date.now(),
|
|
257
|
+
cacheAgeMs: 0,
|
|
258
|
+
unknownCount: s,
|
|
259
|
+
unavailableCount: c,
|
|
260
|
+
dialMode: n.length > 0 ? "known-available" : "host-only"
|
|
158
261
|
};
|
|
159
262
|
}).catch(() => {
|
|
160
263
|
this.seq;
|
|
161
264
|
}).finally(() => {
|
|
162
|
-
|
|
265
|
+
if (a !== this.seq) return;
|
|
266
|
+
this.running = !1;
|
|
267
|
+
let e = this.pendingRequest;
|
|
268
|
+
this.pendingRequest = void 0, e && this.assess(e.servers, e.trigger);
|
|
163
269
|
});
|
|
164
270
|
}
|
|
165
271
|
isRunning() {
|
|
166
272
|
return this.running;
|
|
167
273
|
}
|
|
168
|
-
|
|
169
|
-
|
|
274
|
+
setDialMode(e) {
|
|
275
|
+
let t = this.snapshotState.status;
|
|
276
|
+
this.snapshotState = {
|
|
277
|
+
...this.snapshotState,
|
|
278
|
+
dialMode: e,
|
|
279
|
+
status: t === "healthy" && e === "host-only" ? "stale" : t
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}, d = 3e3;
|
|
283
|
+
function f(e) {
|
|
170
284
|
if (!e) return "";
|
|
171
285
|
let t = String(e.type ?? "");
|
|
172
286
|
return t === "" ? / typ (\w+)/.exec(String(e.candidate ?? ""))?.[1] ?? "" : t;
|
|
173
287
|
}
|
|
174
|
-
function
|
|
288
|
+
function p(e, t = {}) {
|
|
175
289
|
if (typeof e.on != "function") return () => void 0;
|
|
176
|
-
let n = Number.isFinite(t.timeoutMs) && t.timeoutMs > 0 ? t.timeoutMs :
|
|
290
|
+
let n = Number.isFinite(t.timeoutMs) && t.timeoutMs > 0 ? t.timeoutMs : d, r = !1, i, a = () => {
|
|
177
291
|
if (!r) {
|
|
178
|
-
r = !0, clearTimeout(
|
|
292
|
+
r = !0, clearTimeout(s);
|
|
179
293
|
try {
|
|
180
294
|
i?.();
|
|
181
295
|
} catch {}
|
|
@@ -184,13 +298,13 @@ function l(e, t = {}) {
|
|
|
184
298
|
let t = e;
|
|
185
299
|
if (!t || typeof t.ready != "function") return;
|
|
186
300
|
i = t.ready;
|
|
187
|
-
let n =
|
|
301
|
+
let n = f(t.candidate);
|
|
188
302
|
(n === "srflx" || n === "relay") && a();
|
|
189
303
|
};
|
|
190
304
|
e.on("icecandidate", o);
|
|
191
|
-
let
|
|
305
|
+
let s = setTimeout(a, n);
|
|
192
306
|
return () => {
|
|
193
|
-
clearTimeout(
|
|
307
|
+
clearTimeout(s);
|
|
194
308
|
try {
|
|
195
309
|
e.off?.("icecandidate", o);
|
|
196
310
|
} catch {}
|
|
@@ -198,12 +312,12 @@ function l(e, t = {}) {
|
|
|
198
312
|
}
|
|
199
313
|
//#endregion
|
|
200
314
|
//#region src/sip/JsSipAdapter.ts
|
|
201
|
-
var
|
|
202
|
-
function
|
|
315
|
+
var m = 300, h = 25, g = 2, _ = "", v = 120;
|
|
316
|
+
function y(e) {
|
|
203
317
|
let t = Math.floor(Number(e.sip.registerExpires));
|
|
204
|
-
return Number.isFinite(t) && t > 0 ? t :
|
|
318
|
+
return Number.isFinite(t) && t > 0 ? t : m;
|
|
205
319
|
}
|
|
206
|
-
var
|
|
320
|
+
var b = class {
|
|
207
321
|
factory;
|
|
208
322
|
transportBaseUrl;
|
|
209
323
|
keepaliveSeconds;
|
|
@@ -220,8 +334,8 @@ var g = class {
|
|
|
220
334
|
keepaliveBusy = !1;
|
|
221
335
|
registerExpiresSeconds = 0;
|
|
222
336
|
connectionHandlers = /* @__PURE__ */ new Set();
|
|
223
|
-
iceQuality = new
|
|
224
|
-
constructor(e, t, n =
|
|
337
|
+
iceQuality = new u();
|
|
338
|
+
constructor(e, t, n = h, r = _, i = !1) {
|
|
225
339
|
this.factory = e, this.transportBaseUrl = t, this.keepaliveSeconds = n, this.agentTerminal = r, this.sessionTimers = i;
|
|
226
340
|
}
|
|
227
341
|
terminalHeaders() {
|
|
@@ -231,7 +345,7 @@ var g = class {
|
|
|
231
345
|
if (this.closeWarmPc(), typeof RTCPeerConnection < "u" && this.iceServers !== void 0) try {
|
|
232
346
|
this.warmPc = new RTCPeerConnection({
|
|
233
347
|
iceServers: [...this.iceServers],
|
|
234
|
-
iceCandidatePoolSize:
|
|
348
|
+
iceCandidatePoolSize: g
|
|
235
349
|
});
|
|
236
350
|
} catch {
|
|
237
351
|
this.warmPc = void 0;
|
|
@@ -260,28 +374,30 @@ var g = class {
|
|
|
260
374
|
this.keepaliveTimer !== void 0 && clearInterval(this.keepaliveTimer), this.keepaliveTimer = void 0;
|
|
261
375
|
}
|
|
262
376
|
connect(t) {
|
|
263
|
-
this.assertNotDisposed()
|
|
377
|
+
this.assertNotDisposed();
|
|
378
|
+
let n = this.iceQuality.snapshot().runs > 0;
|
|
379
|
+
this.disconnect(this.registrationError("SIP connection replaced"), !n);
|
|
264
380
|
try {
|
|
265
381
|
let e = this.factory.createUa({
|
|
266
|
-
sockets:
|
|
382
|
+
sockets: w(this.factory.createSocket(this.withoutTicket(this.resolveWssUrl(t.transport.wssUrl)), t.transport.ticket)),
|
|
267
383
|
uri: t.sip.uri,
|
|
268
384
|
password: t.sip.registerTicket,
|
|
269
385
|
registrar_server: t.sip.registrar,
|
|
270
386
|
register: !0,
|
|
271
|
-
register_expires:
|
|
387
|
+
register_expires: y(t),
|
|
272
388
|
session_timers: this.sessionTimers,
|
|
273
389
|
...this.agentTerminal === "" ? {} : { user_agent: this.agentTerminal }
|
|
274
390
|
});
|
|
275
|
-
return this.ua = e, this.registerExpiresSeconds =
|
|
391
|
+
return this.ua = e, this.registerExpiresSeconds = y(t), this.iceServers = t.iceServers, this.uaListeners = [], this.startRegistration(e);
|
|
276
392
|
} catch (t) {
|
|
277
393
|
let n = t instanceof e && t.code === "CONFIG_INVALID" ? t : this.transportError(t);
|
|
278
394
|
return this.disconnect(n), Promise.reject(n);
|
|
279
395
|
}
|
|
280
396
|
}
|
|
281
|
-
disconnect(e = this.registrationError("SIP connection disconnected")) {
|
|
282
|
-
this.stopKeepalive(), this.closeWarmPc(), this.iceQuality.reset();
|
|
283
|
-
let
|
|
284
|
-
this.pendingConnection = void 0, this.ua !== void 0 && (this.removeUaListeners(this.ua), this.ua.stop()), this.ua = void 0, this.uaListeners = void 0, this.iceServers = void 0,
|
|
397
|
+
disconnect(e = this.registrationError("SIP connection disconnected"), t = !0) {
|
|
398
|
+
this.stopKeepalive(), this.closeWarmPc(), t ? this.iceQuality.reset() : this.iceQuality.cancelInFlight();
|
|
399
|
+
let n = this.pendingConnection;
|
|
400
|
+
this.pendingConnection = void 0, this.ua !== void 0 && (this.removeUaListeners(this.ua), this.ua.stop()), this.ua = void 0, this.uaListeners = void 0, this.iceServers = void 0, n?.reject(e);
|
|
285
401
|
}
|
|
286
402
|
dial(t, n) {
|
|
287
403
|
let r = this.requireUa();
|
|
@@ -292,20 +408,20 @@ var g = class {
|
|
|
292
408
|
audio: !0,
|
|
293
409
|
video: !1
|
|
294
410
|
},
|
|
295
|
-
sessionTimersExpires:
|
|
411
|
+
sessionTimersExpires: v,
|
|
296
412
|
pcConfig: {
|
|
297
413
|
iceServers: this.dialIceServers(),
|
|
298
|
-
iceCandidatePoolSize:
|
|
414
|
+
iceCandidatePoolSize: g
|
|
299
415
|
}
|
|
300
416
|
} : {
|
|
301
417
|
mediaConstraints: {
|
|
302
418
|
audio: !0,
|
|
303
419
|
video: !1
|
|
304
420
|
},
|
|
305
|
-
sessionTimersExpires:
|
|
421
|
+
sessionTimersExpires: v,
|
|
306
422
|
pcConfig: {
|
|
307
423
|
iceServers: [...n.iceServers],
|
|
308
|
-
iceCandidatePoolSize:
|
|
424
|
+
iceCandidatePoolSize: g
|
|
309
425
|
},
|
|
310
426
|
extraHeaders: [
|
|
311
427
|
...this.terminalHeaders(),
|
|
@@ -313,7 +429,7 @@ var g = class {
|
|
|
313
429
|
...n.type === "extension" ? ["X-XCall-Destination-Type: extension"] : []
|
|
314
430
|
]
|
|
315
431
|
};
|
|
316
|
-
return
|
|
432
|
+
return this.createSessionHandle(r.call(t, e));
|
|
317
433
|
} catch (t) {
|
|
318
434
|
throw new e("CALL_OPERATION_NOT_ALLOWED", "call", !1, { cause: t });
|
|
319
435
|
}
|
|
@@ -330,12 +446,14 @@ var g = class {
|
|
|
330
446
|
this.disposed || (this.disposed = !0, this.disconnect(), this.incomingHandlers = void 0, this.connectionHandlers.clear());
|
|
331
447
|
}
|
|
332
448
|
dialIceServers() {
|
|
333
|
-
|
|
334
|
-
return e === void 0 ? void 0 : [...e];
|
|
449
|
+
return this.iceQuality.serversForDial(this.iceServers);
|
|
335
450
|
}
|
|
336
451
|
iceQualitySnapshot() {
|
|
337
452
|
return this.iceQuality.snapshot();
|
|
338
453
|
}
|
|
454
|
+
reassessIceServers(e = "network-online") {
|
|
455
|
+
this.iceQuality.assess(this.iceServers, e);
|
|
456
|
+
}
|
|
339
457
|
getResourceCounts() {
|
|
340
458
|
return {
|
|
341
459
|
listeners: (this.uaListeners?.length ?? 0) + (this.incomingHandlers?.size ?? 0) + this.connectionHandlers.size,
|
|
@@ -343,12 +461,15 @@ var g = class {
|
|
|
343
461
|
};
|
|
344
462
|
}
|
|
345
463
|
handleIncoming(e) {
|
|
346
|
-
if (!
|
|
464
|
+
if (!S(e)) return;
|
|
347
465
|
let t = e.session;
|
|
348
466
|
if (t === void 0) return;
|
|
349
|
-
let n =
|
|
467
|
+
let n = this.createSessionHandle(t);
|
|
350
468
|
this.incomingHandlers?.forEach((e) => e(n));
|
|
351
469
|
}
|
|
470
|
+
createSessionHandle(e) {
|
|
471
|
+
return new x(e, () => this.reassessIceServers("ice-failed"));
|
|
472
|
+
}
|
|
352
473
|
startRegistration(e) {
|
|
353
474
|
let t = !0, n = !1, r = new Promise((t, n) => {
|
|
354
475
|
this.pendingConnection = {
|
|
@@ -372,7 +493,7 @@ var g = class {
|
|
|
372
493
|
}), this.listen(e, "disconnected", (t) => {
|
|
373
494
|
if (!this.isCurrentUa(e)) return;
|
|
374
495
|
let n = this.transportError(t);
|
|
375
|
-
this.connectionHandlers.forEach((e) => e("disconnected", n)), this.disconnect(n);
|
|
496
|
+
this.connectionHandlers.forEach((e) => e("disconnected", n)), this.disconnect(n, !1);
|
|
376
497
|
}), this.listen(e, "newRTCSession", (t) => {
|
|
377
498
|
this.isCurrentUa(e) && this.handleIncoming(t);
|
|
378
499
|
});
|
|
@@ -400,14 +521,17 @@ var g = class {
|
|
|
400
521
|
}
|
|
401
522
|
resolveConnection(e) {
|
|
402
523
|
let t = this.pendingConnection;
|
|
403
|
-
t?.ua
|
|
524
|
+
if (t?.ua !== e) return;
|
|
525
|
+
this.pendingConnection = void 0, t.resolve(), this.warmIceCandidatePool();
|
|
526
|
+
let n = this.iceQuality.snapshot().runs > 0 ? "sip-reconnected" : "initial-registration";
|
|
527
|
+
this.iceQuality.assess(this.iceServers, n), this.startKeepalive(e, this.registerExpiresSeconds), this.connectionHandlers.forEach((e) => e("registered"));
|
|
404
528
|
}
|
|
405
529
|
resolveWssUrl(e) {
|
|
406
530
|
let t = this.transportBaseUrl?.trim() === "" || this.transportBaseUrl === void 0 ? typeof location > "u" ? "http://localhost" : location.origin : this.transportBaseUrl, n = e.startsWith("/") ? new URL(e, t) : new URL(e);
|
|
407
531
|
return n.protocol === "http:" && (n.protocol = "ws:"), n.protocol === "https:" && (n.protocol = "wss:"), this.assertAllowedWssUrl(n), n.toString();
|
|
408
532
|
}
|
|
409
533
|
assertAllowedWssUrl(t) {
|
|
410
|
-
if (t.protocol !== "wss:" && !(t.protocol === "ws:" &&
|
|
534
|
+
if (t.protocol !== "wss:" && !(t.protocol === "ws:" && T(t.hostname))) throw new e("CONFIG_INVALID", "configuration", !1, { cause: t.origin });
|
|
411
535
|
}
|
|
412
536
|
withoutTicket(e) {
|
|
413
537
|
let t = new URL(e);
|
|
@@ -429,7 +553,7 @@ var g = class {
|
|
|
429
553
|
registrationFailureCause(e) {
|
|
430
554
|
return typeof e == "object" && e && "cause" in e ? e.cause : e;
|
|
431
555
|
}
|
|
432
|
-
},
|
|
556
|
+
}, x = class {
|
|
433
557
|
session;
|
|
434
558
|
pendingHoldReject;
|
|
435
559
|
mediaRegistration;
|
|
@@ -438,14 +562,15 @@ var g = class {
|
|
|
438
562
|
mediaWatchStarted = !1;
|
|
439
563
|
sessionUnsubscribeFromPeerConnection;
|
|
440
564
|
detachIceGatheringTimeout;
|
|
441
|
-
|
|
442
|
-
|
|
565
|
+
detachIceFailureWatch;
|
|
566
|
+
constructor(e, t) {
|
|
567
|
+
this.session = e, this.detachIceGatheringTimeout = p(e), t !== void 0 && this.watchIceFailure(t);
|
|
443
568
|
}
|
|
444
569
|
get id() {
|
|
445
570
|
return this.session.id;
|
|
446
571
|
}
|
|
447
572
|
get from() {
|
|
448
|
-
return this.session.from ??
|
|
573
|
+
return this.session.from ?? E(this.session.remote_identity);
|
|
449
574
|
}
|
|
450
575
|
getMediaRegistration() {
|
|
451
576
|
let e = this.session.connection;
|
|
@@ -456,12 +581,24 @@ var g = class {
|
|
|
456
581
|
mediaConstraints: e.mediaConstraints,
|
|
457
582
|
pcConfig: {
|
|
458
583
|
iceServers: [...e.pcConfig.iceServers],
|
|
459
|
-
iceCandidatePoolSize:
|
|
584
|
+
iceCandidatePoolSize: g
|
|
460
585
|
}
|
|
461
586
|
});
|
|
462
587
|
}
|
|
463
588
|
terminate() {
|
|
464
|
-
this.detachIceGatheringTimeout?.(), this.detachIceGatheringTimeout = void 0, this.pendingHoldReject?.(/* @__PURE__ */ Error("SIP session terminated")), this.session.terminate();
|
|
589
|
+
this.detachIceGatheringTimeout?.(), this.detachIceGatheringTimeout = void 0, this.detachIceFailureWatch?.(), this.detachIceFailureWatch = void 0, this.pendingHoldReject?.(/* @__PURE__ */ Error("SIP session terminated")), this.session.terminate();
|
|
590
|
+
}
|
|
591
|
+
watchIceFailure(e) {
|
|
592
|
+
let t, n = () => {
|
|
593
|
+
t?.iceConnectionState === "failed" && e();
|
|
594
|
+
}, r = (e) => {
|
|
595
|
+
e && e !== t && (t?.removeEventListener("iceconnectionstatechange", n), t = e, t.addEventListener("iceconnectionstatechange", n), n());
|
|
596
|
+
}, i = (e) => {
|
|
597
|
+
r(e?.peerconnection);
|
|
598
|
+
}, a = () => {
|
|
599
|
+
this.session.off("peerconnection", i), this.session.off("ended", a), this.session.off("failed", a), t?.removeEventListener("iceconnectionstatechange", n), t = void 0;
|
|
600
|
+
}, o = this.session.connection;
|
|
601
|
+
o != null && r(o), this.session.on("peerconnection", i), this.session.on("ended", a), this.session.on("failed", a), this.detachIceFailureWatch = a;
|
|
465
602
|
}
|
|
466
603
|
hold() {
|
|
467
604
|
return this.changeHoldState("hold");
|
|
@@ -547,22 +684,22 @@ var g = class {
|
|
|
547
684
|
});
|
|
548
685
|
}
|
|
549
686
|
};
|
|
550
|
-
function
|
|
687
|
+
function S(e) {
|
|
551
688
|
if (typeof e != "object" || !e) return !1;
|
|
552
689
|
let t = e;
|
|
553
|
-
return t.originator === "remote" &&
|
|
690
|
+
return t.originator === "remote" && C(t.session);
|
|
554
691
|
}
|
|
555
|
-
function
|
|
692
|
+
function C(e) {
|
|
556
693
|
return typeof e == "object" && !!e && "id" in e;
|
|
557
694
|
}
|
|
558
|
-
function
|
|
695
|
+
function w(e) {
|
|
559
696
|
return typeof e == "object" && e && (e.via_transport = "WSS"), e;
|
|
560
697
|
}
|
|
561
|
-
function
|
|
698
|
+
function T(e) {
|
|
562
699
|
let t = e.replace(/^\[|\]$/g, "").toLowerCase();
|
|
563
700
|
return t === "localhost" || t === "127.0.0.1" || t === "::1" || t === "0:0:0:0:0:0:0:1";
|
|
564
701
|
}
|
|
565
|
-
function
|
|
702
|
+
function E(e) {
|
|
566
703
|
let t = e?.uri;
|
|
567
704
|
if (t == null) return;
|
|
568
705
|
if (typeof t.user == "string" && t.user !== "") return t.user;
|
|
@@ -570,4 +707,4 @@ function S(e) {
|
|
|
570
707
|
return n.match(/^sips?:([^@;>]+)/i)?.[1] ?? (n === "" ? void 0 : n);
|
|
571
708
|
}
|
|
572
709
|
//#endregion
|
|
573
|
-
export {
|
|
710
|
+
export { b as JsSipAdapter };
|