@coventia/softphone 0.1.0 → 0.2.0

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.
Files changed (54) hide show
  1. package/dist/{call-BTYlT2SU.d.cts → call-DUVnDxsz.d.cts} +152 -5
  2. package/dist/{call-BTYlT2SU.d.ts → call-DUVnDxsz.d.ts} +152 -5
  3. package/dist/{chunk-N2N2EQQJ.js → chunk-7R6LOOAI.js} +4 -2
  4. package/dist/chunk-7R6LOOAI.js.map +1 -0
  5. package/dist/{chunk-3V2L6UTK.js → chunk-LMJXX4YM.js} +17 -3
  6. package/dist/chunk-LMJXX4YM.js.map +1 -0
  7. package/dist/{chunk-5BGEHMPP.js → chunk-YWI6EQYS.js} +40 -7
  8. package/dist/chunk-YWI6EQYS.js.map +1 -0
  9. package/dist/element/index.d.ts +154 -5
  10. package/dist/element/index.js +512 -152
  11. package/dist/element/index.js.map +1 -1
  12. package/dist/{engine-D9nbeY08.d.cts → engine-CDjkrXHY.d.cts} +1 -1
  13. package/dist/{engine-Doa6Brkm.d.ts → engine-EPCKf-Bl.d.ts} +1 -1
  14. package/dist/index.cjs +396 -14
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +5 -5
  17. package/dist/index.d.ts +5 -5
  18. package/dist/index.js +256 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/react/index.cjs +15 -0
  21. package/dist/react/index.cjs.map +1 -1
  22. package/dist/react/index.d.cts +14 -3
  23. package/dist/react/index.d.ts +14 -3
  24. package/dist/react/index.js +2 -2
  25. package/dist/{softphone-DhuhcKCy.d.cts → softphone-BtdgZWkm.d.ts} +17 -2
  26. package/dist/{softphone-DHmhotbf.d.ts → softphone-DHG9MTNg.d.cts} +17 -2
  27. package/dist/softphone.css +395 -1
  28. package/dist/{sources-N4BOEDRL.js → sources-5L2R4HTV.js} +104 -5
  29. package/dist/sources-5L2R4HTV.js.map +1 -0
  30. package/dist/testing/index.cjs +41 -5
  31. package/dist/testing/index.cjs.map +1 -1
  32. package/dist/testing/index.d.cts +8 -2
  33. package/dist/testing/index.d.ts +8 -2
  34. package/dist/testing/index.js +41 -5
  35. package/dist/testing/index.js.map +1 -1
  36. package/dist/ui/index.cjs +490 -139
  37. package/dist/ui/index.cjs.map +1 -1
  38. package/dist/ui/index.d.cts +2 -2
  39. package/dist/ui/index.d.ts +2 -2
  40. package/dist/ui/index.js +478 -141
  41. package/dist/ui/index.js.map +1 -1
  42. package/dist/zadarma/index.cjs +38 -5
  43. package/dist/zadarma/index.cjs.map +1 -1
  44. package/dist/zadarma/index.d.cts +2 -2
  45. package/dist/zadarma/index.d.ts +2 -2
  46. package/dist/zadarma/index.js +1 -1
  47. package/dist/zadarma-engine-4VOPIBXG.js +5 -0
  48. package/dist/{zadarma-engine-DN2SZSQ3.js.map → zadarma-engine-4VOPIBXG.js.map} +1 -1
  49. package/package.json +1 -1
  50. package/dist/chunk-3V2L6UTK.js.map +0 -1
  51. package/dist/chunk-5BGEHMPP.js.map +0 -1
  52. package/dist/chunk-N2N2EQQJ.js.map +0 -1
  53. package/dist/sources-N4BOEDRL.js.map +0 -1
  54. package/dist/zadarma-engine-DN2SZSQ3.js +0 -5
