@telnyx/react-voice-commons-sdk 0.1.3 → 0.1.5

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 (43) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +9 -23
  3. package/lib/callkit/callkit-coordinator.d.ts +114 -110
  4. package/lib/callkit/callkit-coordinator.js +706 -664
  5. package/lib/callkit/callkit.d.ts +41 -41
  6. package/lib/callkit/callkit.js +242 -252
  7. package/lib/callkit/index.js +47 -15
  8. package/lib/callkit/use-callkit.d.ts +19 -19
  9. package/lib/callkit/use-callkit.js +310 -270
  10. package/lib/context/TelnyxVoiceContext.d.ts +9 -9
  11. package/lib/context/TelnyxVoiceContext.js +13 -10
  12. package/lib/hooks/use-callkit-coordinator.d.ts +17 -9
  13. package/lib/hooks/use-callkit-coordinator.js +50 -45
  14. package/lib/hooks/useAppReadyNotifier.js +15 -13
  15. package/lib/hooks/useAppStateHandler.d.ts +11 -6
  16. package/lib/hooks/useAppStateHandler.js +110 -95
  17. package/lib/index.d.ts +21 -3
  18. package/lib/index.js +201 -50
  19. package/lib/internal/CallKitHandler.d.ts +6 -6
  20. package/lib/internal/CallKitHandler.js +104 -96
  21. package/lib/internal/callkit-manager.d.ts +57 -57
  22. package/lib/internal/callkit-manager.js +316 -299
  23. package/lib/internal/calls/call-state-controller.d.ts +78 -73
  24. package/lib/internal/calls/call-state-controller.js +326 -265
  25. package/lib/internal/session/session-manager.d.ts +71 -71
  26. package/lib/internal/session/session-manager.js +437 -360
  27. package/lib/internal/user-defaults-helpers.js +39 -49
  28. package/lib/internal/voice-pn-bridge.d.ts +112 -104
  29. package/lib/internal/voice-pn-bridge.js +193 -203
  30. package/lib/models/call-state.d.ts +46 -46
  31. package/lib/models/call-state.js +74 -70
  32. package/lib/models/call.d.ts +173 -157
  33. package/lib/models/call.js +492 -448
  34. package/lib/models/config.d.ts +18 -11
  35. package/lib/models/config.js +35 -37
  36. package/lib/models/connection-state.d.ts +10 -10
  37. package/lib/models/connection-state.js +16 -16
  38. package/lib/telnyx-voice-app.d.ts +28 -28
  39. package/lib/telnyx-voice-app.js +562 -459
  40. package/lib/telnyx-voip-client.d.ts +174 -167
  41. package/lib/telnyx-voip-client.js +397 -385
  42. package/package.json +9 -5
  43. package/src/telnyx-voice-app.tsx +119 -69
@@ -1,44 +1,63 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
1
+ 'use strict';
2
+ var __createBinding =
3
+ (this && this.__createBinding) ||
4
+ (Object.create
5
+ ? function (o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = {
10
+ enumerable: true,
11
+ get: function () {
12
+ return m[k];
13
+ },
14
+ };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }
18
+ : function (o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ });
22
+ var __setModuleDefault =
23
+ (this && this.__setModuleDefault) ||
24
+ (Object.create
25
+ ? function (o, v) {
26
+ Object.defineProperty(o, 'default', { enumerable: true, value: v });
27
+ }
28
+ : function (o, v) {
29
+ o['default'] = v;
30
+ });
31
+ var __importStar =
32
+ (this && this.__importStar) ||
33
+ (function () {
34
+ var ownKeys = function (o) {
35
+ ownKeys =
36
+ Object.getOwnPropertyNames ||
37
+ function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
24
41
  };
25
- return ownKeys(o);
42
+ return ownKeys(o);
26
43
  };
27
44
  return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null)
48
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++)
49
+ if (k[i] !== 'default') __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
33
52
  };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
53
+ })();
54
+ Object.defineProperty(exports, '__esModule', { value: true });
36
55
  exports.SessionManager = void 0;
37
- const rxjs_1 = require("rxjs");
38
- const operators_1 = require("rxjs/operators");
39
- const TelnyxSDK = __importStar(require("@telnyx/react-native-voice-sdk"));
40
- const connection_state_1 = require("../../models/connection-state");
41
- const config_1 = require("../../models/config");
56
+ const rxjs_1 = require('rxjs');
57
+ const operators_1 = require('rxjs/operators');
58
+ const TelnyxSDK = __importStar(require('@telnyx/react-native-voice-sdk'));
59
+ const connection_state_1 = require('../../models/connection-state');
60
+ const config_1 = require('../../models/config');
42
61
  /**
43
62
  * Manages the connection lifecycle to the Telnyx platform.
44
63
  *
@@ -46,350 +65,408 @@ const config_1 = require("../../models/config");
46
65
  * and automatic reconnection logic.
47
66
  */
