@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
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- import { S as Softphone } from './softphone-DhuhcKCy.cjs';
2
- export { A as AudioDevices } from './softphone-DhuhcKCy.cjs';
3
- import { S as SoftphoneConfig } from './call-BTYlT2SU.cjs';
4
- export { C as CALL_TRANSITIONS, a as Call, b as CallDirection, c as CallEvent, d as CallEventMap, e as CallOptions, f as CallState, g as Contact, E as ERROR_CATALOGUE, F as FatalErrorCode, h as FatalSoftphoneError, H as HangupReason, i as HoldOriginator, I as INITIAL_STATES, L as LogLevel, N as NonFatalErrorCode, j as NonFatalSoftphoneError, R as RemoteParty, k as SoftphoneError, l as SoftphoneErrorCode, m as SoftphoneEvent, n as SoftphoneEventMap, o as SoftphoneState, T as TokenEndpointOptions, p as TokenSource, q as TypedEmitter, V as VoiceToken, r as canTransition, s as isFatal, t as isTerminal } from './call-BTYlT2SU.cjs';
1
+ import { S as Softphone } from './softphone-DHG9MTNg.cjs';
2
+ export { A as AudioDevices } from './softphone-DHG9MTNg.cjs';
3
+ import { S as SoftphoneConfig } from './call-DUVnDxsz.cjs';
4
+ export { C as CALL_TRANSITIONS, a as Call, b as CallDirection, c as CallEvent, d as CallEventMap, e as CallOptions, f as CallState, g as Contact, E as ERROR_CATALOGUE, F as FatalErrorCode, h as FatalSoftphoneError, H as HangupReason, i as HoldOriginator, I as INITIAL_STATES, L as LogLevel, N as NonFatalErrorCode, j as NonFatalSoftphoneError, R as RemoteParty, k as SoftphoneError, l as SoftphoneErrorCode, m as SoftphoneEvent, n as SoftphoneEventMap, o as SoftphoneState, T as TokenEndpointOptions, p as TokenSource, q as TypedEmitter, V as VoiceToken, r as canTransition, s as isFatal, t as isTerminal } from './call-DUVnDxsz.cjs';
5
5
 
6
6
  /**
7
7
  * Construct a softphone.
@@ -57,6 +57,6 @@ declare function isWebRtcSupported(): boolean;
57
57
  * - `MockProvider` — lives at @coventia/softphone/testing, so it never lands in a production bundle.
58
58
  */
59
59
 
60
- declare const VERSION = "0.0.0";
60
+ declare const VERSION = "0.2.0";
61
61
 
62
62
  export { Softphone, SoftphoneConfig, VERSION, createSoftphone, isBrowser, isWebRtcSupported };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { S as Softphone } from './softphone-DHmhotbf.js';
2
- export { A as AudioDevices } from './softphone-DHmhotbf.js';
3
- import { S as SoftphoneConfig } from './call-BTYlT2SU.js';
4
- export { C as CALL_TRANSITIONS, a as Call, b as CallDirection, c as CallEvent, d as CallEventMap, e as CallOptions, f as CallState, g as Contact, E as ERROR_CATALOGUE, F as FatalErrorCode, h as FatalSoftphoneError, H as HangupReason, i as HoldOriginator, I as INITIAL_STATES, L as LogLevel, N as NonFatalErrorCode, j as NonFatalSoftphoneError, R as RemoteParty, k as SoftphoneError, l as SoftphoneErrorCode, m as SoftphoneEvent, n as SoftphoneEventMap, o as SoftphoneState, T as TokenEndpointOptions, p as TokenSource, q as TypedEmitter, V as VoiceToken, r as canTransition, s as isFatal, t as isTerminal } from './call-BTYlT2SU.js';
1
+ import { S as Softphone } from './softphone-BtdgZWkm.js';
2
+ export { A as AudioDevices } from './softphone-BtdgZWkm.js';
3
+ import { S as SoftphoneConfig } from './call-DUVnDxsz.js';
4
+ export { C as CALL_TRANSITIONS, a as Call, b as CallDirection, c as CallEvent, d as CallEventMap, e as CallOptions, f as CallState, g as Contact, E as ERROR_CATALOGUE, F as FatalErrorCode, h as FatalSoftphoneError, H as HangupReason, i as HoldOriginator, I as INITIAL_STATES, L as LogLevel, N as NonFatalErrorCode, j as NonFatalSoftphoneError, R as RemoteParty, k as SoftphoneError, l as SoftphoneErrorCode, m as SoftphoneEvent, n as SoftphoneEventMap, o as SoftphoneState, T as TokenEndpointOptions, p as TokenSource, q as TypedEmitter, V as VoiceToken, r as canTransition, s as isFatal, t as isTerminal } from './call-DUVnDxsz.js';
5
5
 
