@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telnyx/react-voice-commons-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "A high-level, state-agnostic, drop-in module for the Telnyx React Native SDK that simplifies WebRTC voice calling integration",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.js",
@@ -34,7 +34,11 @@
34
34
  "docs:markdown": "typedoc --options typedoc.markdown.json",
35
35
  "docs:all": "npm run docs && npm run docs:markdown",
36
36
  "android": "expo run:android",
37
- "ios": "expo run:ios"
37
+ "ios": "expo run:ios",
38
+ "dev:local": "npm pkg set dependencies.@telnyx/react-native-voice-sdk=file:../package",
39
+ "dev:published": "npm pkg set dependencies.@telnyx/react-native-voice-sdk=^0.3.0",
40
+ "prepublishOnly": "npm run dev:published && npm install --legacy-peer-deps",
41
+ "postpublish": "npm run dev:local && npm install --legacy-peer-deps"
38
42
  },
39
43
  "keywords": [
40
44
  "react-native",
@@ -60,8 +64,8 @@
60
64
  "peerDependencies": {
61
65
  "@react-native-async-storage/async-storage": "^2.1.0",
62
66
  "expo-router": "^5.1.0",
63
- "react": "19.0.0",
64
- "react-native": "^0.79.0",
67
+ "react": ">=19.0.0 <20.0.0",
68
+ "react-native": ">=0.79.0 <1.0.0",
65
69
  "react-native-webrtc": "^124.0.5"
66
70
  },
67
71
  "peerDependenciesMeta": {
@@ -83,7 +87,7 @@
83
87
  },
84
88
  "dependencies": {
85
89
  "@react-native-community/eslint-config": "^3.2.0",
86
- "@telnyx/react-native-voice-sdk": "^0.1.2",
90
+ "@telnyx/react-native-voice-sdk": "^0.3.0",
87
91
  "eventemitter3": "^5.0.1",
88
92
  "expo": "~53.0.22",
89
93
  "react-native-voip-push-notification": "^3.3.3",
@@ -289,84 +289,134 @@ const TelnyxVoiceAppComponent: React.FC<TelnyxVoiceAppProps> = ({
289
289
  try {
290
290
  let pushData: Record<string, any> | null = null;
291
291
 
292
- // Try to get push data from the native layer using our VoicePnBridge
293
- try {
294
- // Import the native bridge module dynamically
295
- const { NativeModules } = require('react-native');
296
- const VoicePnBridge = NativeModules.VoicePnBridge;
297
-
298
- if (VoicePnBridge) {
299
- log('Checking for pending push actions via VoicePnBridge');
300
-
301
- // First check for pending call actions (notification button taps like hangup/answer)
302
- const pendingCallAction = await VoicePnBridge.getPendingCallAction();
303
- log('Raw pending call action response:', pendingCallAction);
304
-
305
- if (pendingCallAction && pendingCallAction.action != null) {
306
- log('Found pending call action:', pendingCallAction);
307
-
308
- // Handle call actions directly
309
- if (pendingCallAction.action === 'hangup' && pendingCallAction.callId) {
310
- log(
311
- 'Processing hangup action from notification for call:',
312
- pendingCallAction.callId
313
- );
314
-
315
- // Find and hangup the call
316
- const activeCall = voipClient.currentActiveCall;
317
- if (activeCall && activeCall.callId === pendingCallAction.callId) {
318
- log('Hanging up active call from notification action');
319
- try {
320
- await activeCall.hangup();
321
- log('Call hung up successfully from notification action');
322
- } catch (error) {
323
- log('Error hanging up call from notification action:', error);
292
+ // Try to get push data from the native layer using platform-specific methods
293
+ if (Platform.OS === 'android') {
294
+ try {
295
+ // Import the native bridge module dynamically
296
+ const { NativeModules } = require('react-native');
297
+ const VoicePnBridge = NativeModules.VoicePnBridge;
298
+
299
+ if (VoicePnBridge) {
300
+ log('Checking for pending push actions via VoicePnBridge');
301
+
302
+ // First check for pending call actions (notification button taps like hangup/answer)
303
+ const pendingCallAction = await VoicePnBridge.getPendingCallAction();
304
+ log('Raw pending call action response:', pendingCallAction);
305
+
306
+ if (pendingCallAction && pendingCallAction.action != null) {
307
+ log('Found pending call action:', pendingCallAction);
308
+
309
+ // Handle call actions directly
310
+ if (pendingCallAction.action === 'hangup' && pendingCallAction.callId) {
311
+ log(
312
+ 'Processing hangup action from notification for call:',
313
+ pendingCallAction.callId
314
+ );
315
+
316
+ // Find and hangup the call
317
+ const activeCall = voipClient.currentActiveCall;
318
+ if (activeCall && activeCall.callId === pendingCallAction.callId) {
319
+ log('Hanging up active call from notification action');
320
+ try {
321
+ await activeCall.hangup();
322
+ log('Call hung up successfully from notification action');
323
+ } catch (error) {
324
+ log('Error hanging up call from notification action:', error);
325
+ }
326
+ } else {
327
+ log('No matching active call found for hangup action');
324
328
  }
325
- } else {
326
- log('No matching active call found for hangup action');
329
+
330
+ // Clear the pending action
331
+ await VoicePnBridge.clearPendingCallAction();
332
+ return; // Don't process as push data
327
333
  }
334
+ }
328
335
 
329
- // Clear the pending action
330
- await VoicePnBridge.clearPendingCallAction();
331
- return; // Don't process as push data
336
+ // Then check for regular push notification data
337
+ const pendingAction = await VoicePnBridge.getPendingPushAction();
338
+ log('Raw pending action response:', pendingAction);
339
+
340
+ if (pendingAction && pendingAction.action != null && pendingAction.metadata != null) {
341
+ log('Found pending push action:', pendingAction);
342
+
343
+ // Parse the metadata if it's a string
344
+ let metadata = pendingAction.metadata;
345
+ try {
346
+ // First try parsing as JSON
347
+ metadata = JSON.parse(metadata);
348
+ log('Parsed metadata as JSON:', metadata);
349
+ } catch (e) {
350
+ log('JSON parse failed, trying Android key-value format');
351
+ }
352
+
353
+ // Create push data structure that matches what the VoIP client expects
354
+ pushData = {
355
+ action: pendingAction.action,
356
+ metadata: metadata,
357
+ from_notification: true,
358
+ };
359
+
360
+ // Clear the pending action so it doesn't get processed again
361
+ await VoicePnBridge.clearPendingPushAction();
362
+ log('Cleared pending push action after retrieval');
363
+ } else {
364
+ log('No pending push actions found');
332
365
  }
366
+ } else {
367
+ log('VoicePnBridge not available on Android');
333
368
  }
334
-
335
- // Then check for regular push notification data
336
- const pendingAction = await VoicePnBridge.getPendingPushAction();
337
- log('Raw pending action response:', pendingAction);
338
-
339
- if (pendingAction && pendingAction.action != null && pendingAction.metadata != null) {
340
- log('Found pending push action:', pendingAction);
341
-
342
- // Parse the metadata if it's a string
343
- let metadata = pendingAction.metadata;
344
- try {
345
- // First try parsing as JSON
346
- metadata = JSON.parse(metadata);
347
- log('Parsed metadata as JSON:', metadata);
348
- } catch (e) {
349
- log('JSON parse failed, trying Android key-value format');
369
+ } catch (bridgeError) {
370
+ log('Error accessing VoicePnBridge on Android:', bridgeError);
371
+ }
372
+ } else if (Platform.OS === 'ios') {
373
+ try {
374
+ // Import the native bridge module dynamically (same as Android)
375
+ const { NativeModules } = require('react-native');
376
+ const VoicePnBridge = NativeModules.VoicePnBridge;
377
+
378
+ if (VoicePnBridge) {
379
+ log('Checking for pending VoIP push data via iOS VoicePnBridge');
380
+
381
+ // Check for VoIP push notification data stored by the native push handler
382
+ const pendingVoipPushJson = await VoicePnBridge.getPendingVoipPush();
383
+ log('Raw pending VoIP push response:', pendingVoipPushJson);
384
+
385
+ if (pendingVoipPushJson) {
386
+ try {
387
+ const pendingVoipPush = JSON.parse(pendingVoipPushJson);
388
+ const voipPayload = pendingVoipPush?.payload;
389
+
390
+ if (voipPayload && voipPayload.metadata) {
391
+ log('Found pending VoIP push data:', voipPayload);
392
+
393
+ // Create push data structure that matches what the VoIP client expects
394
+ pushData = {
395
+ action: 'incoming_call',
396
+ metadata: voipPayload.metadata,
397
+ from_notification: true,
398
+ };
399
+
400
+ // Clear the pending VoIP push data so it doesn't get processed again
401
+ await VoicePnBridge.clearPendingVoipPush();
402
+ log('Cleared pending VoIP push data after retrieval');
403
+ } else {
404
+ log('Invalid VoIP push data structure');
405
+ }
406
+ } catch (parseError) {
407
+ log('Error parsing VoIP push JSON:', parseError);
408
+ }
409
+ } else {
410
+ log('No pending VoIP push data found');
350
411
  }
351
-
352
- // Create push data structure that matches what the VoIP client expects
353
- pushData = {
354
- action: pendingAction.action,
355
- metadata: metadata,
356
- from_notification: true,
357
- };
358
-
359
- // Clear the pending action so it doesn't get processed again
360
- await VoicePnBridge.clearPendingPushAction();
361
- log('Cleared pending push action after retrieval');
362
412
  } else {
363
- log('No pending push actions found');
413
+ log('VoicePnBridge not available on iOS');
364
414
  }
365
- } else {
366
- log('VoicePnBridge not available - this is expected on iOS');
415
+ } catch (bridgeError) {
416
+ log('Error accessing VoicePnBridge on iOS:', bridgeError);
367
417
  }
368
- } catch (bridgeError) {
369
- log('Error accessing VoicePnBridge:', bridgeError);
418
+ } else {
419
+ log('Push data check skipped - unsupported platform');
370
420
  }
371
421
 
372
422
  // Process the push notification if found