@telnyx/react-voice-commons-sdk 1.0.0 → 1.1.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.
- package/CHANGELOG.md +23 -0
- package/README.md +28 -7
- package/android/src/main/java/com/telnyx/react_voice_commons/CallForegroundService.kt +16 -2
- package/android/src/main/java/com/telnyx/react_voice_commons/TelnyxNotificationHelper.kt +345 -24
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnBridgeModule.kt +19 -0
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnManager.kt +19 -0
- package/ios/CallKitBridge.m +20 -1
- package/ios/CallKitBridge.swift +527 -78
- package/ios/README.md +2 -2
- package/ios/VoicePnBridge.m +6 -0
- package/ios/VoicePnBridge.swift +15 -0
- package/lib/callkit/callkit-coordinator.d.ts +39 -3
- package/lib/callkit/callkit-coordinator.js +561 -148
- package/lib/callkit/callkit.d.ts +7 -0
- package/lib/callkit/callkit.js +83 -11
- package/lib/hooks/useAppStateHandler.js +6 -2
- package/lib/internal/CallKitHandler.d.ts +3 -0
- package/lib/internal/CallKitHandler.js +52 -46
- package/lib/internal/calls/call-state-controller.d.ts +33 -1
- package/lib/internal/calls/call-state-controller.js +100 -28
- package/lib/internal/session/session-manager.d.ts +15 -1
- package/lib/internal/session/session-manager.js +214 -62
- package/lib/internal/voice-pn-bridge.d.ts +18 -0
- package/lib/internal/voice-pn-bridge.js +39 -0
- package/lib/models/call.js +35 -0
- package/lib/models/config.d.ts +10 -0
- package/lib/models/config.js +2 -0
- package/lib/telnyx-voice-app.js +85 -43
- package/lib/telnyx-voip-client.d.ts +46 -5
- package/lib/telnyx-voip-client.js +238 -22
- package/package.json +6 -4
- package/src/callkit/callkit-coordinator.ts +642 -160
- package/src/callkit/callkit.ts +110 -12
- package/src/hooks/useAppStateHandler.ts +7 -2
- package/src/internal/CallKitHandler.tsx +60 -55
- package/src/internal/calls/call-state-controller.ts +112 -29
- package/src/internal/session/session-manager.ts +260 -65
- package/src/internal/voice-pn-bridge.ts +47 -0
- package/src/models/call.ts +34 -0
- package/src/models/config.ts +10 -0
- package/src/telnyx-voice-app.tsx +96 -45
- package/src/telnyx-voip-client.ts +216 -24
- package/src/types/telnyx-sdk.d.ts +2 -1
package/lib/telnyx-voice-app.js
CHANGED
|
@@ -6,7 +6,30 @@ const react_1 = require('react');
|
|
|
6
6
|
const react_native_1 = require('react-native');
|
|
7
7
|
const telnyx_voip_client_1 = require('./telnyx-voip-client');
|
|
8
8
|
const connection_state_1 = require('./models/connection-state');
|
|
9
|
+
const call_state_1 = require('./models/call-state');
|
|
9
10
|
const TelnyxVoiceContext_1 = require('./context/TelnyxVoiceContext');
|
|
11
|
+
let sharedBackgroundClient = null;
|
|
12
|
+
let sharedBackgroundDisposePromise = null;
|
|
13
|
+
const disposeSharedBackgroundClient = async (log, expectedClient) => {
|
|
14
|
+
if (sharedBackgroundDisposePromise) {
|
|
15
|
+
await sharedBackgroundDisposePromise;
|
|
16
|
+
}
|
|
17
|
+
const backgroundClient = expectedClient ?? sharedBackgroundClient;
|
|
18
|
+
if (!backgroundClient || (expectedClient && sharedBackgroundClient !== expectedClient)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
sharedBackgroundClient = null;
|
|
22
|
+
log('Disposing background client instance');
|
|
23
|
+
sharedBackgroundDisposePromise = backgroundClient
|
|
24
|
+
.dispose()
|
|
25
|
+
.catch((e) => {
|
|
26
|
+
log('Error disposing background client instance:', e);
|
|
27
|
+
})
|
|
28
|
+
.finally(() => {
|
|
29
|
+
sharedBackgroundDisposePromise = null;
|
|
30
|
+
});
|
|
31
|
+
await sharedBackgroundDisposePromise;
|
|
32
|
+
};
|
|
10
33
|
/**
|
|
11
34
|
* A comprehensive wrapper component that handles all Telnyx SDK lifecycle management.
|
|
12
35
|
*
|
|
@@ -39,11 +62,17 @@ const TelnyxVoiceAppComponent = ({
|
|
|
39
62
|
const [currentConnectionState, setCurrentConnectionState] = (0, react_1.useState)(
|
|
40
63
|
voipClient.currentConnectionState
|
|
41
64
|
);
|
|
65
|
+
// Refs that mirror mutable state for use inside long-lived effects and
|
|
66
|
+
// callbacks. Reading these flags through refs (instead of the state
|
|
67
|
+
// variables) keeps the setup effect's dependency array stable so
|
|
68
|
+
// connection/call subscriptions are not torn down and recreated every
|
|
69
|
+
// time the flags change — fixing the subscription gap described in
|
|
70
|
+
// VSDK-344.
|
|
71
|
+
const isHandlingForegroundCallRef = (0, react_1.useRef)(false);
|
|
72
|
+
const processingPushOnLaunchRef = (0, react_1.useRef)(false);
|
|
42
73
|
// Refs for tracking state
|
|
43
74
|
const appStateRef = (0, react_1.useRef)(react_native_1.AppState.currentState);
|
|
44
75
|
const backgroundDetectorIgnore = (0, react_1.useRef)(false);
|
|
45
|
-
// Static background client instance for singleton pattern
|
|
46
|
-
const backgroundClientRef = (0, react_1.useRef)(null);
|
|
47
76
|
const log = (0, react_1.useCallback)(
|
|
48
77
|
(message, ...args) => {
|
|
49
78
|
if (debug) {
|
|
@@ -59,7 +88,7 @@ const TelnyxVoiceAppComponent = ({
|
|
|
59
88
|
appStateRef.current = nextAppState;
|
|
60
89
|
log(`App state changed from ${previousAppState} to ${nextAppState}`);
|
|
61
90
|
log(`Background detector ignore flag: ${backgroundDetectorIgnore.current}`);
|
|
62
|
-
log(`Handling foreground call: ${
|
|
91
|
+
log(`Handling foreground call: ${isHandlingForegroundCallRef.current}`);
|
|
63
92
|
// Call optional user callback first
|
|
64
93
|
onAppStateChanged?.(nextAppState);
|
|
65
94
|
// Only handle background disconnection when actually transitioning from active to background
|
|
@@ -87,12 +116,12 @@ const TelnyxVoiceAppComponent = ({
|
|
|
87
116
|
await handleAppResumed();
|
|
88
117
|
}
|
|
89
118
|
},
|
|
90
|
-
[enableAutoReconnect, onAppStateChanged,
|
|
119
|
+
[enableAutoReconnect, onAppStateChanged, log]
|
|
91
120
|
);
|
|
92
121
|
// Handle app going to background - disconnect like the old implementation
|
|
93
122
|
const handleAppBackgrounded = (0, react_1.useCallback)(async () => {
|
|
94
123
|
// Check if we should ignore background detection (e.g., during active calls)
|
|
95
|
-
if (backgroundDetectorIgnore.current ||
|
|
124
|
+
if (backgroundDetectorIgnore.current || isHandlingForegroundCallRef.current) {
|
|
96
125
|
log(
|
|
97
126
|
'Background detector ignore flag set or handling foreground call - skipping disconnection'
|
|
98
127
|
);
|
|
@@ -140,7 +169,7 @@ const TelnyxVoiceAppComponent = ({
|
|
|
140
169
|
} catch (e) {
|
|
141
170
|
log('Error disconnecting on background:', e);
|
|
142
171
|
}
|
|
143
|
-
}, [voipClient,
|
|
172
|
+
}, [voipClient, log]);
|
|
144
173
|
// Handle app resuming from background
|
|
145
174
|
const handleAppResumed = (0, react_1.useCallback)(async () => {
|
|
146
175
|
log('App resumed - checking reconnection needs');
|
|
@@ -148,7 +177,7 @@ const TelnyxVoiceAppComponent = ({
|
|
|
148
177
|
// This handles the case where the user accepted a call while the app was backgrounded
|
|
149
178
|
await checkForInitialPushNotification(true); // Pass true for fromAppResume
|
|
150
179
|
// If we're ignoring (e.g., from push call) or handling foreground call, don't auto-reconnect
|
|
151
|
-
if (backgroundDetectorIgnore.current ||
|
|
180
|
+
if (backgroundDetectorIgnore.current || isHandlingForegroundCallRef.current) {
|
|
152
181
|
log(
|
|
153
182
|
'Background detector ignore flag set or handling foreground call - skipping reconnection'
|
|
154
183
|
);
|
|
@@ -176,7 +205,7 @@ const TelnyxVoiceAppComponent = ({
|
|
|
176
205
|
if (currentState !== connection_state_1.TelnyxConnectionState.CONNECTED) {
|
|
177
206
|
await attemptAutoReconnection();
|
|
178
207
|
}
|
|
179
|
-
}, [voipClient,
|
|
208
|
+
}, [voipClient, log]);
|
|
180
209
|
// Attempt to reconnect using stored credentials
|
|
181
210
|
const attemptAutoReconnection = (0, react_1.useCallback)(async () => {
|
|
182
211
|
try {
|
|
@@ -296,12 +325,13 @@ const TelnyxVoiceAppComponent = ({
|
|
|
296
325
|
const checkForInitialPushNotification = (0, react_1.useCallback)(
|
|
297
326
|
async (fromAppResume = false) => {
|
|
298
327
|
log(`checkForInitialPushNotification called${fromAppResume ? ' (from app resume)' : ''}`);
|
|
299
|
-
if (
|
|
328
|
+
if (processingPushOnLaunchRef.current && !fromAppResume) {
|
|
300
329
|
log('Already processing push, returning early');
|
|
301
330
|
return;
|
|
302
331
|
}
|
|
303
332
|
if (!fromAppResume) {
|
|
304
333
|
setProcessingPushOnLaunch(true);
|
|
334
|
+
processingPushOnLaunchRef.current = true;
|
|
305
335
|
}
|
|
306
336
|
onPushNotificationProcessingStarted?.();
|
|
307
337
|
try {
|
|
@@ -324,11 +354,20 @@ const TelnyxVoiceAppComponent = ({
|
|
|
324
354
|
// Prevent duplicate processing if already connected or connecting.
|
|
325
355
|
// Since push data is no longer cleared on read, this guard prevents
|
|
326
356
|
// re-processing when checkForInitialPushNotification fires again on app resume.
|
|
327
|
-
|
|
357
|
+
const isConnectedOrConnecting =
|
|
328
358
|
voipClient.currentConnectionState ===
|
|
329
359
|
connection_state_1.TelnyxConnectionState.CONNECTED ||
|
|
330
|
-
voipClient.currentConnectionState === connection_state_1.TelnyxConnectionState.CONNECTING
|
|
331
|
-
|
|
360
|
+
voipClient.currentConnectionState === connection_state_1.TelnyxConnectionState.CONNECTING;
|
|
361
|
+
const isActiveIOSCallWaitingPush =
|
|
362
|
+
react_native_1.Platform.OS === 'ios' &&
|
|
363
|
+
voipClient.currentConnectionState ===
|
|
364
|
+
connection_state_1.TelnyxConnectionState.CONNECTED &&
|
|
365
|
+
voipClient.currentCalls.some(
|
|
366
|
+
(call) =>
|
|
367
|
+
call.currentState === call_state_1.TelnyxCallState.ACTIVE ||
|
|
368
|
+
call.currentState === call_state_1.TelnyxCallState.HELD
|
|
369
|
+
);
|
|
370
|
+
if (isConnectedOrConnecting && !isActiveIOSCallWaitingPush) {
|
|
332
371
|
log(
|
|
333
372
|
`SKIPPING - Already ${voipClient.currentConnectionState}, preventing duplicate processing`
|
|
334
373
|
);
|
|
@@ -336,20 +375,31 @@ const TelnyxVoiceAppComponent = ({
|
|
|
336
375
|
}
|
|
337
376
|
// Set flags to prevent auto-reconnection during push call
|
|
338
377
|
setIsHandlingForegroundCall(true);
|
|
378
|
+
isHandlingForegroundCallRef.current = true;
|
|
339
379
|
backgroundDetectorIgnore.current = true;
|
|
340
380
|
log(`Background detector ignore set to: true at ${new Date().toISOString()}`);
|
|
341
381
|
log(`Foreground call handling flag set to: true at ${new Date().toISOString()}`);
|
|
342
|
-
disposeBackgroundClient();
|
|
382
|
+
await disposeBackgroundClient();
|
|
343
383
|
// On iOS, coordinate with CallKit using the call_id from push metadata
|
|
344
384
|
if (react_native_1.Platform.OS === 'ios') {
|
|
345
385
|
const callId = pushData.metadata?.call_id;
|
|
346
386
|
if (callId) {
|
|
347
387
|
const { callKitCoordinator } = require('./callkit/callkit-coordinator');
|
|
348
388
|
log('Notifying CallKit coordinator about push notification:', callId);
|
|
349
|
-
await callKitCoordinator.handleCallKitPushReceived(callId, {
|
|
389
|
+
const processed = await callKitCoordinator.handleCallKitPushReceived(callId, {
|
|
350
390
|
callData: { source: 'push_notification' },
|
|
351
391
|
pushData: pushData,
|
|
352
392
|
});
|
|
393
|
+
if (!processed) {
|
|
394
|
+
// The push was filtered, rejected, or otherwise ignored by
|
|
395
|
+
// CallKit. Reset the foreground-push lifecycle flags so the
|
|
396
|
+
// app does not stay in a state that skips background
|
|
397
|
+
// disconnect/reconnect handling.
|
|
398
|
+
log('CallKit push was not processed - resetting foreground flags');
|
|
399
|
+
setIsHandlingForegroundCall(false);
|
|
400
|
+
isHandlingForegroundCallRef.current = false;
|
|
401
|
+
backgroundDetectorIgnore.current = false;
|
|
402
|
+
}
|
|
353
403
|
} else {
|
|
354
404
|
log('No call_id found in push data, falling back to direct handling');
|
|
355
405
|
await voipClient.handlePushNotification(pushData);
|
|
@@ -361,26 +411,18 @@ const TelnyxVoiceAppComponent = ({
|
|
|
361
411
|
} catch (e) {
|
|
362
412
|
log('Error processing initial push notification:', e);
|
|
363
413
|
setIsHandlingForegroundCall(false);
|
|
414
|
+
isHandlingForegroundCallRef.current = false;
|
|
364
415
|
} finally {
|
|
365
416
|
setProcessingPushOnLaunch(false);
|
|
417
|
+
processingPushOnLaunchRef.current = false;
|
|
366
418
|
onPushNotificationProcessingCompleted?.();
|
|
367
419
|
}
|
|
368
420
|
},
|
|
369
|
-
[
|
|
370
|
-
processingPushOnLaunch,
|
|
371
|
-
voipClient,
|
|
372
|
-
onPushNotificationProcessingStarted,
|
|
373
|
-
onPushNotificationProcessingCompleted,
|
|
374
|
-
log,
|
|
375
|
-
]
|
|
421
|
+
[voipClient, onPushNotificationProcessingStarted, onPushNotificationProcessingCompleted, log]
|
|
376
422
|
);
|
|
377
423
|
// Dispose background client instance when no longer needed
|
|
378
|
-
const disposeBackgroundClient = (0, react_1.useCallback)(() => {
|
|
379
|
-
|
|
380
|
-
log('Disposing background client instance');
|
|
381
|
-
backgroundClientRef.current.dispose();
|
|
382
|
-
backgroundClientRef.current = null;
|
|
383
|
-
}
|
|
424
|
+
const disposeBackgroundClient = (0, react_1.useCallback)(async () => {
|
|
425
|
+
await disposeSharedBackgroundClient(log);
|
|
384
426
|
}, [log]);
|
|
385
427
|
// Create background client for push notification handling
|
|
386
428
|
const createBackgroundClient = (0, react_1.useCallback)(() => {
|
|
@@ -429,17 +471,18 @@ const TelnyxVoiceAppComponent = ({
|
|
|
429
471
|
}
|
|
430
472
|
}
|
|
431
473
|
log(
|
|
432
|
-
`Flag reset check: WebRTC calls=${calls.length}, CallKit processing=${hasCallKitProcessing}, isHandlingForegroundCall=${
|
|
474
|
+
`Flag reset check: WebRTC calls=${calls.length}, CallKit processing=${hasCallKitProcessing}, isHandlingForegroundCall=${isHandlingForegroundCallRef.current}, backgroundDetectorIgnore=${backgroundDetectorIgnore.current}`
|
|
433
475
|
);
|
|
434
476
|
if (
|
|
435
477
|
!hasActiveWebRTCCalls &&
|
|
436
478
|
!hasCallKitProcessing &&
|
|
437
|
-
(
|
|
479
|
+
(isHandlingForegroundCallRef.current || backgroundDetectorIgnore.current)
|
|
438
480
|
) {
|
|
439
481
|
log(
|
|
440
482
|
`No active calls and no CallKit processing - resetting ignore flags at ${new Date().toISOString()}`
|
|
441
483
|
);
|
|
442
484
|
setIsHandlingForegroundCall(false);
|
|
485
|
+
isHandlingForegroundCallRef.current = false;
|
|
443
486
|
backgroundDetectorIgnore.current = false;
|
|
444
487
|
} else if (!hasActiveWebRTCCalls && hasCallKitProcessing) {
|
|
445
488
|
log(
|
|
@@ -450,9 +493,10 @@ const TelnyxVoiceAppComponent = ({
|
|
|
450
493
|
}
|
|
451
494
|
// Also reset processingPushOnLaunch if no calls are active
|
|
452
495
|
// This ensures the flag doesn't get stuck after call ends
|
|
453
|
-
if (calls.length === 0 &&
|
|
496
|
+
if (calls.length === 0 && processingPushOnLaunchRef.current) {
|
|
454
497
|
log('No active calls - resetting processing push flag');
|
|
455
498
|
setProcessingPushOnLaunch(false);
|
|
499
|
+
processingPushOnLaunchRef.current = false;
|
|
456
500
|
}
|
|
457
501
|
});
|
|
458
502
|
// Listen for immediate call action events from notification buttons (Android only)
|
|
@@ -501,7 +545,7 @@ const TelnyxVoiceAppComponent = ({
|
|
|
501
545
|
// Handle initial push notification if app was launched from terminated state
|
|
502
546
|
// Only check if we're not already processing to prevent infinite loops
|
|
503
547
|
const timeoutId = setTimeout(() => {
|
|
504
|
-
if (!
|
|
548
|
+
if (!processingPushOnLaunchRef.current) {
|
|
505
549
|
checkForInitialPushNotification();
|
|
506
550
|
}
|
|
507
551
|
}, 100);
|
|
@@ -523,16 +567,9 @@ const TelnyxVoiceAppComponent = ({
|
|
|
523
567
|
}
|
|
524
568
|
clearTimeout(timeoutId);
|
|
525
569
|
// Clean up background client instance
|
|
526
|
-
disposeBackgroundClient();
|
|
570
|
+
void disposeBackgroundClient();
|
|
527
571
|
};
|
|
528
|
-
}, [
|
|
529
|
-
voipClient,
|
|
530
|
-
handleAppStateChange,
|
|
531
|
-
disposeBackgroundClient,
|
|
532
|
-
skipWebBackgroundDetection,
|
|
533
|
-
isHandlingForegroundCall,
|
|
534
|
-
log,
|
|
535
|
-
]);
|
|
572
|
+
}, [voipClient, handleAppStateChange, disposeBackgroundClient, skipWebBackgroundDetection, log]);
|
|
536
573
|
// Simply return the children wrapped in context provider - all lifecycle management is handled internally
|
|
537
574
|
return (0, jsx_runtime_1.jsx)(TelnyxVoiceContext_1.TelnyxVoiceProvider, {
|
|
538
575
|
voipClient: voipClient,
|
|
@@ -608,18 +645,23 @@ const initializeAndCreate = async (options) => {
|
|
|
608
645
|
*/
|
|
609
646
|
const handleBackgroundPush = async (message) => {
|
|
610
647
|
console.log('[TelnyxVoiceApp] Background push received:', message);
|
|
648
|
+
let backgroundClient = null;
|
|
611
649
|
try {
|
|
612
650
|
// TODO: Initialize push notification service in isolate if needed
|
|
651
|
+
await disposeSharedBackgroundClient(console.log);
|
|
613
652
|
// Use singleton pattern for background client to prevent multiple instances
|
|
614
|
-
|
|
653
|
+
backgroundClient = (0, telnyx_voip_client_1.createBackgroundTelnyxVoipClient)({
|
|
615
654
|
debug: false,
|
|
616
655
|
});
|
|
656
|
+
sharedBackgroundClient = backgroundClient;
|
|
617
657
|
await backgroundClient.handlePushNotification(message);
|
|
618
658
|
console.log('[TelnyxVoiceApp] Background push processed successfully');
|
|
619
|
-
// Clean up the background client
|
|
620
|
-
backgroundClient.dispose();
|
|
621
659
|
} catch (e) {
|
|
622
660
|
console.log('[TelnyxVoiceApp] Error processing background push:', e);
|
|
661
|
+
} finally {
|
|
662
|
+
if (backgroundClient) {
|
|
663
|
+
await disposeSharedBackgroundClient(console.log, backgroundClient);
|
|
664
|
+
}
|
|
623
665
|
}
|
|
624
666
|
};
|
|
625
667
|
// Create the component with static methods
|
|
@@ -2,6 +2,7 @@ import { Observable } from 'rxjs';
|
|
|
2
2
|
import { TelnyxConnectionState } from './models/connection-state';
|
|
3
3
|
import { Call } from './models/call';
|
|
4
4
|
import { CredentialConfig, TokenConfig } from './models/config';
|
|
5
|
+
import { type CustomHeaders } from './internal/calls/call-state-controller';
|
|
5
6
|
/**
|
|
6
7
|
* Configuration options for TelnyxVoipClient
|
|
7
8
|
*/
|
|
@@ -28,7 +29,9 @@ export declare class TelnyxVoipClient {
|
|
|
28
29
|
private readonly _sessionManager;
|
|
29
30
|
private readonly _callStateController;
|
|
30
31
|
private readonly _options;
|
|
32
|
+
private readonly _pendingCallKitAnswers;
|
|
31
33
|
private _disposed;
|
|
34
|
+
private _disposePromise?;
|
|
32
35
|
/**
|
|
33
36
|
* Check if the app was launched from a push notification.
|
|
34
37
|
*
|
|
@@ -102,6 +105,22 @@ export declare class TelnyxVoipClient {
|
|
|
102
105
|
* ```
|
|
103
106
|
*/
|
|
104
107
|
getCall(callId: string): Call | null;
|
|
108
|
+
/**
|
|
109
|
+
* Explicitly set the active call for multi-call scenarios.
|
|
110
|
+
* @param callId The ID of the call to mark as active
|
|
111
|
+
*/
|
|
112
|
+
setActiveCall(callId: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* Clear the explicitly selected active call and return to default selection.
|
|
115
|
+
*/
|
|
116
|
+
clearActiveCall(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Swap the current active call with a held call.
|
|
119
|
+
* On iOS this is coordinated through CallKit so native and SDK state stay aligned.
|
|
120
|
+
*
|
|
121
|
+
* @param targetCallId ID of the held call to make active
|
|
122
|
+
*/
|
|
123
|
+
swapCalls(targetCallId: string): Promise<void>;
|
|
105
124
|
/**
|
|
106
125
|
* Current session ID (UUID) for this connection.
|
|
107
126
|
*/
|
|
@@ -161,7 +180,7 @@ export declare class TelnyxVoipClient {
|
|
|
161
180
|
destination: string,
|
|
162
181
|
callerName?: string,
|
|
163
182
|
callerNumber?: string,
|
|
164
|
-
customHeaders?:
|
|
183
|
+
customHeaders?: CustomHeaders
|
|
165
184
|
): Promise<Call>;
|
|
166
185
|
/**
|
|
167
186
|
* Handle push notification payload.
|
|
@@ -197,12 +216,21 @@ export declare class TelnyxVoipClient {
|
|
|
197
216
|
* This should be called when the user answers from CallKit before the socket connection is established
|
|
198
217
|
* @param customHeaders Optional custom headers to include with the answer
|
|
199
218
|
*/
|
|
200
|
-
queueAnswerFromCallKit(
|
|
219
|
+
queueAnswerFromCallKit(
|
|
220
|
+
callKitUUIDOrHeaders?: string | Record<string, string>,
|
|
221
|
+
customHeaders?: Record<string, string>
|
|
222
|
+
): void;
|
|
201
223
|
/**
|
|
202
224
|
* Queue an end action for when the call invite arrives (for CallKit integration)
|
|
203
225
|
* This should be called when the user ends from CallKit before the socket connection is established
|
|
204
226
|
*/
|
|
205
|
-
queueEndFromCallKit(): void;
|
|
227
|
+
queueEndFromCallKit(callKitUUID?: string): void;
|
|
228
|
+
/**
|
|
229
|
+
* Associate the next push-delivered INVITE with its app-facing CallKit UUID.
|
|
230
|
+
* The underlying signaling call ID remains unchanged.
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
setPushNotificationCallKitUUID(callKitUUID: string | null): void;
|
|
206
234
|
/**
|
|
207
235
|
* Dispose of the client and clean up all resources.
|
|
208
236
|
*
|
|
@@ -210,7 +238,20 @@ export declare class TelnyxVoipClient {
|
|
|
210
238
|
* This is particularly important for background clients that should be
|
|
211
239
|
* disposed after handling push notifications.
|
|
212
240
|
*/
|
|
213
|
-
dispose(): void
|
|
241
|
+
dispose(): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Forward answers captured during cold start as soon as SessionManager has
|
|
244
|
+
* created the TelnyxRTC instance. SessionManager invokes its ready callback
|
|
245
|
+
* before connect(), so the UUID-keyed action is present when the INVITE
|
|
246
|
+
* arrives.
|
|
247
|
+
*/
|
|
248
|
+
private _flushPendingCallKitAnswers;
|
|
249
|
+
/**
|
|
250
|
+
* Prefer an explicitly supplied token, otherwise hydrate it from PushKit's
|
|
251
|
+
* native storage. PushKit registration starts in AppDelegate before React
|
|
252
|
+
* mounts, so this removes the race between the JS token event and login.
|
|
253
|
+
*/
|
|
254
|
+
private _withNativeVoipPushToken;
|
|
214
255
|
/**
|
|
215
256
|
* Store credential configuration for automatic reconnection
|
|
216
257
|
*/
|
|
@@ -238,7 +279,7 @@ export declare function createTelnyxVoipClient(options?: TelnyxVoipClientOptions
|
|
|
238
279
|
* Disposes the current singleton so that a subsequent call to
|
|
239
280
|
* `createTelnyxVoipClient()` will create a fresh instance.
|
|
240
281
|
*/
|
|
241
|
-
export declare function destroyTelnyxVoipClient(): void
|
|
282
|
+
export declare function destroyTelnyxVoipClient(): Promise<void>;
|
|
242
283
|
/**
|
|
243
284
|
* Create a new TelnyxVoipClient instance for background push notification handling.
|
|
244
285
|
*
|