6
6
  /**
7
7
  * Construct a softphone.
@@ -57,6 +57,6 @@ declare function isWebRtcSupported(): boolean;
57
57
  * - `MockProvider` — lives at @coventia/softphone/testing, so it never lands in a production bundle.
58
58
  */
59
59
 
60
- declare const VERSION = "0.0.0";
60
+ declare const VERSION = "0.2.0";
61
61
 
62
62
  export { Softphone, SoftphoneConfig, VERSION, createSoftphone, isBrowser, isWebRtcSupported };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isBrowser } from './chunk-KAXEMJ7E.js';
2
2
  export { isBrowser, isWebRtcSupported } from './chunk-KAXEMJ7E.js';
3
- export { CallEvent, SoftphoneEvent } from './chunk-N2N2EQQJ.js';
3
+ export { CallEvent, SoftphoneEvent } from './chunk-7R6LOOAI.js';
4
4
  import { isFatal } from './chunk-2ZSOGGPO.js';
5
5
  export { ERROR_CATALOGUE, isFatal } from './chunk-2ZSOGGPO.js';
6
6
  import { cachedTokenSource } from './chunk-MHOJHG5E.js';
@@ -78,10 +78,11 @@ function isTerminal(state) {
78
78
 
79
79
  // src/core/call-impl.ts
80
80
  var CallImpl = class _CallImpl extends Emitter {
81
- constructor(engineCall, onListenerError, onInternalError) {
81
+ constructor(engineCall, onListenerError, onInternalError, onTransfer) {
82
82
  super(onListenerError);
83
83
  this.engineCall = engineCall;
84
84
  this.onInternalError = onInternalError;
85
+ this.onTransfer = onTransfer;
85
86
  this.#onListenerError = onListenerError;
86
87
  this.#state = INITIAL_STATES[engineCall.direction];
87
88
  this.#remote = {
@@ -93,6 +94,7 @@ var CallImpl = class _CallImpl extends Emitter {
93
94
  }
94
95
  engineCall;
95
96
  onInternalError;
97
+ onTransfer;
96
98
  #state;
97
99
  #remote;
98
100
  #answeredAt = null;
@@ -178,7 +180,10 @@ var CallImpl = class _CallImpl extends Emitter {
178
180
  }
179
181
  async hangup() {
180
182
  if (isTerminal(this.#state)) return;
181
- await this.engineCall.hangup();
183
+ const consult = this.#consultCall;
184
+ this.#consultCall = null;
185
+ this.#consultEngineCall = null;
186
+ await Promise.all([consult?.hangup() ?? Promise.resolve(), this.engineCall.hangup()]);
182
187
  }
183
188
  mute(muted) {
184
189
  if (this.#muted === muted) return;
@@ -200,6 +205,7 @@ var CallImpl = class _CallImpl extends Emitter {
200
205
  }
201
206
  async transfer(target) {
202
207
  await this.engineCall.transfer(target);
208
+ this.onTransfer?.(target, this.#remote.number.trim() || null);
203
209
  }
204
210
  async startConsult(target) {
205
211
  await this.hold();
@@ -235,6 +241,12 @@ var CallImpl = class _CallImpl extends Emitter {
235
241
  }
236
242
  #end(reason) {
237
243
  if (isTerminal(this.#state)) return;
244
+ if (this.#consultCall) {
245
+ const consult = this.#consultCall;
246
+ this.#consultCall = null;
247
+ this.#consultEngineCall = null;
248
+ void consult.hangup();
249
+ }
238
250
  const from = this.#state;
239
251
  this.#state = "ended";
240
252
  this.emit("stateChanged" /* StateChanged */, { state: "ended", previous: from });
@@ -269,7 +281,7 @@ function coventiaBackend(config, tokenSource, fallbackBaseUrl) {
269
281
  }
270
282
  let pending = null;
271
283
  const load = () => {
272
- pending ??= import('./sources-N4BOEDRL.js').then(
284
+ pending ??= import('./sources-5L2R4HTV.js').then(
273
285
  (m) => m.coventiaSources({ ...config, baseUrl, tokenSource })
274
286
  );
275
287
  return pending;
@@ -278,7 +290,9 @@ function coventiaBackend(config, tokenSource, fallbackBaseUrl) {
278
290
  contacts: async (params) => (await load()).contacts(params),
279
291
  history: async (params) => (await load()).history(params),
280
292
  resolveContact: async (number) => (await load()).resolveContact(number),
281
- listAgents: async () => (await load()).listAgents()
293
+ listAgents: async () => (await load()).listAgents(),
294
+ transferOutcomes: async (params) => (await load()).transferOutcomes(params),
295
+ presence: async (callbacks) => (await load()).presence(callbacks)
282
296
  };
283
297
  }
284
298
 
@@ -315,6 +329,166 @@ function webLocksTabLock(lockName = LOCK_NAME) {
315
329
  };
316
330
  }
317
331
 
332
+ // src/core/transfer-watch.ts
333
+ var FAST_INTERVAL_MS = 2e3;
334
+ var FAST_WINDOW_MS = 1e4;
335
+ var SLOW_INTERVAL_MS = 5e3;
336
+ var DEADLINE_MS = 9e4;
337
+ var EXTENSION_LIKE = /^\d{1,6}$/;
338
+ function startTransferWatch(params) {
339
+ const {
340
+ target,
341
+ callerNumber,
342
+ source,
343
+ getIsLeader,
344
+ emit,
345
+ setTimeout: scheduleTimeout = globalThis.setTimeout,
346
+ clearTimeout: cancelTimeout = globalThis.clearTimeout,
347
+ now = () => Date.now()
348
+ } = params;
349
+ if (!EXTENSION_LIKE.test(target)) return () => {
350
+ };
351
+ if (!getIsLeader()) return () => {
352
+ };
353
+ let stopped = false;
354
+ let timer = null;
355
+ let cursor = null;
356
+ const startedAt = now();
357
+ const stop = () => {
358
+ stopped = true;
359
+ if (timer !== null) {
360
+ cancelTimeout(timer);
361
+ timer = null;
362
+ }
363
+ };
364
+ const finish = (status) => {
365
+ stop();
366
+ emit({ status, target, caller: callerNumber, at: new Date(now()) });
367
+ };
368
+ const scheduleNext = () => {
369
+ if (stopped) return;
370
+ const elapsed = now() - startedAt;
371
+ if (elapsed >= DEADLINE_MS) {
372
+ stop();
373
+ return;
374
+ }
375
+ timer = scheduleTimeout(() => void poll(), elapsed < FAST_WINDOW_MS ? FAST_INTERVAL_MS : SLOW_INTERVAL_MS);
376
+ };
377
+ const poll = async () => {
378
+ if (stopped) return;
379
+ if (!getIsLeader()) {
380
+ stop();
381
+ return;
382
+ }
383
+ let page;
384
+ try {
385
+ page = await source(cursor === null ? {} : { since: cursor });
386
+ } catch {
387
+ if (!stopped) scheduleNext();
388
+ return;
389
+ }
390
+ if (stopped) return;
391
+ if (cursor === null) {
392
+ cursor = page.cursor;
393
+ } else {
394
+ cursor = page.cursor;
395
+ const match = page.outcomes.find((o) => o.target === target);
396
+ if (match) {
397
+ finish(match.status);
398
+ return;
399
+ }
400
+ }
401
+ scheduleNext();
402
+ };
403
+ void poll();
404
+ return stop;
405
+ }
406
+
407
+ // src/core/presence-socket.ts
408
+ var RECONNECT_BASE_MS = 1e3;
409
+ var RECONNECT_MAX_MS = 3e4;
410
+ var NOOP_WATCH = { reportCallState: () => {
411
+ }, stop: () => {
412
+ } };
413
+ function startPresenceSocket(params) {
414
+ const {
415
+ source,
416
+ getIsLeader,
417
+ onAgentsChanged,
418
+ setTimeout: scheduleTimeout = globalThis.setTimeout,
419
+ clearTimeout: cancelTimeout = globalThis.clearTimeout,
420
+ random = Math.random
421
+ } = params;
422
+ if (!getIsLeader()) return NOOP_WATCH;
423
+ let stopped = false;
424
+ let attempt = 0;
425
+ let reconnectTimer = null;
426
+ let agents = /* @__PURE__ */ new Map();
427
+ let lastReportedOnCall = null;
428
+ let connection = null;
429
+ const stop = () => {
430
+ if (stopped) return;
431
+ stopped = true;
432
+ if (reconnectTimer !== null) {
433
+ cancelTimeout(reconnectTimer);
434
+ reconnectTimer = null;
435
+ }
436
+ connection?.close();
437
+ connection = null;
438
+ };
439
+ const scheduleReconnect = () => {
440
+ if (stopped) return;
441
+ attempt += 1;
442
+ const capped = Math.min(RECONNECT_BASE_MS * 2 ** (attempt - 1), RECONNECT_MAX_MS);
443
+ const delay = capped * random();
444
+ reconnectTimer = scheduleTimeout(() => void connect(), delay);
445
+ };
446
+ const connect = async () => {
447
+ if (stopped) return;
448
+ if (!getIsLeader()) {
449
+ stop();
450
+ return;
451
+ }
452
+ let opened;
453
+ try {
454
+ opened = await source({
455
+ onSnapshot: (snapshot) => {
456
+ agents = new Map(snapshot.map((agent) => [agent.userId, agent]));
457
+ onAgentsChanged([...agents.values()]);
458
+ },
459
+ onDelta: (agent) => {
460
+ agents.set(agent.userId, agent);
461
+ onAgentsChanged([...agents.values()]);
462
+ },
463
+ onClose: () => {
464
+ if (connection === null) return;
465
+ connection = null;
466
+ scheduleReconnect();
467
+ }
468
+ });
469
+ } catch {
470
+ if (!stopped) scheduleReconnect();
471
+ return;
472
+ }
473
+ if (stopped) {
474
+ opened.close();
475
+ return;
476
+ }
477
+ connection = opened;
478
+ attempt = 0;
479
+ if (lastReportedOnCall !== null) connection.reportCallState(lastReportedOnCall);
480
+ };
481
+ void connect();
482
+ return {
483
+ reportCallState: (onCall) => {
484
+ if (onCall === lastReportedOnCall) return;
485
+ lastReportedOnCall = onCall;
486
+ connection?.reportCallState(onCall);
487
+ },
488
+ stop
489
+ };
490
+ }
491
+
318
492
  // src/core/softphone-impl.ts
319
493
  var liveInstance = false;
320
494
  var BrowserAudioDevices = class {
@@ -377,6 +551,21 @@ var SoftphoneImpl = class extends Emitter {
377
551
  /** Contacts + history, whenever there is a Coventia backend to reach. The widget reads these. */
378
552
  sources;
379
553
  audio;
554
+ /**
555
+ * Every in-flight transfer-outcome watch (Phase A), so `destroy()` can stop all of them. Never
556
+ * pruned as individual watches finish on their own — `stop()` is idempotent and cheap to call again,
557
+ * and a session accumulating a handful of closures for however many transfers it makes is not worth
558
+ * the bookkeeping a self-removing set would add.
559
+ */
560
+ #activeWatches = /* @__PURE__ */ new Set();
561
+ /**
562
+ * Phase B (presence-gated transfer picker). ONE long-lived watch, not a member of `#activeWatches`
563
+ * — that set is per-transfer instances a live call spawns and forgets; this is a single background
564
+ * connection tied to the softphone's own lifecycle, started and stopped by `#syncPresenceWatch`
565
+ * rather than by any one call.
566
+ */
567
+ #presenceWatch = null;
568
+ #presenceAgents = [];
380
569
  /**
381
570
  * `tabLock` defaults to the real Web Locks implementation — not part of `SoftphoneConfig` (an
382
571
  * internal seam, not something an integrator tunes). Tests construct this class directly with a
@@ -409,6 +598,9 @@ var SoftphoneImpl = class extends Emitter {
409
598
  get activeCall() {
410
599
  return this.#activeCall;
411
600
  }
601
+ get presence() {
602
+ return this.#presenceAgents;
603
+ }
412
604
  get canPlayAudio() {
413
605
  return true;
414
606
  }
@@ -445,6 +637,10 @@ var SoftphoneImpl = class extends Emitter {
445
637
  async destroy() {
446
638
  if (this.#destroyed) return;
447
639
  this.#destroyed = true;
640
+ for (const stopWatch of this.#activeWatches) stopWatch();
641
+ this.#activeWatches.clear();
642
+ this.#presenceWatch?.stop();
643
+ this.#presenceWatch = null;
448
644
  await this.stop().catch(() => {
449
645
  });
450
646
  this.#setState("destroyed");
@@ -475,7 +671,8 @@ var SoftphoneImpl = class extends Emitter {
475
671
  const call = new CallImpl(
476
672
  engineCall,
477
673
  (event, error) => this.#reportListenerError("call", event, error),
478
- (message) => this.#reportInternalError(message)
674
+ (message) => this.#reportInternalError(message),
675
+ (target, callerNumber) => this.#onTransfer(target, callerNumber)
479
676
  );
480
677
  this.#activeCall = call;
481
678
  const off = call.on("ended" /* Ended */, () => {
@@ -500,11 +697,62 @@ var SoftphoneImpl = class extends Emitter {
500
697
  this.#state = state;
501
698
  if (state === "online") this.#lastError = null;
502
699
  this.emit("stateChanged" /* StateChanged */, { state, previous });
700
+ this.#syncPresenceWatch();
503
701
  }
504
702
  #setLeader(isLeader) {
505
703
  if (isLeader === this.#isLeader) return;
506
704
  this.#isLeader = isLeader;
507
705
  this.emit("leaderChanged" /* LeaderChanged */, { isLeader });
706
+ this.#syncPresenceWatch();
707
+ }
708
+ /**
709
+ * Phase B (presence-gated transfer picker, `docs/specs/transfer-presence-picker.md` plan T6/T7).
710
+ * The ONE place that decides whether the presence connection should be running right now — called
711
+ * after every `#setState`/`#setLeader` transition rather than left to either alone, since either
712
+ * one flipping can change the answer. No-ops entirely when no Coventia backend is configured
713
+ * (`sources` is null) — same guard `#onTransfer` uses, and for the same reason: nothing to open.
714
+ *
715
+ * `presence-socket.ts`'s own `getIsLeader` is checked at start and before each reconnect attempt,
716
+ * not on a poll tick the way `startTransferWatch`'s is — see that module's own doc comment for why.
717
+ * This still passes `getIsLeader: () => this.#isLeader` for that narrower, defensive recheck; the
718
+ * BROAD online/leader gate — whether to be connected AT ALL — is owned entirely here, the same
719
+ * split `#onTransfer` already has with `startTransferWatch`.
720
+ */
721
+ #syncPresenceWatch() {
722
+ const shouldRun = Boolean(this.sources) && this.#state === "online" && this.#isLeader;
723
+ if (shouldRun === (this.#presenceWatch !== null)) return;
724
+ if (shouldRun) {
725
+ this.#presenceWatch = startPresenceSocket({
726
+ source: this.sources.presence,
727
+ getIsLeader: () => this.#isLeader,
728
+ onAgentsChanged: (agents) => {
729
+ this.#presenceAgents = agents;
730
+ this.emit("presenceChanged" /* PresenceChanged */, { agents });
731
+ }
732
+ });
733
+ } else {
734
+ this.#presenceWatch?.stop();
735
+ this.#presenceWatch = null;
736
+ this.#presenceAgents = [];
737
+ this.emit("presenceChanged" /* PresenceChanged */, { agents: [] });
738
+ }
739
+ }
740
+ /**
741
+ * Phase A (transfer outcome relay, `docs/specs/transfer-outcome-relay.md`) — `CallImpl.transfer()`'s
742
+ * internal seam calls this. No-ops entirely when no Coventia backend is configured (`sources` is
743
+ * null): there is then nothing to poll, and behaviour is exactly what it was before this feature
744
+ * existed (spec §5.4).
745
+ */
746
+ #onTransfer(target, callerNumber) {
747
+ if (!this.sources) return;
748
+ const stopWatch = startTransferWatch({
749
+ target,
750
+ callerNumber,
751
+ source: this.sources.transferOutcomes,
752
+ getIsLeader: () => this.#isLeader,
753
+ emit: (payload) => this.emit("transferOutcome" /* TransferOutcome */, payload)
754
+ });
755
+ this.#activeWatches.add(stopWatch);
508
756
  }
509
757
  /**
510
758
  * Re-emit an engine failure to the host, and remember it if it is fatal.
@@ -563,7 +811,7 @@ function defaultZadarmaEngine(config) {
563
811
  const stateChange = new LazyRelay();
564
812
  const error = new LazyRelay();
565
813
  function load() {
566
- pending ??= import('./zadarma-engine-DN2SZSQ3.js').then(({ createZadarmaEngine }) => {
814
+ pending ??= import('./zadarma-engine-4VOPIBXG.js').then(({ createZadarmaEngine }) => {
567
815
  const engine = createZadarmaEngine(config);
568
816
  incoming.attach({ on: (l) => engine.onIncoming(l) });
569
817
  stateChange.attach({ on: (l) => engine.onStateChange(l) });
@@ -623,7 +871,7 @@ function isCallEngine(value) {
623
871
  }
624
872
 
625
873
  // src/index.ts
626
- var VERSION = "0.0.0";
874
+ var VERSION = "0.2.0";
627
875
 
628
876
  export { CALL_TRANSITIONS, INITIAL_STATES, VERSION, canTransition, createSoftphone, isTerminal };
629
877
  //# sourceMappingURL=index.js.map