@@ -421,6 +421,14 @@ var SipCallEngine = class {
421
421
  #uaInFlight = null;
422
422
  #domain = "";
423
423
  #activeCall = null;
424
+ /**
425
+ * The consult leg from `startConsult` (SPEC §5.6), if one is live on this UA right now.
426
+ *
427
+ * Tracked separately from `#activeCall` so `#maybeTeardownUA` can tell "both legs are actually gone"
428
+ * apart from "the main leg ended, but a consult is still up" — see that method's own comment for the
429
+ * bug this exists to prevent.
430
+ */
431
+ #consultCall = null;
424
432
  /** The chosen microphone, or `null` for the browser default. Read fresh by every new leg's
425
433
  * `mediaConstraints`, and pushed live to `#activeCall` by `setInputDevice`. */
426
434
  #inputDeviceId = null;
@@ -539,9 +547,7 @@ var SipCallEngine = class {
539
547
  const ms = this.provider.quirks?.noInviteTeardownMs;
540
548
  if (!ms) return;
541
549
  this.#clearNoInviteTimer();
542
- this.#noInviteTimer = setTimeout(() => {
543
- if (!this.#activeCall) this.#teardownUA();
544
- }, ms);
550
+ this.#noInviteTimer = setTimeout(() => this.#maybeTeardownUA(), ms);
545
551
  }
546
552
  /**
547
553
  * Rebuild the incoming-signal channel with fresh credentials, after a registration failure.
@@ -663,6 +669,7 @@ var SipCallEngine = class {
663
669
  }
664
670
  this.#ua = null;
665
671
  this.#activeCall = null;
672
+ this.#consultCall = null;
666
673
  }
667
674
  /** Place a call once the UA is registered (its 200 OK for REGISTER has arrived). */
668
675
  /**
@@ -705,7 +712,7 @@ var SipCallEngine = class {
705
712
  const code = missed ? "call/missed" : CALL_END_CODES[event.reason];
706
713
  if (code) this.#reportError(code, event.cause);
707
714
  if (this.#activeCall === call) this.#activeCall = null;
708
- if (this.provider.registrationMode === "on-demand") this.#teardownUA();
715
+ this.#maybeTeardownUA();
709
716
  }
710
717
  });
711
718
  return call;
@@ -716,12 +723,38 @@ var SipCallEngine = class {
716
723
  mediaConstraints: buildAudioConstraints(this.#inputDeviceId),
717
724
  pcConfig: PC_CONFIG
718
725
  });
719
- return new SipEngineCall(consultSession, {
726
+ const consultCall = new SipEngineCall(consultSession, {
720
727
  id: nextCallId(),
721
728
  buildTarget: (x) => this.#buildTarget(x),
722
729
  placeConsult: () => Promise.reject(new Error("cannot consult from a consult leg")),
723
730
  iceGatheringCapMs: this.provider.quirks?.iceGatheringCapMs ?? DEFAULT_ICE_CAP_MS
724
731
  });
732
+ this.#consultCall = consultCall;
733
+ consultCall.onEvent((event) => {
734
+ if (event.type === "ended") {
735
+ if (this.#consultCall === consultCall) this.#consultCall = null;
736
+ this.#maybeTeardownUA();
737
+ }
738
+ });
739
+ return consultCall;
740
+ }
741
+ /**
742
+ * On-demand registration (SPEC §3.3): the UA is disposable once NOTHING is left on it — but "the
743
+ * main leg ended" (or "no INVITE followed this push") is not the same fact as "nothing is left."
744
+ * `completeTransfer()` (SPEC §5.6) ends the main leg via a REFER…Replaces BYE *while the consult leg
745
+ * is still what the PBX needs to bridge the caller onto* — tearing the UA down (and with it, EVERY
746
+ * session on it, via `terminateSessions`) the instant the main leg's `ended` fires killed that
747
+ * consult leg out from under the transfer before the bridge could use it, and the caller was simply
748
+ * gone. Two real call sites hit this independently (found live, 2026-08-04): the main leg's own
749
+ * `ended` handler, and `#armNoInviteTeardown`'s 5s timer — the latter re-arms on EVERY push,
750
+ * including unrelated "answered" pushes Zadarma sends around other account activity, so it can fire
751
+ * minutes after a transfer with no `#activeCall` and no idea a consult leg is mid-handoff. Both now
752
+ * route through here rather than checking `#activeCall` alone.
753
+ */
754
+ #maybeTeardownUA() {
755
+ if (this.provider.registrationMode !== "on-demand") return;
756
+ if (this.#activeCall || this.#consultCall) return;
757
+ this.#teardownUA();
725
758
  }
726
759
  #startRejectGuard() {
727
760
  const ms = this.provider.quirks?.rejectGuardMs;