@16x/webphone-sdk 3.1.12 → 3.1.15

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.
@@ -0,0 +1,710 @@
1
+ import { i as e } from "./SharedWorkerProtocol-CffZrUXg.js";
2
+ //#region src/sip/nativeMediaAdapter.ts
3
+ function t(e) {
4
+ let t = /* @__PURE__ */ new Map();
5
+ return {
6
+ peerConnection: {
7
+ getSenders: () => e.getSenders().map((n) => {
8
+ let r = t.get(n);
9
+ if (r !== void 0) return r;
10
+ let i = {
11
+ get track() {
12
+ return n.track;
13
+ },
14
+ get senderKind() {
15
+ let t = n.track;
16
+ if (t !== null) return t.kind === "audio" || t.kind === "video" ? t.kind : void 0;
17
+ let r = e.getTransceivers().find((e) => e.sender === n)?.receiver.track;
18
+ if (r?.kind === "audio" || r?.kind === "video") return r.kind;
19
+ let i = n.getParameters().codecs?.find((e) => typeof e.mimeType == "string");
20
+ if (i?.mimeType?.toLowerCase().startsWith("video/")) return "video";
21
+ if (i?.mimeType?.toLowerCase().startsWith("audio/")) return "audio";
22
+ },
23
+ replaceTrack: (e) => n.replaceTrack(e)
24
+ };
25
+ return t.set(n, i), i;
26
+ }),
27
+ close: () => {
28
+ e.connectionState !== "closed" && e.close();
29
+ }
30
+ },
31
+ trackSource: { onTrack(t) {
32
+ let n = (e) => {
33
+ let n = e.track;
34
+ t({
35
+ streams: [...e.streams],
36
+ track: n
37
+ });
38
+ };
39
+ return e.addEventListener("track", n), () => e.removeEventListener("track", n);
40
+ } }
41
+ };
42
+ }
43
+ //#endregion
44
+ //#region src/sip/iceServerQuality.ts
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) {
67
+ if (!e) return "";
68
+ let t = String(e.type ?? "");
69
+ return t === "" ? / typ (\w+)/.exec(String(e.candidate ?? ""))?.[1] ?? "" : t;
70
+ }
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 = [];
92
+ for (let t of e) {
93
+ if (!t) continue;
94
+ let e = Array.isArray(t.urls) ? t.urls : [t.urls];
95
+ for (let n of e) {
96
+ let e = String(n ?? "").trim();
97
+ /^(stun|turn|turns):/i.test(e) && i.push({
98
+ url: e,
99
+ entry: t
100
+ });
101
+ }
102
+ }
103
+ return Promise.all(i.map((e) => new Promise((t) => {
104
+ let n = !1, i = !1, s, c = o(e.url), l = (r, i) => {
105
+ if (!n) {
106
+ n = !0, clearTimeout(u);
107
+ try {
108
+ s?.close();
109
+ } catch {}
110
+ t({
111
+ url: e.url,
112
+ status: r,
113
+ transport: c,
114
+ reason: i
115
+ });
116
+ }
117
+ }, u = setTimeout(() => l(i ? "unavailable" : "unknown", i ? "server-error" : "timeout"), r);
118
+ try {
119
+ if (typeof RTCPeerConnection > "u") {
120
+ l("unknown", "local-error");
121
+ return;
122
+ }
123
+ let t = { urls: [e.url] };
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) => {
125
+ if (!e || !e.candidate) return;
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"));
131
+ } catch {
132
+ l("unknown", "local-error");
133
+ }
134
+ })));
135
+ }
136
+ function l(e, t) {
137
+ let n = /* @__PURE__ */ new Map();
138
+ for (let e of t) e && e.url && n.set(String(e.url), e.status === "available");
139
+ let r = [];
140
+ for (let t of e ?? []) {
141
+ if (!t) continue;
142
+ let e = (Array.isArray(t.urls) ? t.urls : [t.urls]).filter(Boolean).filter((e) => n.get(String(e)) === !0);
143
+ if (e.length === 0) continue;
144
+ let i = {
145
+ ...t,
146
+ urls: e
147
+ };
148
+ r.push(i);
149
+ }
150
+ return r;
151
+ }
152
+ var u = class {
153
+ availableList;
154
+ lastGoodList;
155
+ lastGoodAt;
156
+ lastResults = [];
157
+ snapshotState = i();
158
+ running = !1;
159
+ seq = 0;
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"), [];
187
+ }
188
+ snapshot() {
189
+ return this.snapshotState;
190
+ }
191
+ reset() {
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;
196
+ }
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) => ({
226
+ ...e,
227
+ urls: Array.isArray(e.urls) ? [...e.urls] : [e.urls]
228
+ }));
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
+ };
235
+ let o = Date.now();
236
+ c(i).then((e) => {
237
+ if (a !== this.seq) return;
238
+ this.lastResults = e;
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 = {
249
+ runs: this.snapshotState.runs + 1,
250
+ lastMs: Date.now() - o,
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"
261
+ };
262
+ }).catch(() => {
263
+ this.seq;
264
+ }).finally(() => {
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);
269
+ });
270
+ }
271
+ isRunning() {
272
+ return this.running;
273
+ }
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) {
284
+ if (!e) return "";
285
+ let t = String(e.type ?? "");
286
+ return t === "" ? / typ (\w+)/.exec(String(e.candidate ?? ""))?.[1] ?? "" : t;
287
+ }
288
+ function p(e, t = {}) {
289
+ if (typeof e.on != "function") return () => void 0;
290
+ let n = Number.isFinite(t.timeoutMs) && t.timeoutMs > 0 ? t.timeoutMs : d, r = !1, i, a = () => {
291
+ if (!r) {
292
+ r = !0, clearTimeout(s);
293
+ try {
294
+ i?.();
295
+ } catch {}
296
+ }
297
+ }, o = (e) => {
298
+ let t = e;
299
+ if (!t || typeof t.ready != "function") return;
300
+ i = t.ready;
301
+ let n = f(t.candidate);
302
+ (n === "srflx" || n === "relay") && a();
303
+ };
304
+ e.on("icecandidate", o);
305
+ let s = setTimeout(a, n);
306
+ return () => {
307
+ clearTimeout(s);
308
+ try {
309
+ e.off?.("icecandidate", o);
310
+ } catch {}
311
+ };
312
+ }
313
+ //#endregion
314
+ //#region src/sip/JsSipAdapter.ts
315
+ var m = 300, h = 25, g = 2, _ = "", v = 120;
316
+ function y(e) {
317
+ let t = Math.floor(Number(e.sip.registerExpires));
318
+ return Number.isFinite(t) && t > 0 ? t : m;
319
+ }
320
+ var b = class {
321
+ factory;
322
+ transportBaseUrl;
323
+ keepaliveSeconds;
324
+ agentTerminal;
325
+ sessionTimers;
326
+ ua;
327
+ uaListeners;
328
+ incomingHandlers;
329
+ iceServers;
330
+ pendingConnection;
331
+ disposed = !1;
332
+ warmPc;
333
+ keepaliveTimer;
334
+ keepaliveBusy = !1;
335
+ registerExpiresSeconds = 0;
336
+ connectionHandlers = /* @__PURE__ */ new Set();
337
+ iceQuality = new u();
338
+ constructor(e, t, n = h, r = _, i = !1) {
339
+ this.factory = e, this.transportBaseUrl = t, this.keepaliveSeconds = n, this.agentTerminal = r, this.sessionTimers = i;
340
+ }
341
+ terminalHeaders() {
342
+ return this.agentTerminal === "" ? [] : [`X-Agent-Terminal: ${this.agentTerminal}`];
343
+ }
344
+ warmIceCandidatePool() {
345
+ if (this.closeWarmPc(), typeof RTCPeerConnection < "u" && this.iceServers !== void 0) try {
346
+ this.warmPc = new RTCPeerConnection({
347
+ iceServers: [...this.iceServers],
348
+ iceCandidatePoolSize: g
349
+ });
350
+ } catch {
351
+ this.warmPc = void 0;
352
+ }
353
+ }
354
+ closeWarmPc() {
355
+ try {
356
+ this.warmPc?.close();
357
+ } catch {}
358
+ this.warmPc = void 0;
359
+ }
360
+ keepaliveTick(e) {
361
+ if (this.isCurrentUa(e) && !this.keepaliveBusy) try {
362
+ if (typeof e.isConnected == "function" && e.isConnected() === !1 || typeof e.register != "function") return;
363
+ this.keepaliveBusy = !0, e.register({ extraHeaders: this.terminalHeaders() });
364
+ } catch {} finally {
365
+ this.keepaliveBusy = !1;
366
+ }
367
+ }
368
+ startKeepalive(e, t) {
369
+ if (this.stopKeepalive(), !Number.isFinite(this.keepaliveSeconds) || this.keepaliveSeconds <= 0 || t > 0 && t <= this.keepaliveSeconds) return;
370
+ let n = Math.max(10, Math.floor(this.keepaliveSeconds)) * 1e3;
371
+ this.keepaliveTimer = setInterval(() => this.keepaliveTick(e), n);
372
+ }
373
+ stopKeepalive() {
374
+ this.keepaliveTimer !== void 0 && clearInterval(this.keepaliveTimer), this.keepaliveTimer = void 0;
375
+ }
376
+ connect(t) {
377
+ this.assertNotDisposed();
378
+ let n = this.iceQuality.snapshot().runs > 0;
379
+ this.disconnect(this.registrationError("SIP connection replaced"), !n);
380
+ try {
381
+ let e = this.factory.createUa({
382
+ sockets: w(this.factory.createSocket(this.withoutTicket(this.resolveWssUrl(t.transport.wssUrl)), t.transport.ticket)),
383
+ uri: t.sip.uri,
384
+ password: t.sip.registerTicket,
385
+ registrar_server: t.sip.registrar,
386
+ register: !0,
387
+ register_expires: y(t),
388
+ session_timers: this.sessionTimers,
389
+ ...this.agentTerminal === "" ? {} : { user_agent: this.agentTerminal }
390
+ });
391
+ return this.ua = e, this.registerExpiresSeconds = y(t), this.iceServers = t.iceServers, this.uaListeners = [], this.startRegistration(e);
392
+ } catch (t) {
393
+ let n = t instanceof e && t.code === "CONFIG_INVALID" ? t : this.transportError(t);
394
+ return this.disconnect(n), Promise.reject(n);
395
+ }
396
+ }
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);
401
+ }
402
+ dial(t, n) {
403
+ let r = this.requireUa();
404
+ if (t.trim() === "") throw new e("CALL_INVALID_DESTINATION", "call", !1);
405
+ try {
406
+ let e = n === void 0 ? {
407
+ mediaConstraints: {
408
+ audio: !0,
409
+ video: !1
410
+ },
411
+ sessionTimersExpires: v,
412
+ pcConfig: {
413
+ iceServers: this.dialIceServers(),
414
+ iceCandidatePoolSize: g
415
+ }
416
+ } : {
417
+ mediaConstraints: {
418
+ audio: !0,
419
+ video: !1
420
+ },
421
+ sessionTimersExpires: v,
422
+ pcConfig: {
423
+ iceServers: [...n.iceServers],
424
+ iceCandidatePoolSize: g
425
+ },
426
+ extraHeaders: [
427
+ ...this.terminalHeaders(),
428
+ ...n.extraHeaders,
429
+ ...n.type === "extension" ? ["X-XCall-Destination-Type: extension"] : []
430
+ ]
431
+ };
432
+ return this.createSessionHandle(r.call(t, e));
433
+ } catch (t) {
434
+ throw new e("CALL_OPERATION_NOT_ALLOWED", "call", !1, { cause: t });
435
+ }
436
+ }
437
+ onIncoming(e) {
438
+ this.assertNotDisposed();
439
+ let t = this.incomingHandlers ?? /* @__PURE__ */ new Set();
440
+ return this.incomingHandlers = t, t.add(e), () => t.delete(e);
441
+ }
442
+ onConnectionStateChanged(e) {
443
+ return this.disposed ? () => void 0 : (this.connectionHandlers.add(e), () => this.connectionHandlers.delete(e));
444
+ }
445
+ dispose() {
446
+ this.disposed || (this.disposed = !0, this.disconnect(), this.incomingHandlers = void 0, this.connectionHandlers.clear());
447
+ }
448
+ dialIceServers() {
449
+ return this.iceQuality.serversForDial(this.iceServers);
450
+ }
451
+ iceQualitySnapshot() {
452
+ return this.iceQuality.snapshot();
453
+ }
454
+ reassessIceServers(e = "network-online") {
455
+ this.iceQuality.assess(this.iceServers, e);
456
+ }
457
+ getResourceCounts() {
458
+ return {
459
+ listeners: (this.uaListeners?.length ?? 0) + (this.incomingHandlers?.size ?? 0) + this.connectionHandlers.size,
460
+ webSockets: this.ua === void 0 ? 0 : 1
461
+ };
462
+ }
463
+ handleIncoming(e) {
464
+ if (!S(e)) return;
465
+ let t = e.session;
466
+ if (t === void 0) return;
467
+ let n = this.createSessionHandle(t);
468
+ this.incomingHandlers?.forEach((e) => e(n));
469
+ }
470
+ createSessionHandle(e) {
471
+ return new x(e, () => this.reassessIceServers("ice-failed"));
472
+ }
473
+ startRegistration(e) {
474
+ let t = !0, n = !1, r = new Promise((t, n) => {
475
+ this.pendingConnection = {
476
+ ua: e,
477
+ resolve: t,
478
+ reject: n
479
+ };
480
+ });
481
+ this.listen(e, "registered", () => {
482
+ if (this.isCurrentUa(e)) {
483
+ if (t) {
484
+ n = !0;
485
+ return;
486
+ }
487
+ this.resolveConnection(e);
488
+ }
489
+ }), this.listen(e, "registrationFailed", (t) => {
490
+ if (!this.isCurrentUa(e)) return;
491
+ let n = this.registrationError(this.registrationFailureCause(t));
492
+ this.connectionHandlers.forEach((e) => e("failed", n)), this.disconnect(n);
493
+ }), this.listen(e, "disconnected", (t) => {
494
+ if (!this.isCurrentUa(e)) return;
495
+ let n = this.transportError(t);
496
+ this.connectionHandlers.forEach((e) => e("disconnected", n)), this.disconnect(n, !1);
497
+ }), this.listen(e, "newRTCSession", (t) => {
498
+ this.isCurrentUa(e) && this.handleIncoming(t);
499
+ });
500
+ try {
501
+ e.start();
502
+ } catch (e) {
503
+ let t = this.transportError(e);
504
+ this.connectionHandlers.forEach((e) => e("failed", t)), this.disconnect(t);
505
+ } finally {
506
+ t = !1;
507
+ }
508
+ return n && this.resolveConnection(e), r;
509
+ }
510
+ listen(e, t, n) {
511
+ e.on(t, n), this.uaListeners?.push({
512
+ event: t,
513
+ handler: n
514
+ });
515
+ }
516
+ removeUaListeners(e) {
517
+ this.uaListeners?.forEach(({ event: t, handler: n }) => e.off(t, n));
518
+ }
519
+ isCurrentUa(e) {
520
+ return this.ua === e;
521
+ }
522
+ resolveConnection(e) {
523
+ let t = this.pendingConnection;
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"));
528
+ }
529
+ resolveWssUrl(e) {
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);
531
+ return n.protocol === "http:" && (n.protocol = "ws:"), n.protocol === "https:" && (n.protocol = "wss:"), this.assertAllowedWssUrl(n), n.toString();
532
+ }
533
+ assertAllowedWssUrl(t) {
534
+ if (t.protocol !== "wss:" && !(t.protocol === "ws:" && T(t.hostname))) throw new e("CONFIG_INVALID", "configuration", !1, { cause: t.origin });
535
+ }
536
+ withoutTicket(e) {
537
+ let t = new URL(e);
538
+ return t.searchParams.delete("ticket"), t.toString();
539
+ }
540
+ requireUa() {
541
+ if (this.assertNotDisposed(), this.ua === void 0) throw new e("CALL_NOT_CONNECTED", "call", !1);
542
+ return this.ua;
543
+ }
544
+ assertNotDisposed() {
545
+ if (this.disposed) throw new e("SDK_ALREADY_DISPOSED", "internal", !1);
546
+ }
547
+ registrationError(t) {
548
+ return new e("REGISTRATION_FAILED", "registration", !0, { cause: t });
549
+ }
550
+ transportError(t) {
551
+ return new e("SIP_WS_UNAVAILABLE", "registration", !0, { cause: t });
552
+ }
553
+ registrationFailureCause(e) {
554
+ return typeof e == "object" && e && "cause" in e ? e.cause : e;
555
+ }
556
+ }, x = class {
557
+ session;
558
+ pendingHoldReject;
559
+ mediaRegistration;
560
+ mediaConnection;
561
+ mediaHandlers = /* @__PURE__ */ new Set();
562
+ mediaWatchStarted = !1;
563
+ sessionUnsubscribeFromPeerConnection;
564
+ detachIceGatheringTimeout;
565
+ detachIceFailureWatch;
566
+ constructor(e, t) {
567
+ this.session = e, this.detachIceGatheringTimeout = p(e), t !== void 0 && this.watchIceFailure(t);
568
+ }
569
+ get id() {
570
+ return this.session.id;
571
+ }
572
+ get from() {
573
+ return this.session.from ?? E(this.session.remote_identity);
574
+ }
575
+ getMediaRegistration() {
576
+ let e = this.session.connection;
577
+ if (e != null) return this.mediaRegistration !== void 0 && this.mediaConnection === e ? this.mediaRegistration : (this.mediaConnection = e, this.mediaRegistration = t(e), this.mediaRegistration);
578
+ }
579
+ answer(e) {
580
+ this.session.answer({
581
+ mediaConstraints: e.mediaConstraints,
582
+ pcConfig: {
583
+ iceServers: [...e.pcConfig.iceServers],
584
+ iceCandidatePoolSize: g
585
+ }
586
+ });
587
+ }
588
+ 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;
602
+ }
603
+ hold() {
604
+ return this.changeHoldState("hold");
605
+ }
606
+ unhold() {
607
+ return this.changeHoldState("unhold");
608
+ }
609
+ mute() {
610
+ this.session.mute();
611
+ }
612
+ unmute() {
613
+ this.session.unmute();
614
+ }
615
+ sendDtmf(e) {
616
+ this.session.sendDTMF(e);
617
+ }
618
+ refer(e) {
619
+ this.session.refer(e);
620
+ }
621
+ on(e, t) {
622
+ return e === "mediaConnected" ? (this.mediaHandlers.add(t), this.watchMediaConnection(), () => {
623
+ this.mediaHandlers.delete(t), this.mediaHandlers.size === 0 && (this.sessionUnsubscribeFromPeerConnection?.(), this.sessionUnsubscribeFromPeerConnection = void 0);
624
+ }) : (this.session.on(e, t), () => this.session.off(e, t));
625
+ }
626
+ watchMediaConnection() {
627
+ if (this.mediaWatchStarted) return;
628
+ this.mediaWatchStarted = !0;
629
+ let e = !1, t = (t) => {
630
+ if (t == null) return;
631
+ let n = () => {
632
+ if (e) return;
633
+ let n = t.connectionState || t.iceConnectionState;
634
+ if (n === "connected") {
635
+ e = !0;
636
+ for (let e of this.mediaHandlers) try {
637
+ e({ state: n });
638
+ } catch {}
639
+ }
640
+ };
641
+ t.addEventListener("connectionstatechange", n), n();
642
+ }, n = this.session.connection;
643
+ if (n != null) {
644
+ t(n);
645
+ return;
646
+ }
647
+ let r = (e) => {
648
+ t(e?.peerconnection ?? void 0);
649
+ };
650
+ this.session.on("peerconnection", r), this.sessionUnsubscribeFromPeerConnection = () => this.session.off("peerconnection", r);
651
+ }
652
+ changeHoldState(t) {
653
+ return new Promise((n, r) => {
654
+ let i = !1, a = (e) => {
655
+ c(e);
656
+ }, o = () => {
657
+ try {
658
+ this.session.off("ended", a);
659
+ } catch {}
660
+ try {
661
+ this.session.off("failed", a);
662
+ } catch {}
663
+ this.pendingHoldReject === c && (this.pendingHoldReject = void 0);
664
+ }, s = () => {
665
+ i || (i = !0, o(), n());
666
+ }, c = (t) => {
667
+ i || (i = !0, o(), r(new e("CALL_OPERATION_NOT_ALLOWED", "call", !1, { cause: t })));
668
+ };
669
+ try {
670
+ this.session.on("ended", a), this.session.on("failed", a);
671
+ } catch (e) {
672
+ c(e);
673
+ return;
674
+ }
675
+ this.pendingHoldReject = c;
676
+ try {
677
+ this.session[t](void 0, s) || c({
678
+ reason: "jssip_operation_rejected",
679
+ operation: t
680
+ });
681
+ } catch (e) {
682
+ c(e);
683
+ }
684
+ });
685
+ }
686
+ };
687
+ function S(e) {
688
+ if (typeof e != "object" || !e) return !1;
689
+ let t = e;
690
+ return t.originator === "remote" && C(t.session);
691
+ }
692
+ function C(e) {
693
+ return typeof e == "object" && !!e && "id" in e;
694
+ }
695
+ function w(e) {
696
+ return typeof e == "object" && e && (e.via_transport = "WSS"), e;
697
+ }
698
+ function T(e) {
699
+ let t = e.replace(/^\[|\]$/g, "").toLowerCase();
700
+ return t === "localhost" || t === "127.0.0.1" || t === "::1" || t === "0:0:0:0:0:0:0:1";
701
+ }
702
+ function E(e) {
703
+ let t = e?.uri;
704
+ if (t == null) return;
705
+ if (typeof t.user == "string" && t.user !== "") return t.user;
706
+ let n = t.toString();
707
+ return n.match(/^sips?:([^@;>]+)/i)?.[1] ?? (n === "" ? void 0 : n);
708
+ }
709
+ //#endregion
710
+ export { b as JsSipAdapter };