@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.
@@ -1,5 +1,5 @@
1
1
  import { i as e, t } from "./SharedWorkerProtocol-CffZrUXg.js";
2
- import { r as n, t as r } from "./Diagnostics-B_v3Ais8.js";
2
+ import { r as n, t as r } from "./Diagnostics-C2iTL_c-.js";
3
3
  //#region src/events/TypedEventBus.ts
4
4
  var i = class {
5
5
  handlers = /* @__PURE__ */ new Map();
@@ -608,6 +608,27 @@ var x = class {
608
608
  }).then(() => void 0);
609
609
  return this.disposeOperation = n, n;
610
610
  }
611
+ async forceTerminateCalls(e = 5e3) {
612
+ if (this.disposed) return;
613
+ let t = [...this.calls.values()];
614
+ for (let n of t) {
615
+ if (this.disposed) return;
616
+ if (this.calls.get(n.id) === n) {
617
+ try {
618
+ await Promise.race([n.hangup().catch(() => void 0), new Promise((t) => setTimeout(t, Math.max(0, e)))]);
619
+ } catch {}
620
+ try {
621
+ n.dispose();
622
+ } catch {}
623
+ if (this.calls.get(n.id) === n) {
624
+ this.calls.delete(n.id), this.callSessions.delete(n.id), this.callOwners.delete(n.id), this.ownerLostCalls.delete(n.id), this.activeCallId === n.id && (this.activeCallId = null);
625
+ try {
626
+ await this.notifyCallTerminal(n.id);
627
+ } catch {}
628
+ }
629
+ }
630
+ }
631
+ }
611
632
  updateSession(e) {
612
633
  this.disposed || (this.incomingSessionSnapshot = e);
613
634
  }