48
67
  class SessionManager {
49
- constructor() {
50
- this._connectionState = new rxjs_1.BehaviorSubject(connection_state_1.TelnyxConnectionState.DISCONNECTED);
51
- this._disposed = false;
52
- this._sessionId = this._generateSessionId();
68
+ constructor() {
69
+ this._connectionState = new rxjs_1.BehaviorSubject(
70
+ connection_state_1.TelnyxConnectionState.DISCONNECTED
71
+ );
72
+ this._disposed = false;
73
+ this._sessionId = this._generateSessionId();
74
+ }
75
+ /**
76
+ * Observable stream of connection state changes
77
+ */
78
+ get connectionState$() {
79
+ return this._connectionState.asObservable().pipe((0, operators_1.distinctUntilChanged)());
80
+ }
81
+ /**
82
+ * Set callback to be called when the Telnyx client is ready
83
+ */
84
+ setOnClientReady(callback) {
85
+ this._onClientReady = callback;
86
+ }
87
+ /**
88
+ * Current connection state (synchronous access)
89
+ */
90
+ get currentState() {
91
+ return this._connectionState.value;
92
+ }
93
+ /**
94
+ * Current session ID
95
+ */
96
+ get sessionId() {
97
+ return this._sessionId;
98
+ }
99
+ /**
100
+ * Get the underlying Telnyx client instance
101
+ */
102
+ get telnyxClient() {
103
+ return this._telnyxClient;
104
+ }
105
+ /**
106
+ * Connect using credential authentication
107
+ */
108
+ async connectWithCredential(config) {
109
+ if (this._disposed) {
110
+ throw new Error('SessionManager has been disposed');
53
111
  }
54
- /**
55
- * Observable stream of connection state changes
56
- */
57
- get connectionState$() {
58
- return this._connectionState.asObservable().pipe((0, operators_1.distinctUntilChanged)());
112
+ this._currentConfig = config;
113
+ await this._connect();
114
+ }
115
+ /**
116
+ * Connect using token authentication
117
+ */
118
+ async connectWithToken(config) {
119
+ if (this._disposed) {
120
+ throw new Error('SessionManager has been disposed');
59
121
  }
60
- /**
61
- * Set callback to be called when the Telnyx client is ready
62
- */
63
- setOnClientReady(callback) {
64
- this._onClientReady = callback;
122
+ this._currentConfig = config;
123
+ await this._connect();
124
+ }
125
+ /**
126
+ * Disconnect from the Telnyx platform
127
+ */
128
+ async disconnect() {
129
+ if (this._disposed) {
130
+ return;
65
131
  }
66
- /**
67
- * Current connection state (synchronous access)
68
- */
69
- get currentState() {
70
- return this._connectionState.value;
132
+ this._currentConfig = undefined;
133
+ if (this._telnyxClient) {
134
+ try {
135
+ await this._telnyxClient.disconnect();
136
+ } catch (error) {
137
+ console.error('Error during disconnect:', error);
138
+ }
71
139
  }
72
- /**
73
- * Current session ID
74
- */
75
- get sessionId() {
76
- return this._sessionId;
140
+ this._connectionState.next(connection_state_1.TelnyxConnectionState.DISCONNECTED);
141
+ }
142
+ /**
143
+ * Disable push notifications for the current session
144
+ */
145
+ disablePushNotifications() {
146
+ if (
147
+ this._telnyxClient &&
148
+ this.currentState === connection_state_1.TelnyxConnectionState.CONNECTED
149
+ ) {
150
+ // Implementation depends on the actual Telnyx SDK API
151
+ // This is a placeholder for the actual implementation
152
+ console.log('Disabling push notifications for session:', this._sessionId);
77
153
  }
78
- /**
79
- * Get the underlying Telnyx client instance
80
- */
81
- get telnyxClient() {
82
- return this._telnyxClient;
154
+ }
155
+ /**
156
+ * Handle push notification with stored config
157
+ */
158
+ handlePushNotificationWithConfig(pushMetaData, config) {
159
+ if (this._disposed) {
160
+ return;
83
161
  }
84
- /**
85
- * Connect using credential authentication
86
- */
87
- async connectWithCredential(config) {
88
- if (this._disposed) {
89
- throw new Error('SessionManager has been disposed');
90
- }
91
- this._currentConfig = config;
92
- await this._connect();
162
+ this._currentConfig = config;
163
+ // Implementation for handling push notifications
164
+ // This would integrate with the actual Telnyx SDK push handling
165
+ console.log('Handling push notification with config:', { pushMetaData, config: config.type });
166
+ }
167
+ /**
168
+ * Handle push notification (async version)
169
+ */
170
+ async handlePushNotification(payload) {
171
+ if (this._disposed) {
172
+ return;
93
173
  }
94
- /**
95
- * Connect using token authentication
96
- */
97
- async connectWithToken(config) {
98
- if (this._disposed) {
99
- throw new Error('SessionManager has been disposed');
174
+ console.log(
175
+ 'SessionManager: RELEASE DEBUG - Processing push notification, payload:',
176
+ JSON.stringify(payload)
177
+ );
178
+ // Store the push notification payload for when the client is created
179
+ this._pendingPushPayload = payload;
180
+ // If we don't have a config yet but we're processing a push notification,
181
+ // attempt to load stored config first (for terminated app startup)
182
+ if (!this._currentConfig && !this._telnyxClient) {
183
+ console.log(
184
+ 'SessionManager: RELEASE DEBUG - No config available, attempting to load from stored config for push notification'
185
+ );
186
+ try {
187
+ // Try to retrieve stored credentials and token from AsyncStorage
188
+ const AsyncStorage = require('@react-native-async-storage/async-storage').default;
189
+ const storedUsername = await AsyncStorage.getItem('@telnyx_username');
190
+ const storedPassword = await AsyncStorage.getItem('@telnyx_password');
191
+ const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
192
+ const storedPushToken = await AsyncStorage.getItem('@push_token');
193
+ // Check if we have credential-based authentication data
194
+ if (storedUsername && storedPassword) {
195
+ console.log('SessionManager: RELEASE DEBUG - Found stored credentials, creating config');
196
+ const { createCredentialConfig } = require('../../models/config');
197
+ this._currentConfig = createCredentialConfig(storedUsername, storedPassword, {
198
+ pushNotificationDeviceToken: storedPushToken,
199
+ });
100
200
  }
101
- this._currentConfig = config;
102
- await this._connect();
103
- }
104
- /**
105
- * Disconnect from the Telnyx platform
106
- */
107
- async disconnect() {
108
- if (this._disposed) {
109
- return;
201
+ // Check if we have token-based authentication data
202
+ else if (storedCredentialToken) {
203
+ console.log('SessionManager: RELEASE DEBUG - Found stored token, creating config');
204
+ const { createTokenConfig } = require('../../models/config');
205
+ this._currentConfig = createTokenConfig(storedCredentialToken, {
206
+ pushNotificationDeviceToken: storedPushToken,
207
+ });
110
208
  }
111
- this._currentConfig = undefined;
112
- if (this._telnyxClient) {
113
- try {
114
- await this._telnyxClient.disconnect();
115
- }
116
- catch (error) {
117
- console.error('Error during disconnect:', error);
118
- }
209
+ if (this._currentConfig) {
210
+ console.log(
211
+ 'SessionManager: RELEASE DEBUG - Successfully loaded stored config for push notification'
212
+ );
213
+ } else {
214
+ console.log('SessionManager: RELEASE DEBUG - No stored authentication data found');
119
215
  }
120
- this._connectionState.next(connection_state_1.TelnyxConnectionState.DISCONNECTED);
216
+ } catch (error) {
217
+ console.warn('SessionManager: Failed to load stored config for push notification:', error);
218
+ }
121
219
  }
122
- /**
123
- * Disable push notifications for the current session
124
- */
125
- disablePushNotifications() {
126
- if (this._telnyxClient && this.currentState === connection_state_1.TelnyxConnectionState.CONNECTED) {
127
- // Implementation depends on the actual Telnyx SDK API
128
- // This is a placeholder for the actual implementation
129
- console.log('Disabling push notifications for session:', this._sessionId);
220
+ // If we already have a client, process the push notification immediately
221
+ if (this._telnyxClient) {
222
+ console.log(
223
+ 'SessionManager: RELEASE DEBUG - Client available, processing push notification immediately'
224
+ );
225
+ // Use type assertion to access the processVoIPNotification method
226
+ // This method sets the isCallFromPush flag which is needed for proper push handling
227
+ if (typeof this._telnyxClient.processVoIPNotification === 'function') {
228
+ console.log(
229
+ 'SessionManager: RELEASE DEBUG - Calling processVoIPNotification with payload:',
230
+ JSON.stringify(payload)
231
+ );
232
+ // Extract the actual push notification metadata that the client expects
233
+ const actualPayload = this._extractPushPayload(payload);
234
+ this._telnyxClient.processVoIPNotification(actualPayload);
235
+ console.log('SessionManager: RELEASE DEBUG - Called processVoIPNotification successfully');
236
+ } else {
237
+ console.warn(
238
+ 'SessionManager: processVoIPNotification method not available on TelnyxRTC client'
239
+ );
240
+ }
241
+ // Clear the pending payload since it was processed
242
+ this._pendingPushPayload = null;
243
+ } else {
244
+ console.log(
245
+ 'SessionManager: RELEASE DEBUG - No client available, checking if we can trigger immediate connection'
246
+ );
247
+ // If we have config (either existing or newly loaded from storage) and are disconnected, trigger immediate connection
248
+ // The _connect() method will process the pending push payload BEFORE calling connect()
249
+ if (
250
+ this._currentConfig &&
251
+ this.currentState === connection_state_1.TelnyxConnectionState.DISCONNECTED
252
+ ) {
253
+ console.log(
254
+ 'SessionManager: RELEASE DEBUG - Triggering immediate connection for push notification with config type:',
255
+ this._currentConfig.type || 'credential'
256
+ );
257
+ try {
258
+ await this._connect();
259
+ console.log(
260
+ 'SessionManager: RELEASE DEBUG - Successfully connected after push notification trigger'
261
+ );
262
+ } catch (error) {
263
+ console.error(
264
+ 'SessionManager: Failed to connect after push notification trigger:',
265
+ error
266
+ );
130
267
  }
268
+ } else {
269
+ console.log(
270
+ 'SessionManager: RELEASE DEBUG - Cannot trigger connection, config available:',
271
+ !!this._currentConfig,
272
+ 'current state:',
273
+ this.currentState
274
+ );
275
+ console.log(
276
+ 'SessionManager: RELEASE DEBUG - Push payload stored for later processing when client becomes available'
277
+ );
278
+ }
131
279
  }
132
- /**
133
- * Handle push notification with stored config
134
- */
135
- handlePushNotificationWithConfig(pushMetaData, config) {
136
- if (this._disposed) {
137
- return;
138
- }
139
- this._currentConfig = config;
140
- // Implementation for handling push notifications
141
- // This would integrate with the actual Telnyx SDK push handling
142
- console.log('Handling push notification with config:', { pushMetaData, config: config.type });
280
+ console.log('SessionManager: RELEASE DEBUG - Push notification handling complete');
281
+ }
282
+ /**
283
+ * Dispose of the session manager and clean up resources
284
+ */
285
+ dispose() {
286
+ if (this._disposed) {
287
+ return;
143
288
  }
144
- /**
145
- * Handle push notification (async version)
146
- */
147
- async handlePushNotification(payload) {
148
- if (this._disposed) {
149
- return;
150
- }
151
- console.log('SessionManager: RELEASE DEBUG - Processing push notification, payload:', JSON.stringify(payload));
152
- // Store the push notification payload for when the client is created
153
- this._pendingPushPayload = payload;
154
- // If we don't have a config yet but we're processing a push notification,
155
- // attempt to load stored config first (for terminated app startup)
156
- if (!this._currentConfig && !this._telnyxClient) {
157
- console.log('SessionManager: RELEASE DEBUG - No config available, attempting to load from stored config for push notification');
158
- try {
159
- // Try to retrieve stored credentials and token from AsyncStorage
160
- const AsyncStorage = require('@react-native-async-storage/async-storage').default;
161
- const storedUsername = await AsyncStorage.getItem('@telnyx_username');
162
- const storedPassword = await AsyncStorage.getItem('@telnyx_password');
163
- const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
164
- const storedPushToken = await AsyncStorage.getItem('@push_token');
165
- // Check if we have credential-based authentication data
166
- if (storedUsername && storedPassword) {
167
- console.log('SessionManager: RELEASE DEBUG - Found stored credentials, creating config');
168
- const { createCredentialConfig } = require('../../models/config');
169
- this._currentConfig = createCredentialConfig(storedUsername, storedPassword, {
170
- pushNotificationDeviceToken: storedPushToken,
171
- });
172
- }
173
- // Check if we have token-based authentication data
174
- else if (storedCredentialToken) {
175
- console.log('SessionManager: RELEASE DEBUG - Found stored token, creating config');
176
- const { createTokenConfig } = require('../../models/config');
177
- this._currentConfig = createTokenConfig(storedCredentialToken, {
178
- pushNotificationDeviceToken: storedPushToken,
179
- });
180
- }
181
- if (this._currentConfig) {
182
- console.log('SessionManager: RELEASE DEBUG - Successfully loaded stored config for push notification');
183
- }
184
- else {
185
- console.log('SessionManager: RELEASE DEBUG - No stored authentication data found');
186
- }
187
- }
188
- catch (error) {
189
- console.warn('SessionManager: Failed to load stored config for push notification:', error);
190
- }
191
- }
192
- // If we already have a client, process the push notification immediately
193
- if (this._telnyxClient) {
194
- console.log('SessionManager: RELEASE DEBUG - Client available, processing push notification immediately');
195
- // Use type assertion to access the processVoIPNotification method
196
- // This method sets the isCallFromPush flag which is needed for proper push handling
197
- if (typeof this._telnyxClient.processVoIPNotification === 'function') {
198
- console.log('SessionManager: RELEASE DEBUG - Calling processVoIPNotification with payload:', JSON.stringify(payload));
199
- // Extract the actual push notification metadata that the client expects
200
- const actualPayload = this._extractPushPayload(payload);
201
- this._telnyxClient.processVoIPNotification(actualPayload);
202
- console.log('SessionManager: RELEASE DEBUG - Called processVoIPNotification successfully');
203
- }
204
- else {
205
- console.warn('SessionManager: processVoIPNotification method not available on TelnyxRTC client');
206
- }
207
- // Clear the pending payload since it was processed
208
- this._pendingPushPayload = null;
209
- }
210
- else {
211
- console.log('SessionManager: RELEASE DEBUG - No client available, checking if we can trigger immediate connection');
212
- // If we have config (either existing or newly loaded from storage) and are disconnected, trigger immediate connection
213
- // The _connect() method will process the pending push payload BEFORE calling connect()
214
- if (this._currentConfig && this.currentState === connection_state_1.TelnyxConnectionState.DISCONNECTED) {
215
- console.log('SessionManager: RELEASE DEBUG - Triggering immediate connection for push notification with config type:', this._currentConfig.type || 'credential');
216
- try {
217
- await this._connect();
218
- console.log('SessionManager: RELEASE DEBUG - Successfully connected after push notification trigger');
219
- }
220
- catch (error) {
221
- console.error('SessionManager: Failed to connect after push notification trigger:', error);
222
- }
223
- }
224
- else {
225
- console.log('SessionManager: RELEASE DEBUG - Cannot trigger connection, config available:', !!this._currentConfig, 'current state:', this.currentState);
226
- console.log('SessionManager: RELEASE DEBUG - Push payload stored for later processing when client becomes available');
227
- }
228
- }
229
- console.log('SessionManager: RELEASE DEBUG - Push notification handling complete');
289
+ this._disposed = true;
290
+ this.disconnect();
291
+ this._connectionState.complete();
292
+ }
293
+ /**
294
+ * Internal method to establish connection with or without push notification handling
295
+ */
296
+ async _connect() {
297
+ if (!this._currentConfig) {
298
+ throw new Error('No configuration provided');
230
299
  }
231
- /**
232
- * Dispose of the session manager and clean up resources
233
- */
234
- dispose() {
235
- if (this._disposed) {
236
- return;
237
- }
238
- this._disposed = true;
239
- this.disconnect();
240
- this._connectionState.complete();
241
- }
242
- /**
243
- * Internal method to establish connection with or without push notification handling
244
- */
245
- async _connect() {
246
- if (!this._currentConfig) {
247
- throw new Error('No configuration provided');
248
- }
249
- this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTING);
250
- try {
251
- // Clean up existing client
252
- if (this._telnyxClient) {
253
- await this._telnyxClient.disconnect();
254
- }
255
- // Create new client instance with authentication options
256
- let clientOptions;
257
- if ((0, config_1.isCredentialConfig)(this._currentConfig)) {
258
- clientOptions = {
259
- login: this._currentConfig.sipUser,
260
- password: this._currentConfig.sipPassword,
261
- logLevel: this._currentConfig.debug ? 'debug' : 'warn',
262
- pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
263
- };
264
- console.log('🔧 SessionManager: Creating TelnyxRTC with credential config, logLevel:', clientOptions.logLevel, 'pushToken:', !!this._currentConfig.pushNotificationDeviceToken);
265
- }
266
- else if ((0, config_1.isTokenConfig)(this._currentConfig)) {
267
- clientOptions = {
268
- login_token: this._currentConfig.token,
269
- logLevel: this._currentConfig.debug ? 'debug' : 'warn',
270
- pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
271
- };
272
- console.log('🔧 SessionManager: Creating TelnyxRTC with token config, logLevel:', clientOptions.logLevel, 'pushToken:', !!this._currentConfig.pushNotificationDeviceToken);
273
- }
274
- else {
275
- throw new Error('Invalid configuration type');
276
- }
277
- this._telnyxClient = new TelnyxSDK.TelnyxRTC(clientOptions);
278
- // CRITICAL: Process any pending push notification payload BEFORE connecting
279
- // This ensures voice_sdk_id and other payload variables are set before connect() is called
280
- const pendingPushPayload = this._pendingPushPayload;
281
- if (pendingPushPayload) {
282
- console.log('SessionManager: RELEASE DEBUG - Processing pending push notification BEFORE connect:', JSON.stringify(pendingPushPayload));
283
- if (typeof this._telnyxClient.processVoIPNotification === 'function') {
284
- console.log('SessionManager: RELEASE DEBUG - Calling processVoIPNotification BEFORE connect to set voice_sdk_id');
285
- // Extract the actual push notification metadata that the client expects
286
- const actualPayload = this._extractPushPayload(pendingPushPayload);
287
- this._telnyxClient.processVoIPNotification(actualPayload);
288
- console.log('SessionManager: RELEASE DEBUG - Successfully processed pending push notification before connect');
289
- }
290
- else {
291
- console.warn('SessionManager: processVoIPNotification method not available on new client');
292
- }
293
- // Clear the pending payload
294
- this._pendingPushPayload = null;
295
- }
296
- this._setupClientListeners();
297
- // Set up CallStateController listeners immediately after client creation
298
- // This ensures they're ready before any incoming call events are emitted
299
- console.log('🔧 SessionManager: Setting up CallStateController listeners before connection...');
300
- console.log('🔧 SessionManager: _onClientReady callback exists:', !!this._onClientReady);
301
- if (this._onClientReady) {
302
- console.log('🔧 SessionManager: Calling _onClientReady callback now...');
303
- this._onClientReady();
304
- console.log('🔧 SessionManager: _onClientReady callback completed');
305
- }
306
- else {
307
- console.log('🔧 SessionManager: No _onClientReady callback found');
308
- }
309
- // Connect to the platform AFTER processing push notification
310
- console.log('SessionManager: RELEASE DEBUG - About to call connect() after processing push notification');
311
- await this._telnyxClient.connect();
312
- // Notify that client is ready for event listeners
313
- console.log('🔧 SessionManager: Client connected successfully');
314
- }
315
- catch (error) {
316
- console.error('Connection failed:', error);
317
- this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
318
- throw error;
300
+ this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTING);
301
+ try {
302
+ // Clean up existing client
303
+ if (this._telnyxClient) {
304
+ await this._telnyxClient.disconnect();
305
+ }
306
+ // Create new client instance with authentication options
307
+ let clientOptions;
308
+ if ((0, config_1.isCredentialConfig)(this._currentConfig)) {
309
+ clientOptions = {
310
+ login: this._currentConfig.sipUser,
311
+ password: this._currentConfig.sipPassword,
312
+ logLevel: this._currentConfig.debug ? 'debug' : 'warn',
313
+ pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
314
+ };
315
+ console.log(
316
+ '🔧 SessionManager: Creating TelnyxRTC with credential config, logLevel:',
317
+ clientOptions.logLevel,
318
+ 'pushToken:',
319
+ !!this._currentConfig.pushNotificationDeviceToken
320
+ );
321
+ } else if ((0, config_1.isTokenConfig)(this._currentConfig)) {
322
+ clientOptions = {
323
+ login_token: this._currentConfig.token,
324
+ logLevel: this._currentConfig.debug ? 'debug' : 'warn',
325
+ pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
326
+ };
327
+ console.log(
328
+ '🔧 SessionManager: Creating TelnyxRTC with token config, logLevel:',
329
+ clientOptions.logLevel,
330
+ 'pushToken:',
331
+ !!this._currentConfig.pushNotificationDeviceToken
332
+ );
333
+ } else {
334
+ throw new Error('Invalid configuration type');
335
+ }
336
+ this._telnyxClient = new TelnyxSDK.TelnyxRTC(clientOptions);
337
+ // CRITICAL: Process any pending push notification payload BEFORE connecting
338
+ // This ensures voice_sdk_id and other payload variables are set before connect() is called
339
+ const pendingPushPayload = this._pendingPushPayload;
340
+ if (pendingPushPayload) {
341
+ console.log(
342
+ 'SessionManager: RELEASE DEBUG - Processing pending push notification BEFORE connect:',
343
+ JSON.stringify(pendingPushPayload)
344
+ );
345
+ if (typeof this._telnyxClient.processVoIPNotification === 'function') {
346
+ console.log(
347
+ 'SessionManager: RELEASE DEBUG - Calling processVoIPNotification BEFORE connect to set voice_sdk_id'
348
+ );
349
+ // Extract the actual push notification metadata that the client expects
350
+ const actualPayload = this._extractPushPayload(pendingPushPayload);
351
+ this._telnyxClient.processVoIPNotification(actualPayload);
352
+ console.log(
353
+ 'SessionManager: RELEASE DEBUG - Successfully processed pending push notification before connect'
354
+ );
355
+ } else {
356
+ console.warn(
357
+ 'SessionManager: processVoIPNotification method not available on new client'
358
+ );
319
359
  }
360
+ // Clear the pending payload
361
+ this._pendingPushPayload = null;
362
+ }
363
+ this._setupClientListeners();
364
+ // Set up CallStateController listeners immediately after client creation
365
+ // This ensures they're ready before any incoming call events are emitted
366
+ console.log(
367
+ '🔧 SessionManager: Setting up CallStateController listeners before connection...'
368
+ );
369
+ console.log('🔧 SessionManager: _onClientReady callback exists:', !!this._onClientReady);
370
+ if (this._onClientReady) {
371
+ console.log('🔧 SessionManager: Calling _onClientReady callback now...');
372
+ this._onClientReady();
373
+ console.log('🔧 SessionManager: _onClientReady callback completed');
374
+ } else {
375
+ console.log('🔧 SessionManager: No _onClientReady callback found');
376
+ }
377
+ // Connect to the platform AFTER processing push notification
378
+ console.log(
379
+ 'SessionManager: RELEASE DEBUG - About to call connect() after processing push notification'
380
+ );
381
+ await this._telnyxClient.connect();
382
+ // Notify that client is ready for event listeners
383
+ console.log('🔧 SessionManager: Client connected successfully');
384
+ } catch (error) {
385
+ console.error('Connection failed:', error);
386
+ this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
387
+ throw error;
320
388
  }
321
- /**
322
- * Set up event listeners for the Telnyx client
323
- */
324
- _setupClientListeners() {
325
- if (!this._telnyxClient) {
326
- return;
327
- }
328
- this._telnyxClient.on('telnyx.client.ready', () => {
329
- console.log('Telnyx client ready');
330
- this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTED);
331
- // Ensure CallStateController listeners are set up when client becomes ready
332
- // This handles both initial connection and automatic reconnection
333
- console.log('🔧 SessionManager: Client ready event - reinitializing CallStateController listeners');
334
- if (this._onClientReady) {
335
- console.log('🔧 SessionManager: Calling _onClientReady callback from client ready event...');
336
- this._onClientReady();
337
- console.log('🔧 SessionManager: _onClientReady callback completed from client ready event');
338
- }
339
- else {
340
- console.log('🔧 SessionManager: No _onClientReady callback found in client ready event');
341
- }
342
- });
343
- this._telnyxClient.on('telnyx.client.error', (error) => {
344
- console.error('Telnyx client error:', error);
345
- this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
346
- });
347
- // Note: Socket-level events are not exposed in the current SDK
348
- // We'll rely on the client-level events for now
389
+ }
390
+ /**
391
+ * Set up event listeners for the Telnyx client
392
+ */
393
+ _setupClientListeners() {
394
+ if (!this._telnyxClient) {
395
+ return;
349
396
  }
350
- /**
351
- * Extract the actual payload metadata from wrapped push notification payload
352
- */
353
- _extractPushPayload(payload) {
354
- // The payload might be wrapped, so we need to extract the core metadata
355
- let actualPayload = payload;
356
- if (payload.metadata && typeof payload.metadata === 'object') {
357
- // If there's a metadata wrapper, use that but preserve wrapper-level flags
358
- actualPayload = payload.metadata;
359
- // Preserve important flags from the wrapper level
360
- if (payload.from_notification !== undefined) {
361
- actualPayload.from_notification = payload.from_notification;
362
- }
363
- if (payload.action !== undefined) {
364
- actualPayload.action = payload.action;
365
- }
366
- console.log('SessionManager: RELEASE DEBUG - Using metadata portion of payload with preserved flags:', JSON.stringify(actualPayload));
397
+ this._telnyxClient.on('telnyx.client.ready', () => {
398
+ console.log('Telnyx client ready');
399
+ this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTED);
400
+ // Ensure CallStateController listeners are set up when client becomes ready
401
+ // This handles both initial connection and automatic reconnection
402
+ console.log(
403
+ '🔧 SessionManager: Client ready event - reinitializing CallStateController listeners'
404
+ );
405
+ if (this._onClientReady) {
406
+ console.log(
407
+ '🔧 SessionManager: Calling _onClientReady callback from client ready event...'
408
+ );
409
+ this._onClientReady();
410
+ console.log('🔧 SessionManager: _onClientReady callback completed from client ready event');
411
+ } else {
412
+ console.log('🔧 SessionManager: No _onClientReady callback found in client ready event');
413
+ }
414
+ });
415
+ this._telnyxClient.on('telnyx.client.error', (error) => {
416
+ console.error('Telnyx client error:', error);
417
+ this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
418
+ });
419
+ // Note: Socket-level events are not exposed in the current SDK
420
+ // We'll rely on the client-level events for now
421
+ }
422
+ /**
423
+ * Extract the actual payload metadata from wrapped push notification payload
424
+ */
425
+ _extractPushPayload(payload) {
426
+ // The payload might be wrapped, so we need to extract the core metadata
427
+ let actualPayload = payload;
428
+ if (payload.metadata && typeof payload.metadata === 'object') {
429
+ // If there's a metadata wrapper, use that but preserve wrapper-level flags
430
+ actualPayload = payload.metadata;
431
+ // Preserve important flags from the wrapper level
432
+ if (payload.from_notification !== undefined) {
433
+ actualPayload.from_notification = payload.from_notification;
434
+ }
435
+ if (payload.action !== undefined) {
436
+ actualPayload.action = payload.action;
437
+ }
438
+ console.log(
439
+ 'SessionManager: RELEASE DEBUG - Using metadata portion of payload with preserved flags:',
440
+ JSON.stringify(actualPayload)
441
+ );
442
+ } else if (payload.action === 'incoming_call' && payload.metadata) {
443
+ // Handle the case where metadata is a string that needs parsing
444
+ try {
445
+ const parsedMetadata =
446
+ typeof payload.metadata === 'string' ? JSON.parse(payload.metadata) : payload.metadata;
447
+ actualPayload = parsedMetadata;
448
+ // Preserve important flags from the wrapper level
449
+ if (payload.from_notification !== undefined) {
450
+ actualPayload.from_notification = payload.from_notification;
367
451
  }
368
- else if (payload.action === 'incoming_call' && payload.metadata) {
369
- // Handle the case where metadata is a string that needs parsing
370
- try {
371
- const parsedMetadata = typeof payload.metadata === 'string' ? JSON.parse(payload.metadata) : payload.metadata;
372
- actualPayload = parsedMetadata;
373
- // Preserve important flags from the wrapper level
374
- if (payload.from_notification !== undefined) {
375
- actualPayload.from_notification = payload.from_notification;
376
- }
377
- if (payload.action !== undefined) {
378
- actualPayload.action = payload.action;
379
- }
380
- console.log('SessionManager: RELEASE DEBUG - Using parsed metadata with preserved flags:', JSON.stringify(actualPayload));
381
- }
382
- catch (error) {
383
- console.warn('SessionManager: Failed to parse metadata:', error);
384
- }
452
+ if (payload.action !== undefined) {
453
+ actualPayload.action = payload.action;
385
454
  }
386
- return actualPayload;
387
- }
388
- /**
389
- * Generate a unique session ID
390
- */
391
- _generateSessionId() {
392
- return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
455
+ console.log(
456
+ 'SessionManager: RELEASE DEBUG - Using parsed metadata with preserved flags:',
457
+ JSON.stringify(actualPayload)
458
+ );
459
+ } catch (error) {
460
+ console.warn('SessionManager: Failed to parse metadata:', error);
461
+ }
393
462
  }
463
+ return actualPayload;
464
+ }
465
+ /**
466
+ * Generate a unique session ID
467
+ */
468
+ _generateSessionId() {
469
+ return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
470
+ }
394
471
  }
395
472
  exports.SessionManager = SessionManager;