@@ -1917,6 +1938,7 @@ function Me(e, t = Math.random) {
1917
1938
  //#region src/reconnect/ReconnectManager.ts
1918
1939
  var Ne = class {
1919
1940
  recover;
1941
+ isRecovered;
1920
1942
  random;
1921
1943
  isOnline;
1922
1944
  onAttempt;
@@ -1928,7 +1950,7 @@ var Ne = class {
1928
1950
  disposed = !1;
1929
1951
  restartAfterRun = !1;
1930
1952
  constructor(e) {
1931
- this.recover = e.recover, this.random = e.random ?? Math.random, this.isOnline = e.isOnline ?? (() => !0), this.onAttempt = e.onAttempt;
1953
+ this.recover = e.recover, this.isRecovered = e.isRecovered, this.random = e.random ?? Math.random, this.isOnline = e.isOnline ?? (() => !0), this.onAttempt = e.onAttempt;
1932
1954
  }
1933
1955
  start() {
1934
1956
  if (this.disposed || !this.online || !this.isOnline() || this.pendingTimer !== void 0 || this.running) return;
@@ -1966,7 +1988,7 @@ var Ne = class {
1966
1988
  } finally {
1967
1989
  this.running = !1;
1968
1990
  }
1969
- this.restartAfterRun ? (this.restartAfterRun = !1, this.isCurrent(this.generation) && this.start()) : t && this.isCurrent(e) && this.start();
1991
+ !t && this.isCurrent(e) && this.isRecovered !== void 0 && !this.isRecovered() && (this.attempt += 1, t = !0), this.restartAfterRun ? (this.restartAfterRun = !1, this.isCurrent(this.generation) && this.start()) : t && this.isCurrent(e) && this.start();
1970
1992
  }
1971
1993
  isCurrent(e) {
1972
1994
  return !this.disposed && this.online && e === this.generation && this.isOnline();
@@ -1974,7 +1996,7 @@ var Ne = class {
1974
1996
  clearPendingTimer() {
1975
1997
  this.pendingTimer !== void 0 && (clearTimeout(this.pendingTimer), this.pendingTimer = void 0);
1976
1998
  }
1977
- }, Pe = class t {
1999
+ }, Pe = 12e4, Fe = 5e3, Ie = class t {
1978
2000
  media;
1979
2001
  options;
1980
2002
  api;
@@ -2004,6 +2026,8 @@ var Ne = class {
2004
2026
  managerUnsubscribers = [];
2005
2027
  sipUnsubscribe;
2006
2028
  networkUnsubscribers = [];
2029
+ networkProbeTimer;
2030
+ stuckCallsSince;
2007
2031
  sessionDeleteOperations = /* @__PURE__ */ new Map();
2008
2032
  deletedSessions = /* @__PURE__ */ new Set();
2009
2033
  ownedSessionIds = /* @__PURE__ */ new Set();
@@ -2011,8 +2035,9 @@ var Ne = class {
2011
2035
  sharedWorkerSelection;
2012
2036
  constructor(t) {
2013
2037
  if (this.options = t, t.api === void 0 && t.sessionProvider === void 0) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "CCBarClient 需要 sessionProvider" });
2014
- this.api = t.api === void 0 ? H(Le(t.sessionProvider)) : H(t.api), this.suppliedSip = t.sip === void 0 ? void 0 : Re(t.sip), this.mediaBridge = Oe(() => this.getActiveMediaContext()), this.media = this.mediaBridge.publicMedia, this.reconnect = new Ne({
2038
+ this.api = t.api === void 0 ? H(ze(t.sessionProvider)) : H(t.api), this.suppliedSip = t.sip === void 0 ? void 0 : Be(t.sip), this.mediaBridge = Oe(() => this.getActiveMediaContext()), this.media = this.mediaBridge.publicMedia, this.reconnect = new Ne({
2015
2039
  recover: () => this.recoverConnection(),
2040
+ isRecovered: () => this.state === "connected",
2016
2041
  onAttempt: (e) => {
2017
2042
  this.disposed || this.events.emit("connection.reconnecting", { attempt: e });
2018
2043
  }
@@ -2029,7 +2054,7 @@ var Ne = class {
2029
2054
  });
2030
2055
  }
2031
2056
  static async checkSupport() {
2032
- let e = typeof navigator < "u" && navigator.mediaDevices !== void 0, t = typeof WebSocket < "u", n = Ie(typeof navigator < "u" ? navigator.userAgent : "");
2057
+ let e = typeof navigator < "u" && navigator.mediaDevices !== void 0, t = typeof WebSocket < "u", n = Re(typeof navigator < "u" ? navigator.userAgent : "");
2033
2058
  return {
2034
2059
  supported: e && t,
2035
2060
  platform: n,
@@ -2137,7 +2162,7 @@ var Ne = class {
2137
2162
  sdkVersion: n,
2138
2163
  platform: a === "mobile-web" ? "mobile_web" : "web",
2139
2164
  ...this.options.locale === void 0 ? {} : { locale: this.options.locale },
2140
- requestedCapabilities: [...this.options.requestedCapabilities ?? He(a)]
2165
+ requestedCapabilities: [...this.options.requestedCapabilities ?? We(a)]
2141
2166
  }), this.ownedSessionIds.add(t.sessionId), this.assertGeneration(e), r = await this.getSip(), this.assertGeneration(e), this.session = t;
2142
2167
  let o = this.callManager ?? this.createCallManager(r, t, a);
2143
2168
  this.callManager === void 0 && (i = o), o.updateSession(t), this.callManager = o, this.attachSipListener(r), this.attachNetworkListeners(), await r.connect(t), this.assertGeneration(e), this.setConnectionState("connected"), this.events.emit("connection.registered", { registered: !0 }), this.scheduleRefresh(t);
@@ -2161,7 +2186,7 @@ var Ne = class {
2161
2186
  } catch (t) {
2162
2187
  K(t) || (e ??= t);
2163
2188
  }
2164
- this.reconnect.cancel(), this.clearRefreshTimer(), this.intentionalDisconnect = !0, this.detachNetworkListeners(), this.detachSipListener(), this.detachManagerListeners();
2189
+ this.reconnect.cancel(), this.stuckCallsSince = void 0, this.clearRefreshTimer(), this.intentionalDisconnect = !0, this.detachNetworkListeners(), this.detachSipListener(), this.detachManagerListeners();
2165
2190
  let r = this.callManager, i = this.sip;
2166
2191
  this.callManager = void 0;
2167
2192
  try {
@@ -2243,7 +2268,7 @@ var Ne = class {
2243
2268
  try {
2244
2269
  await this.media.releaseAll();
2245
2270
  } catch (t) {
2246
- ze(t) || (e ??= t);
2271
+ Ve(t) || (e ??= t);
2247
2272
  }
2248
2273
  try {
2249
2274
  await this.mediaBridge.dispose();
@@ -2265,16 +2290,31 @@ var Ne = class {
2265
2290
  async awaitMediaReleaseBarriers() {
2266
2291
  let e;
2267
2292
  for (let [t, n] of [...this.terminalReleaseOperations]) try {
2268
- await n, this.terminalReleaseOperations.delete(t);
2293
+ await this.withBarrierTimeout(n, t), this.terminalReleaseOperations.delete(t);
2269
2294
  } catch (n) {
2270
2295
  try {
2271
- await this.mediaBridge.releaseCall(t), this.terminalReleaseOperations.delete(t);
2296
+ await this.withBarrierTimeout(this.mediaBridge.releaseCall(t), t), this.terminalReleaseOperations.delete(t);
2272
2297
  } catch (t) {
2273
2298
  e ??= t ?? n;
2274
2299
  }
2275
2300
  }
2276
2301
  if (e !== void 0) throw e;
2277
2302
  }
2303
+ withBarrierTimeout(t, n, r = Fe) {
2304
+ return new Promise((i, a) => {
2305
+ let o = setTimeout(() => {
2306
+ a(new e("SDK_INTERNAL_ERROR", "internal", !0, {
2307
+ callId: n,
2308
+ cause: "media release barrier timeout"
2309
+ }));
2310
+ }, Math.max(0, r));
2311
+ t.then((e) => {
2312
+ clearTimeout(o), i(e);
2313
+ }, (e) => {
2314
+ clearTimeout(o), a(e);
2315
+ });
2316
+ });
2317
+ }
2278
2318
  detachSipListener() {
2279
2319
  let e = this.sipUnsubscribe;
2280
2320
  this.sipUnsubscribe = void 0;
@@ -2384,7 +2424,7 @@ var Ne = class {
2384
2424
  if (!this.disposed) try {
2385
2425
  await this.performConnect(this.lifecycleGeneration);
2386
2426
  } catch {
2387
- this.reconnect.cancel();
2427
+ this.disposed || this.reconnect.start();
2388
2428
  }
2389
2429
  }
2390
2430
  }
@@ -2396,12 +2436,23 @@ var Ne = class {
2396
2436
  }, n);
2397
2437
  }
2398
2438
  async recoverConnection() {
2399
- this.disposed || this.intentionalDisconnect || this.hasNonTerminalCalls() || (await this.awaitMediaReleaseBarriers(), await this.refreshAndRebuild());
2439
+ if (!(this.disposed || this.intentionalDisconnect)) {
2440
+ if (this.hasNonTerminalCalls()) {
2441
+ let e = Date.now();
2442
+ if (this.stuckCallsSince === void 0 && (this.stuckCallsSince = e), e - this.stuckCallsSince < Pe) return;
2443
+ this.stuckCallsSince = void 0, await this.callManager?.forceTerminateCalls();
2444
+ } else this.stuckCallsSince = void 0;
2445
+ if (await this.awaitMediaReleaseBarriers(), this.session === void 0) {
2446
+ await this.performConnect(this.lifecycleGeneration);
2447
+ return;
2448
+ }
2449
+ await this.refreshAndRebuild();
2450
+ }
2400
2451
  }
2401
2452
  async getSip() {
2402
2453
  if (this.sip !== void 0) return this.sip;
2403
2454
  if (this.suppliedSip !== void 0) return this.sip = this.suppliedSip, this.sip;
2404
- let [e, t] = await Promise.all([import("./createJsSipFactory-CoWZN-BC.js"), import("./JsSipAdapter-BHtCsy_S.js")]);
2455
+ let [e, t] = await Promise.all([import("./createJsSipFactory-CoWZN-BC.js"), import("./JsSipAdapter-B8ueIoBA.js")]);
2405
2456
  return this.sip = new t.JsSipAdapter(e.createJsSipFactory(), this.options.baseUrl, this.options.sipKeepaliveSeconds, this.options.agentTerminal, this.options.sipSessionTimers ?? !1), this.sip;
2406
2457
  }
2407
2458
  attachSipListener(e) {
@@ -2417,11 +2468,24 @@ var Ne = class {
2417
2468
  }
2418
2469
  attachNetworkListeners() {
2419
2470
  if (this.networkUnsubscribers.length > 0 || typeof window > "u") return;
2420
- let e = window, t = () => this.reconnect.notifyOnline(), n = () => this.reconnect.notifyOffline();
2421
- e.addEventListener("online", t), e.addEventListener("offline", n), this.networkUnsubscribers = [() => e.removeEventListener("online", t), () => e.removeEventListener("offline", n)];
2471
+ let e = window, t = () => {
2472
+ this.reconnect.notifyOnline(), this.scheduleIceReassessment();
2473
+ }, n = () => this.reconnect.notifyOffline(), r = () => this.scheduleIceReassessment();
2474
+ e.addEventListener("online", t), e.addEventListener("offline", n);
2475
+ let i = (typeof navigator > "u" ? void 0 : navigator)?.connection;
2476
+ i?.addEventListener("change", r), this.networkUnsubscribers = [
2477
+ () => e.removeEventListener("online", t),
2478
+ () => e.removeEventListener("offline", n),
2479
+ ...i === void 0 ? [] : [() => i.removeEventListener("change", r)]
2480
+ ];
2481
+ }
2482
+ scheduleIceReassessment() {
2483
+ this.networkProbeTimer !== void 0 && clearTimeout(this.networkProbeTimer), this.networkProbeTimer = setTimeout(() => {
2484
+ this.networkProbeTimer = void 0, !this.disposed && this.state === "connected" && this.sip?.reassessIceServers?.("network-online");
2485
+ }, 2e3);
2422
2486
  }
2423
2487
  detachNetworkListeners() {
2424
- this.networkUnsubscribers.splice(0).forEach((e) => e());
2488
+ this.networkProbeTimer !== void 0 && clearTimeout(this.networkProbeTimer), this.networkProbeTimer = void 0, this.networkUnsubscribers.splice(0).forEach((e) => e());
2425
2489
  }
2426
2490
  getActiveMediaContext() {
2427
2491
  let e = this.callManager?.getActiveCall();
@@ -2443,7 +2507,7 @@ var Ne = class {
2443
2507
  destination: e.destination
2444
2508
  })),
2445
2509
  permission: this.support?.hasMediaDevices === !1 ? "unsupported" : "unknown",
2446
- ice: Fe(e, this.sip?.iceQualitySnapshot?.()),
2510
+ ice: Le(e, this.sip?.iceQualitySnapshot?.()),
2447
2511
  wss: {
2448
2512
  configured: e !== void 0,
2449
2513
  secure: e?.transport.wssUrl.toLowerCase().startsWith("wss://") ?? !1,
@@ -2560,7 +2624,7 @@ var Ne = class {
2560
2624
  return new e("SDK_ALREADY_DISPOSED", "internal", !1);
2561
2625
  }
2562
2626
  };
2563
- function Fe(e, t) {
2627
+ function Le(e, t) {
2564
2628
  if (e === void 0) return {
2565
2629
  configured: !1,
2566
2630
  serverCount: 0,
@@ -2580,7 +2644,7 @@ function Fe(e, t) {
2580
2644
  turnServerCount: r
2581
2645
  };
2582
2646
  }
2583
- function Ie(e) {
2647
+ function Re(e) {
2584
2648
  return e === "" ? "unknown" : /iPhone|iPad|Android/i.test(e) ? "mobile-web" : "web";
2585
2649
  }
2586
2650
  function H(t) {
@@ -2599,7 +2663,7 @@ async function U(e) {
2599
2663
  }
2600
2664
  };
2601
2665
  }
2602
- function Le(t) {
2666
+ function ze(t) {
2603
2667
  let r = {
2604
2668
  createSession: async (e) => U(await t.createSession(e)),
2605
2669
  refreshSession: async (e) => U(t.refreshSession === void 0 ? await t.createSession({
@@ -2613,7 +2677,7 @@ function Le(t) {
2613
2677
  }, i = t.invalidateToken;
2614
2678
  return i !== void 0 && (r.invalidateToken = () => i()), r;
2615
2679
  }
2616
- function Re(t) {
2680
+ function Be(t) {
2617
2681
  if (typeof t != "object" || !t) throw new e("CONFIG_INVALID", "configuration", !1);
2618
2682
  return t;
2619
2683
  }
@@ -2633,13 +2697,13 @@ function W(t, n, r, i, a) {
2633
2697
  function G(t) {
2634
2698
  return t instanceof e ? t.status !== void 0 && t.status >= 400 && t.status < 500 || t.serverCode === "SESSION_NOT_FOUND" || t.serverCode === "SESSION_EXPIRED" || t.serverCode === "TOKEN_INVALID" || t.serverCode === "TOKEN_EXPIRED" || t.code === "AUTH_TOKEN_UNAVAILABLE" || t.code === "AUTH_TOKEN_EXPIRED" || t.code === "AUTH_TOKEN_REJECTED" : !1;
2635
2699
  }
2636
- function ze(t) {
2700
+ function Ve(t) {
2637
2701
  return t instanceof e && t.code === "SDK_ALREADY_DISPOSED";
2638
2702
  }
2639
2703
  function K(t) {
2640
2704
  return t instanceof e && (t.code === "SDK_ALREADY_DISPOSED" || t.code === "CALL_NOT_CONNECTED");
2641
2705
  }
2642
- var Be = [
2706
+ var He = [
2643
2707
  "outbound",
2644
2708
  "inbound",
2645
2709
  "mute",
@@ -2647,24 +2711,24 @@ var Be = [
2647
2711
  "dtmf",
2648
2712
  "blind_transfer",
2649
2713
  "device_selection"
2650
- ], Ve = [
2714
+ ], Ue = [
2651
2715
  "outbound",
2652
2716
  "mute",
2653
2717
  "dtmf"
2654
2718
  ];
2655
- function He(e) {
2656
- return e === "mobile-web" ? Ve : Be;
2719
+ function We(e) {
2720
+ return e === "mobile-web" ? Ue : He;
2657
2721
  }
2658
2722
  //#endregion
2659
2723
  //#region src/legacy/legacySessionProvider.ts
2660
- var Ue = "/openapi/token/v1", We = "/seat/account/get", Ge = "/seats/set-status", Ke = 3478, qe = 600, q = 600, Je = 180, J = 60, Ye = 5e3, Y = 2e4, Xe = [
2724
+ var Ge = "/openapi/token/v1", Ke = "/seat/account/get", qe = "/seats/set-status", Je = 3478, Ye = 600, Xe = 600, Ze = 180, q = 60, Qe = 5e3, J = 2e4, Y = [
2661
2725
  "outbound",
2662
2726
  "inbound",
2663
2727
  "mute",
2664
2728
  "dtmf",
2665
2729
  "hold",
2666
2730
  "blind_transfer"
2667
- ], Ze = {
2731
+ ], $e = {
2668
2732
  available: {
2669
2733
  status: "Available",
2670
2734
  reason: "空闲"
@@ -2679,10 +2743,10 @@ var Ue = "/openapi/token/v1", We = "/seat/account/get", Ge = "/seats/set-status"
2679
2743
  }
2680
2744
  };
2681
2745
  function X(t) {
2682
- let n = $e(t.host), r = et(t.pathPrefix ?? Ue), i = `${n}${r}${Z(t.accountPath ?? We)}`, a = `${n}${r}${Z(t.statusPath ?? Ge)}`, o = {
2746
+ let n = tt(t.host), r = nt(t.pathPrefix ?? Ge), i = `${n}${r}${Z(t.accountPath ?? Ke)}`, a = `${n}${r}${Z(t.statusPath ?? qe)}`, o = {
2683
2747
  ...t.aesKey ? { key: t.aesKey } : {},
2684
2748
  ...t.aesIv ? { iv: t.aesIv } : {}
2685
- }, s = Math.max(0, t.refreshBufferSeconds ?? Je), c = t.fetchImpl ?? globalThis.fetch, l, u, d = "";
2749
+ }, s = Math.max(0, t.refreshBufferSeconds ?? Ze), c = t.fetchImpl ?? globalThis.fetch, l, u, d = "";
2686
2750
  async function f() {
2687
2751
  if (t.getToken !== void 0) return t.getToken();
2688
2752
  if (t.tokenUrl !== void 0) {
@@ -2711,14 +2775,14 @@ function X(t) {
2711
2775
  throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 getToken 或 tokenUrl;坐席状态也可以直接用会话软电话地址里的 token(setAgentStatus 的 context.wssUrl),但这次调用没有会话可用" });
2712
2776
  }
2713
2777
  async function p() {
2714
- if (l && l.expiresAtMs - Date.now() > Ye) return l.token;
2778
+ if (l && l.expiresAtMs - Date.now() > Qe) return l.token;
2715
2779
  let t;
2716
2780
  try {
2717
2781
  t = await f();
2718
2782
  } catch (t) {
2719
2783
  throw t instanceof e ? t : new e("AUTH_TOKEN_UNAVAILABLE", "auth", !0, { cause: t });
2720
2784
  }
2721
- let n = nt(t);
2785
+ let n = it(t);
2722
2786
  if (!n.token) throw new e("AUTH_TOKEN_UNAVAILABLE", "auth", !0, { cause: "取 token 的返回里没有 token(支持 {token}、{accessToken}、{data:{token}} 或裸字符串)" });
2723
2787
  let r = Q(n.expires, 3600);
2724
2788
  return l = {
@@ -2793,14 +2857,14 @@ function X(t) {
2793
2857
  }).filter((e) => e !== void 0);
2794
2858
  if (t.length > 0) return t;
2795
2859
  let n = String(e.turnIp ?? "").trim();
2796
- return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) || Ke}`] }] : [];
2860
+ return n ? [{ urls: [`stun:${n}:${Number(e.turnPort) || Je}`] }] : [];
2797
2861
  }
2798
2862
  async function b() {
2799
2863
  let r = await p(), i = await g(), a = String(i.username ?? i.account ?? "").trim();
2800
2864
  if (!a) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
2801
2865
  let o = String(i.registerPassword ?? i.password ?? ""), c = o ? await _(o) : "";
2802
2866
  if (!c) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 password/registerPassword,或解密后为空" });
2803
- let u = Q(i.expiresIn ?? i.expires_in, q), f = Math.max(0, Math.round((l.expiresAtMs - Date.now()) / 1e3)), m = Math.max(J, Math.min(f || u, u) - s), h = String(i.domain ?? "").trim() || tt(n), b = v(r);
2867
+ let u = Q(i.expiresIn ?? i.expires_in, Xe), f = Math.max(0, Math.round((l.expiresAtMs - Date.now()) / 1e3)), m = Math.max(q, Math.min(f || u, u) - s), h = String(i.domain ?? "").trim() || rt(n), b = v(r);
2804
2868
  return r && (d = r), {
2805
2869
  sessionId: `legacy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
2806
2870
  expiresAt: Math.floor(Date.now() / 1e3) + m,
@@ -2815,7 +2879,7 @@ function X(t) {
2815
2879
  uri: `sip:${a}@${h}`,
2816
2880
  registrar: h,
2817
2881
  registerTicket: c,
2818
- registerExpires: Number(t.registerExpires) > 0 ? Number(t.registerExpires) : qe,
2882
+ registerExpires: Number(t.registerExpires) > 0 ? Number(t.registerExpires) : Ye,
2819
2883
  ticketExpiresIn: m
2820
2884
  },
2821
2885
  transport: {
@@ -2830,7 +2894,7 @@ function X(t) {
2830
2894
  mobileIncomingEnabled: t.mobileIncomingEnabled ?? !0,
2831
2895
  backgroundCallingSupported: !1
2832
2896
  },
2833
- capabilities: [...t.capabilities ?? Xe]
2897
+ capabilities: [...t.capabilities ?? Y]
2834
2898
  };
2835
2899
  }
2836
2900
  return {
@@ -2840,7 +2904,7 @@ function X(t) {
2840
2904
  if (t !== "available" && t !== "offline" && t !== "break") throw new e("CONFIG_INVALID", "configuration", !1, { cause: `Unsupported agent status: ${String(t)}` });
2841
2905
  let i = await h(r), o = u ?? await g(i), s = String(o.username ?? o.account ?? "").trim();
2842
2906
  if (!s) throw new e("LEGACY_PLATFORM_REJECTED", "auth", !1, { cause: "坐席账号里没有 username" });
2843
- let l = Ze[t], d = await $(c, a, {
2907
+ let l = $e[t], d = await $(c, a, {
2844
2908
  method: "POST",
2845
2909
  headers: {
2846
2910
  Authorization: i,
@@ -2878,15 +2942,15 @@ function X(t) {
2878
2942
  getSeatAccount: async () => u ?? g()
2879
2943
  };
2880
2944
  }
2881
- function Qe(e) {
2945
+ function et(e) {
2882
2946
  return X(e);
2883
2947
  }
2884
- function $e(t) {
2948
+ function tt(t) {
2885
2949
  let n = String(t ?? "").trim().replace(/\/+$/, "");
2886
2950
  if (!n) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "createLegacySessionProvider 需要 host" });
2887
2951
  return /^https?:\/\//i.test(n) ? n : `https://${n}`;
2888
2952
  }
2889
- function et(e) {
2953
+ function nt(e) {
2890
2954
  let t = String(e ?? "").trim();
2891
2955
  return !t || t === "/" ? "" : `/${t.replace(/^\/+|\/+$/g, "")}`;
2892
2956
  }
@@ -2894,7 +2958,7 @@ function Z(e) {
2894
2958
  let t = String(e ?? "").trim();
2895
2959
  return t.startsWith("/") ? t : `/${t}`;
2896
2960
  }
2897
- function tt(e) {
2961
+ function rt(e) {
2898
2962
  try {
2899
2963
  return new URL(e).hostname;
2900
2964
  } catch {
@@ -2903,9 +2967,9 @@ function tt(e) {
2903
2967
  }
2904
2968
  function Q(e, t) {
2905
2969
  let n = Number(e);
2906
- return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n), J), 86400));
2970
+ return !Number.isFinite(n) || n <= 0 ? t : (n > 86400 && (n /= 1e3), Math.min(Math.max(Math.floor(n), q), 86400));
2907
2971
  }
2908
- function nt(e) {
2972
+ function it(e) {
2909
2973
  if (typeof e == "string") return { token: e.trim() };
2910
2974
  let t = e ?? {}, n = typeof t.data == "object" && t.data !== null ? t.data : void 0;
2911
2975
  for (let e of [t, n]) {
@@ -2922,7 +2986,7 @@ function nt(e) {
2922
2986
  return { token: "" };
2923
2987
  }
2924
2988
  async function $(t, n, r, i) {
2925
- let a = new AbortController(), o = setTimeout(() => a.abort(), Y);
2989
+ let a = new AbortController(), o = setTimeout(() => a.abort(), J);
2926
2990
  try {
2927
2991
  return await t(n, {
2928
2992
  ...r,
@@ -2930,10 +2994,10 @@ async function $(t, n, r, i) {
2930
2994
  });
2931
2995
  } catch (t) {
2932
2996
  let r = a.signal.aborted;
2933
- throw new e(r ? "NETWORK_TIMEOUT" : "LEGACY_PLATFORM_UNREACHABLE", "network", !0, { cause: r ? `${i}超时(${Y / 1e3} 秒):POST ${n}` : `${i}失败:无法请求 ${n}(${t instanceof Error ? t.message : String(t)})` });
2997
+ throw new e(r ? "NETWORK_TIMEOUT" : "LEGACY_PLATFORM_UNREACHABLE", "network", !0, { cause: r ? `${i}超时(${J / 1e3} 秒):POST ${n}` : `${i}失败:无法请求 ${n}(${t instanceof Error ? t.message : String(t)})` });
2934
2998
  } finally {
2935
2999
  clearTimeout(o);
2936
3000
  }
2937
3001
  }
2938
3002
  //#endregion
2939
- export { D as a, f as c, o as d, l as f, E as i, c as l, i as m, X as n, C as o, a as p, Pe as r, x as s, Qe as t, s as u };
3003
+ export { D as a, f as c, o as d, l as f, E as i, c as l, i as m, X as n, C as o, a as p, Ie as r, x as s, et as t, s as u };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "3.2.6";
1
+ export declare const SDK_VERSION = "3.2.8";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@16x/webphone-sdk",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
4
4
  "homepage": "https://www.npmjs.com/package/@16x/webphone-sdk",
5
5
  "private": false,
6
6
  "license": "UNLICENSED",
@@ -1 +0,0 @@
1
- const e=require("./SharedWorkerProtocol-C-4KpECM.cjs");require("./createJsSipFactory-B1ORbJiP.cjs");function t(e){let t=new Map;return{peerConnection:{getSenders:()=>e.getSenders().map(n=>{let r=t.get(n);if(r!==void 0)return r;let i={get track(){return n.track},get senderKind(){let t=n.track;if(t!==null)return t.kind===`audio`||t.kind===`video`?t.kind:void 0;let r=e.getTransceivers().find(e=>e.sender===n)?.receiver.track;if(r?.kind===`audio`||r?.kind===`video`)return r.kind;let i=n.getParameters().codecs?.find(e=>typeof e.mimeType==`string`);if(i?.mimeType?.toLowerCase().startsWith(`video/`))return`video`;if(i?.mimeType?.toLowerCase().startsWith(`audio/`))return`audio`},replaceTrack:e=>n.replaceTrack(e)};return t.set(n,i),i}),close:()=>{e.connectionState!==`closed`&&e.close()}},trackSource:{onTrack(t){let n=e=>{let n=e.track;t({streams:[...e.streams],track:n})};return e.addEventListener(`track`,n),()=>e.removeEventListener(`track`,n)}}}}var n=2e3;function r(e){if(!e)return``;let t=String(e.type??``);return t===``?/ typ (\w+)/.exec(String(e.candidate??``))?.[1]??``:t}function i(e,t={}){let i=Number.isFinite(t.timeoutMs)&&t.timeoutMs>0?t.timeoutMs:n;if(typeof RTCPeerConnection>`u`||!Array.isArray(e))return Promise.resolve([]);let a=[];for(let t of e){if(!t)continue;let e=Array.isArray(t.urls)?t.urls:[t.urls];for(let n of e){let e=String(n??``).trim();/^(stun|turn|turns):/i.test(e)&&a.push({url:e,entry:t})}}return Promise.all(a.map(e=>new Promise(t=>{let n=!1,a,o=r=>{if(!n){n=!0,clearTimeout(s);try{a?.close()}catch{}t({url:e.url,ok:r,tcp:/transport=tcp/i.test(e.url)||/^turns:/i.test(e.url)})}},s=setTimeout(()=>o(!1),i);try{let t={urls:[e.url]};e.entry.username&&(t.username=e.entry.username),e.entry.credential&&(t.credential=e.entry.credential),a=new RTCPeerConnection({iceServers:[t]}),a.createDataChannel(`webphone-ice-probe`),a.onicecandidate=e=>{if(!e||!e.candidate)return;let t=r(e.candidate);(t===`srflx`||t===`relay`)&&o(!0)},a.createOffer().then(e=>a?.setLocalDescription(e)).catch(()=>o(!1))}catch{o(!1)}})))}function a(e,t){let n=new Map;for(let e of t)e&&e.url&&n.set(String(e.url),e.ok===!0);let r=[];for(let t of e??[]){if(!t)continue;let e=(Array.isArray(t.urls)?t.urls:[t.urls]).filter(Boolean).filter(e=>n.get(String(e))===!0);if(e.length===0)continue;let i={...t,urls:e};r.push(i)}return r}var o=class{convergedList;lastResults=[];snapshotState={runs:0,lastMs:null,udpOk:!1,tcpRelayOk:!1,convergedServers:null,unchanged:null};running=!1;seq=0;converged(e){return this.convergedList??e}snapshot(){return this.snapshotState}reset(){this.seq++,this.running=!1,this.convergedList=void 0,this.lastResults=[],this.snapshotState={runs:0,lastMs:null,udpOk:!1,tcpRelayOk:!1,convergedServers:null,unchanged:null}}assess(e,t={}){if(e===void 0||e.length===0)return;let n=e.map(e=>({...e,urls:Array.isArray(e.urls)?[...e.urls]:[e.urls]}));if(typeof RTCPeerConnection>`u`||!n.some(e=>(Array.isArray(e.urls)?e.urls:[e.urls]).some(e=>/^(stun|turn|turns):/i.test(String(e??``)))))return;let r=++this.seq;this.running=!0;let o=Date.now();i(n,t).then(e=>{if(r!==this.seq)return;this.lastResults=e;let t=n,i=a(t,e);this.convergedList=i,this.snapshotState={runs:this.snapshotState.runs+1,lastMs:Date.now()-o,udpOk:e.some(e=>e.ok&&!e.tcp),tcpRelayOk:e.some(e=>e.ok&&e.tcp),convergedServers:i.length,unchanged:JSON.stringify(i)===JSON.stringify(t)}}).catch(()=>{this.seq}).finally(()=>{r===this.seq&&(this.running=!1)})}isRunning(){return this.running}},s=3e3;function c(e){if(!e)return``;let t=String(e.type??``);return t===``?/ typ (\w+)/.exec(String(e.candidate??``))?.[1]??``:t}function l(e,t={}){if(typeof e.on!=`function`)return()=>void 0;let n=Number.isFinite(t.timeoutMs)&&t.timeoutMs>0?t.timeoutMs:s,r=!1,i,a=()=>{if(!r){r=!0,clearTimeout(l);try{i?.()}catch{}}},o=e=>{let t=e;if(!t||typeof t.ready!=`function`)return;i=t.ready;let n=c(t.candidate);(n===`srflx`||n===`relay`)&&a()};e.on(`icecandidate`,o);let l=setTimeout(a,n);return()=>{clearTimeout(l);try{e.off?.(`icecandidate`,o)}catch{}}}var u=300,d=25,f=2,p=``,m=120;function h(e){let t=Math.floor(Number(e.sip.registerExpires));return Number.isFinite(t)&&t>0?t:u}var g=class{factory;transportBaseUrl;keepaliveSeconds;agentTerminal;sessionTimers;ua;uaListeners;incomingHandlers;iceServers;pendingConnection;disposed=!1;warmPc;keepaliveTimer;keepaliveBusy=!1;registerExpiresSeconds=0;connectionHandlers=new Set;iceQuality=new o;constructor(e,t,n=d,r=p,i=!1){this.factory=e,this.transportBaseUrl=t,this.keepaliveSeconds=n,this.agentTerminal=r,this.sessionTimers=i}terminalHeaders(){return this.agentTerminal===``?[]:[`X-Agent-Terminal: ${this.agentTerminal}`]}warmIceCandidatePool(){if(this.closeWarmPc(),typeof RTCPeerConnection<`u`&&this.iceServers!==void 0)try{this.warmPc=new RTCPeerConnection({iceServers:[...this.iceServers],iceCandidatePoolSize:f})}catch{this.warmPc=void 0}}closeWarmPc(){try{this.warmPc?.close()}catch{}this.warmPc=void 0}keepaliveTick(e){if(this.isCurrentUa(e)&&!this.keepaliveBusy)try{if(typeof e.isConnected==`function`&&e.isConnected()===!1||typeof e.register!=`function`)return;this.keepaliveBusy=!0,e.register({extraHeaders:this.terminalHeaders()})}catch{}finally{this.keepaliveBusy=!1}}startKeepalive(e,t){if(this.stopKeepalive(),!Number.isFinite(this.keepaliveSeconds)||this.keepaliveSeconds<=0||t>0&&t<=this.keepaliveSeconds)return;let n=Math.max(10,Math.floor(this.keepaliveSeconds))*1e3;this.keepaliveTimer=setInterval(()=>this.keepaliveTick(e),n)}stopKeepalive(){this.keepaliveTimer!==void 0&&clearInterval(this.keepaliveTimer),this.keepaliveTimer=void 0}connect(t){this.assertNotDisposed(),this.disconnect(this.registrationError(`SIP connection replaced`));try{let e=this.factory.createUa({sockets:b(this.factory.createSocket(this.withoutTicket(this.resolveWssUrl(t.transport.wssUrl)),t.transport.ticket)),uri:t.sip.uri,password:t.sip.registerTicket,registrar_server:t.sip.registrar,register:!0,register_expires:h(t),session_timers:this.sessionTimers,...this.agentTerminal===``?{}:{user_agent:this.agentTerminal}});return this.ua=e,this.registerExpiresSeconds=h(t),this.iceServers=t.iceServers,this.uaListeners=[],this.startRegistration(e)}catch(t){let n=t instanceof e.i&&t.code===`CONFIG_INVALID`?t:this.transportError(t);return this.disconnect(n),Promise.reject(n)}}disconnect(e=this.registrationError(`SIP connection disconnected`)){this.stopKeepalive(),this.closeWarmPc(),this.iceQuality.reset();let t=this.pendingConnection;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,t?.reject(e)}dial(t,n){let r=this.requireUa();if(t.trim()===``)throw new e.i(`CALL_INVALID_DESTINATION`,`call`,!1);try{let e=n===void 0?{mediaConstraints:{audio:!0,video:!1},sessionTimersExpires:m,pcConfig:{iceServers:this.dialIceServers(),iceCandidatePoolSize:f}}:{mediaConstraints:{audio:!0,video:!1},sessionTimersExpires:m,pcConfig:{iceServers:[...n.iceServers],iceCandidatePoolSize:f},extraHeaders:[...this.terminalHeaders(),...n.extraHeaders,...n.type===`extension`?[`X-XCall-Destination-Type: extension`]:[]]};return new _(r.call(t,e))}catch(t){throw new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{cause:t})}}onIncoming(e){this.assertNotDisposed();let t=this.incomingHandlers??new Set;return this.incomingHandlers=t,t.add(e),()=>t.delete(e)}onConnectionStateChanged(e){return this.disposed?()=>void 0:(this.connectionHandlers.add(e),()=>this.connectionHandlers.delete(e))}dispose(){this.disposed||(this.disposed=!0,this.disconnect(),this.incomingHandlers=void 0,this.connectionHandlers.clear())}dialIceServers(){let e=this.iceQuality.converged(this.iceServers);return e===void 0?void 0:[...e]}iceQualitySnapshot(){return this.iceQuality.snapshot()}getResourceCounts(){return{listeners:(this.uaListeners?.length??0)+(this.incomingHandlers?.size??0)+this.connectionHandlers.size,webSockets:this.ua===void 0?0:1}}handleIncoming(e){if(!v(e))return;let t=e.session;if(t===void 0)return;let n=new _(t);this.incomingHandlers?.forEach(e=>e(n))}startRegistration(e){let t=!0,n=!1,r=new Promise((t,n)=>{this.pendingConnection={ua:e,resolve:t,reject:n}});this.listen(e,`registered`,()=>{if(this.isCurrentUa(e)){if(t){n=!0;return}this.resolveConnection(e)}}),this.listen(e,`registrationFailed`,t=>{if(!this.isCurrentUa(e))return;let n=this.registrationError(this.registrationFailureCause(t));this.connectionHandlers.forEach(e=>e(`failed`,n)),this.disconnect(n)}),this.listen(e,`disconnected`,t=>{if(!this.isCurrentUa(e))return;let n=this.transportError(t);this.connectionHandlers.forEach(e=>e(`disconnected`,n)),this.disconnect(n)}),this.listen(e,`newRTCSession`,t=>{this.isCurrentUa(e)&&this.handleIncoming(t)});try{e.start()}catch(e){let t=this.transportError(e);this.connectionHandlers.forEach(e=>e(`failed`,t)),this.disconnect(t)}finally{t=!1}return n&&this.resolveConnection(e),r}listen(e,t,n){e.on(t,n),this.uaListeners?.push({event:t,handler:n})}removeUaListeners(e){this.uaListeners?.forEach(({event:t,handler:n})=>e.off(t,n))}isCurrentUa(e){return this.ua===e}resolveConnection(e){let t=this.pendingConnection;t?.ua===e&&(this.pendingConnection=void 0,t.resolve(),this.warmIceCandidatePool(),this.iceQuality.assess(this.iceServers),this.startKeepalive(e,this.registerExpiresSeconds),this.connectionHandlers.forEach(e=>e(`registered`)))}resolveWssUrl(e){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);return n.protocol===`http:`&&(n.protocol=`ws:`),n.protocol===`https:`&&(n.protocol=`wss:`),this.assertAllowedWssUrl(n),n.toString()}assertAllowedWssUrl(t){if(t.protocol!==`wss:`&&!(t.protocol===`ws:`&&x(t.hostname)))throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:t.origin})}withoutTicket(e){let t=new URL(e);return t.searchParams.delete(`ticket`),t.toString()}requireUa(){if(this.assertNotDisposed(),this.ua===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return this.ua}assertNotDisposed(){if(this.disposed)throw new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)}registrationError(t){return new e.i(`REGISTRATION_FAILED`,`registration`,!0,{cause:t})}transportError(t){return new e.i(`SIP_WS_UNAVAILABLE`,`registration`,!0,{cause:t})}registrationFailureCause(e){return typeof e==`object`&&e&&`cause`in e?e.cause:e}},_=class{session;pendingHoldReject;mediaRegistration;mediaConnection;mediaHandlers=new Set;mediaWatchStarted=!1;sessionUnsubscribeFromPeerConnection;detachIceGatheringTimeout;constructor(e){this.session=e,this.detachIceGatheringTimeout=l(e)}get id(){return this.session.id}get from(){return this.session.from??S(this.session.remote_identity)}getMediaRegistration(){let e=this.session.connection;if(e!=null)return this.mediaRegistration!==void 0&&this.mediaConnection===e?this.mediaRegistration:(this.mediaConnection=e,this.mediaRegistration=t(e),this.mediaRegistration)}answer(e){this.session.answer({mediaConstraints:e.mediaConstraints,pcConfig:{iceServers:[...e.pcConfig.iceServers],iceCandidatePoolSize:f}})}terminate(){this.detachIceGatheringTimeout?.(),this.detachIceGatheringTimeout=void 0,this.pendingHoldReject?.(Error(`SIP session terminated`)),this.session.terminate()}hold(){return this.changeHoldState(`hold`)}unhold(){return this.changeHoldState(`unhold`)}mute(){this.session.mute()}unmute(){this.session.unmute()}sendDtmf(e){this.session.sendDTMF(e)}refer(e){this.session.refer(e)}on(e,t){return e===`mediaConnected`?(this.mediaHandlers.add(t),this.watchMediaConnection(),()=>{this.mediaHandlers.delete(t),this.mediaHandlers.size===0&&(this.sessionUnsubscribeFromPeerConnection?.(),this.sessionUnsubscribeFromPeerConnection=void 0)}):(this.session.on(e,t),()=>this.session.off(e,t))}watchMediaConnection(){if(this.mediaWatchStarted)return;this.mediaWatchStarted=!0;let e=!1,t=t=>{if(t==null)return;let n=()=>{if(e)return;let n=t.connectionState||t.iceConnectionState;if(n===`connected`){e=!0;for(let e of this.mediaHandlers)try{e({state:n})}catch{}}};t.addEventListener(`connectionstatechange`,n),n()},n=this.session.connection;if(n!=null){t(n);return}let r=e=>{t(e?.peerconnection??void 0)};this.session.on(`peerconnection`,r),this.sessionUnsubscribeFromPeerConnection=()=>this.session.off(`peerconnection`,r)}changeHoldState(t){return new Promise((n,r)=>{let i=!1,a=e=>{c(e)},o=()=>{try{this.session.off(`ended`,a)}catch{}try{this.session.off(`failed`,a)}catch{}this.pendingHoldReject===c&&(this.pendingHoldReject=void 0)},s=()=>{i||(i=!0,o(),n())},c=t=>{i||(i=!0,o(),r(new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{cause:t})))};try{this.session.on(`ended`,a),this.session.on(`failed`,a)}catch(e){c(e);return}this.pendingHoldReject=c;try{this.session[t](void 0,s)||c({reason:`jssip_operation_rejected`,operation:t})}catch(e){c(e)}})}};function v(e){if(typeof e!=`object`||!e)return!1;let t=e;return t.originator===`remote`&&y(t.session)}function y(e){return typeof e==`object`&&!!e&&`id`in e}function b(e){return typeof e==`object`&&e&&(e.via_transport=`WSS`),e}function x(e){let t=e.replace(/^\[|\]$/g,``).toLowerCase();return t===`localhost`||t===`127.0.0.1`||t===`::1`||t===`0:0:0:0:0:0:0:1`}function S(e){let t=e?.uri;if(t==null)return;if(typeof t.user==`string`&&t.user!==``)return t.user;let n=t.toString();return n.match(/^sips?:([^@;>]+)/i)?.[1]??(n===``?void 0:n)}exports.JsSipAdapter=g;