@voipsdk/react-native-voipcloud 0.2.1 → 1.0.1

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 (45) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +182 -117
  3. package/android/build.gradle +7 -7
  4. package/android/src/main/java/com/voipcloud/sdk/rn/VoipCloudModule.java +307 -208
  5. package/android/src/main/java/com/voipcloud/sdk/rn/internal/BridgeGuard.java +74 -0
  6. package/android/src/main/java/com/voipcloud/sdk/rn/internal/Events.java +7 -2
  7. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedAccount.java +49 -5
  8. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedCall.java +58 -2
  9. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedCallRegistry.java +4 -0
  10. package/android/src/main/libs/voipcloud-release.aar +0 -0
  11. package/ios/VoipCloud.mm +8 -8
  12. package/lib/commonjs/VoipCloud.js +33 -48
  13. package/lib/commonjs/VoipCloud.js.map +1 -1
  14. package/lib/commonjs/events.js +13 -7
  15. package/lib/commonjs/events.js.map +1 -1
  16. package/lib/commonjs/index.js +2 -3
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/nativeModule.js +18 -0
  19. package/lib/commonjs/nativeModule.js.map +1 -0
  20. package/lib/module/VoipCloud.js +34 -48
  21. package/lib/module/VoipCloud.js.map +1 -1
  22. package/lib/module/events.js +9 -8
  23. package/lib/module/events.js.map +1 -1
  24. package/lib/module/index.js +1 -2
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/module/nativeModule.js +13 -0
  27. package/lib/module/nativeModule.js.map +1 -0
  28. package/lib/typescript/VoipCloud.d.ts +7 -31
  29. package/lib/typescript/events.d.ts +6 -2
  30. package/lib/typescript/index.d.ts +2 -3
  31. package/lib/typescript/nativeModule.d.ts +7 -0
  32. package/lib/typescript/types.d.ts +5 -17
  33. package/package.json +7 -5
  34. package/react-native-voipcloud.podspec +7 -5
  35. package/src/VoipCloud.ts +42 -49
  36. package/src/events.ts +9 -8
  37. package/src/index.ts +1 -3
  38. package/src/nativeModule.ts +17 -0
  39. package/src/types.ts +5 -18
  40. package/lib/commonjs/License.js +0 -51
  41. package/lib/commonjs/License.js.map +0 -1
  42. package/lib/module/License.js +0 -45
  43. package/lib/module/License.js.map +0 -1
  44. package/lib/typescript/License.d.ts +0 -31
  45. package/src/License.ts +0 -52
@@ -0,0 +1,74 @@
1
+ package com.voipcloud.sdk.rn.internal;
2
+
3
+ import com.facebook.react.bridge.Promise;
4
+ import com.facebook.react.bridge.ReadableMap;
5
+
6
+ /**
7
+ * Shared guards and input validation for the RN bridge — reject with clear
8
+ * VC_* codes instead of letting native/JNI exceptions crash the app.
9
+ */
10
+ public final class BridgeGuard {
11
+
12
+ private static volatile boolean nativeLoaded = false;
13
+ private static volatile String nativeLoadError =
14
+ "libvoipcloud.so failed to load (missing ABI, stale build, or AAR not packaged)";
15
+
16
+ /** Loads libvoipcloud.so before any SWIG type (Endpoint, voipcloudJNI). */
17
+ static {
18
+ try {
19
+ System.loadLibrary("voipcloud");
20
+ nativeLoaded = true;
21
+ } catch (UnsatisfiedLinkError e) {
22
+ nativeLoadError = "Failed to load libvoipcloud.so: " + e.getMessage()
23
+ + ". Ensure voipcloud-release.aar is included and the app was rebuilt.";
24
+ } catch (Throwable t) {
25
+ nativeLoadError = "Failed to load libvoipcloud.so: " + t.getMessage();
26
+ }
27
+ }
28
+
29
+ private BridgeGuard() {}
30
+
31
+ public static boolean isNativeLoaded() { return nativeLoaded; }
32
+
33
+ public static String nativeLoadError() { return nativeLoadError; }
34
+
35
+ /** Reject the promise if native .so did not load. Returns false when rejected. */
36
+ public static boolean ensureNative(Promise promise) {
37
+ if (nativeLoaded) return true;
38
+ promise.reject("VC_NATIVE_LOAD", nativeLoadError);
39
+ return false;
40
+ }
41
+
42
+ /** Reject if {@link VoipCloudModule} endpoint is not running. */
43
+ public static boolean ensureInited(boolean inited, Promise promise) {
44
+ if (inited) return true;
45
+ promise.reject("VC_NOT_INITIALIZED",
46
+ "VoipCloud.init() must succeed before calling this method.");
47
+ return false;
48
+ }
49
+
50
+ /**
51
+ * Read a required non-empty string field from a JS config object.
52
+ * Rejects with VC_INVALID_ARGUMENT and returns null on failure.
53
+ */
54
+ public static String requireString(ReadableMap map, String key, Promise promise) {
55
+ if (map == null || !map.hasKey(key) || map.isNull(key)) {
56
+ promise.reject("VC_INVALID_ARGUMENT", "Missing required field: " + key);
57
+ return null;
58
+ }
59
+ String value = map.getString(key);
60
+ if (value == null || value.trim().isEmpty()) {
61
+ promise.reject("VC_INVALID_ARGUMENT", "Field must not be empty: " + key);
62
+ return null;
63
+ }
64
+ return value.trim();
65
+ }
66
+
67
+ /** Reject with a stable code; message includes PJSIP detail when available. */
68
+ public static void reject(Promise promise, String code, String context, Throwable t) {
69
+ String detail = (t != null && t.getMessage() != null && !t.getMessage().isEmpty())
70
+ ? t.getMessage()
71
+ : (t != null ? t.getClass().getSimpleName() : "unknown error");
72
+ promise.reject(code, context + ": " + detail, t);
73
+ }
74
+ }
@@ -32,7 +32,12 @@ public final class Events {
32
32
 
33
33
  public static void emit(ReactContext ctx, String name, WritableMap payload) {
34
34
  if (ctx == null || !ctx.hasActiveReactInstance()) return;
35
- ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
36
- .emit(name, payload);
35
+ // PJSIP fires callbacks on its worker thread — hop to the RN UI queue
36
+ // so DeviceEventEmitter does not crash the app on some RN versions.
37
+ ctx.runOnUiQueueThread(() -> {
38
+ if (!ctx.hasActiveReactInstance()) return;
39
+ ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
40
+ .emit(name, payload);
41
+ });
37
42
  }
38
43
  }
@@ -7,8 +7,10 @@ import com.facebook.react.bridge.WritableMap;
7
7
  import com.voipcloud.sdk.Account;
8
8
  import com.voipcloud.sdk.AccountInfo;
9
9
  import com.voipcloud.sdk.CallOpParam;
10
+ import com.voipcloud.sdk.Endpoint;
10
11
  import com.voipcloud.sdk.OnIncomingCallParam;
11
12
  import com.voipcloud.sdk.OnRegStateParam;
13
+ import com.voipcloud.sdk.pjsip_status_code;
12
14
 
13
15
  /**
14
16
  * Account subclass forwarding PJSUA2 callbacks to JS as RN events.
@@ -17,10 +19,12 @@ import com.voipcloud.sdk.OnRegStateParam;
17
19
  public final class ManagedAccount extends Account {
18
20
  private final ReactContext ctx;
19
21
  private final ManagedCallRegistry callRegistry;
22
+ private final Endpoint endpoint;
20
23
 
21
- public ManagedAccount(ReactContext ctx, ManagedCallRegistry callRegistry) {
24
+ public ManagedAccount(ReactContext ctx, ManagedCallRegistry callRegistry, Endpoint endpoint) {
22
25
  this.ctx = ctx;
23
26
  this.callRegistry = callRegistry;
27
+ this.endpoint = endpoint;
24
28
  }
25
29
 
26
30
  public int accountId() {
@@ -41,23 +45,63 @@ public final class ManagedAccount extends Account {
41
45
  // Allocate a ManagedCall so we can fire callState events for
42
46
  // this inbound leg. The consumer must call answer(callId) or
43
47
  // hangup(callId) to proceed.
44
- ManagedCall call = new ManagedCall(ctx, this, prm.getCallId());
48
+ ManagedCall call = new ManagedCall(ctx, this, prm.getCallId(), callRegistry);
49
+ call.bindEndpoint(endpoint);
45
50
  callRegistry.put(call);
46
51
 
52
+ // Send 180 Ringing immediately: without a provisional response the
53
+ // caller hears dead silence and many PBX/trunk setups drop the call
54
+ // before the callee can answer.
55
+ try {
56
+ CallOpParam ringing = new CallOpParam();
57
+ ringing.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING);
58
+ call.answer(ringing);
59
+ } catch (Throwable ignored) {}
60
+
61
+ String from = "";
62
+ String to = "";
47
63
  try {
48
64
  AccountInfo accInfo = getInfo();
65
+ com.voipcloud.sdk.CallInfo callInfo = call.getInfo();
66
+ from = callInfo.getRemoteUri();
67
+ to = accInfo.getUri();
49
68
  WritableMap payload = Arguments.createMap();
50
69
  payload.putInt("accountId", accountId());
51
70
  payload.putInt("callId", call.callId());
52
- payload.putString("from", call.getInfo().getRemoteUri());
53
- payload.putString("to", accInfo.getUri());
71
+ payload.putString("from", from);
72
+ payload.putString("to", to);
73
+ // SIP Call-ID header — stable across systems (PBX CDR, CRM sync),
74
+ // unlike the numeric PJSUA call slot which is recycled.
75
+ payload.putString("sipCallId", callInfo.getCallIdString());
54
76
  Events.emit(ctx, Events.INCOMING_CALL, payload);
55
77
  } catch (Exception ignored) {
56
- // If we cannot pull info, still notify with what we have.
57
78
  WritableMap payload = Arguments.createMap();
58
79
  payload.putInt("accountId", accountId());
59
80
  payload.putInt("callId", call.callId());
60
81
  Events.emit(ctx, Events.INCOMING_CALL, payload);
61
82
  }
83
+ dispatchIncomingToApp(ctx, accountId(), call.callId(), from, to);
84
+ }
85
+
86
+ /** Notify VoicePBX native layer before JS (background incoming calls). */
87
+ private static void dispatchIncomingToApp(
88
+ ReactContext ctx, int accountId, int callId, String from, String to) {
89
+ try {
90
+ Class<?> cls = Class.forName("com.voicepbx.voip.VoipIncomingNotifier");
91
+ cls.getMethod(
92
+ "onIncomingCall",
93
+ android.content.Context.class,
94
+ int.class,
95
+ int.class,
96
+ String.class,
97
+ String.class)
98
+ .invoke(
99
+ null,
100
+ ctx.getApplicationContext(),
101
+ accountId,
102
+ callId,
103
+ from != null ? from : "",
104
+ to != null ? to : "");
105
+ } catch (Throwable ignored) {}
62
106
  }
63
107
  }
@@ -22,23 +22,31 @@ import com.voipcloud.sdk.pjsua_call_media_status;
22
22
  /** Call subclass forwarding state callbacks to JS. */
23
23
  public final class ManagedCall extends Call {
24
24
  private final ReactContext ctx;
25
+ private final ManagedCallRegistry registry;
25
26
  /** Local snapshot of the PJSUA call id — Call.getId() can throw post-disconnect. */
26
27
  private final int cachedId;
27
28
  /** Mute is tracked at the bridge level — PJSIP does not own this state. */
28
29
  private volatile boolean isMuted = false;
30
+ private Endpoint endpoint;
29
31
 
30
- public ManagedCall(ReactContext ctx, Account acc) {
32
+ public ManagedCall(ReactContext ctx, Account acc, ManagedCallRegistry registry) {
31
33
  super(acc);
32
34
  this.ctx = ctx;
35
+ this.registry = registry;
33
36
  this.cachedId = -1;
34
37
  }
35
38
 
36
- public ManagedCall(ReactContext ctx, Account acc, int callId) {
39
+ public ManagedCall(ReactContext ctx, Account acc, int callId, ManagedCallRegistry registry) {
37
40
  super(acc, callId);
38
41
  this.ctx = ctx;
42
+ this.registry = registry;
39
43
  this.cachedId = callId;
40
44
  }
41
45
 
46
+ public void bindEndpoint(Endpoint ep) {
47
+ this.endpoint = ep;
48
+ }
49
+
42
50
  public int callId() {
43
51
  try { return getId(); } catch (Exception e) { return cachedId; }
44
52
  }
@@ -54,6 +62,7 @@ public final class ManagedCall extends Call {
54
62
  * tracked so unhold-then-emit reflects the user's intent.
55
63
  */
56
64
  public void setMuted(Endpoint endpoint, boolean muted) throws Exception {
65
+ this.endpoint = endpoint;
57
66
  AudDevManager adm = endpoint.audDevManager();
58
67
  AudioMedia mic = adm.getCaptureDevMedia();
59
68
  CallInfo info = getInfo();
@@ -74,6 +83,43 @@ public final class ManagedCall extends Call {
74
83
  emitMediaState();
75
84
  }
76
85
 
86
+ /**
87
+ * Re-wire capture ↔ call ↔ playback (e.g. after hold/unhold or speaker change).
88
+ */
89
+ public void reconnectAudioMedia() {
90
+ connectAudioMedia();
91
+ emitMediaState();
92
+ }
93
+
94
+ /**
95
+ * Wire capture ↔ call ↔ playback whenever media becomes active.
96
+ * Required for two-way audio — PJSIP does not auto-bridge on Android.
97
+ */
98
+ private void connectAudioMedia() {
99
+ if (endpoint == null) return;
100
+ try {
101
+ AudDevManager adm = endpoint.audDevManager();
102
+ AudioMedia mic = adm.getCaptureDevMedia();
103
+ AudioMedia speaker = adm.getPlaybackDevMedia();
104
+ CallInfo info = getInfo();
105
+ for (int i = 0; i < info.getMedia().size(); i++) {
106
+ CallMediaInfo mi = info.getMedia().get(i);
107
+ if (mi.getType() != pjmedia_type.PJMEDIA_TYPE_AUDIO) continue;
108
+ AudioMedia leg = getAudioMedia(i);
109
+ int status = mi.getStatus();
110
+ if (status == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE) {
111
+ if (!isMuted) {
112
+ mic.startTransmit(leg);
113
+ }
114
+ leg.startTransmit(speaker);
115
+ } else {
116
+ try { mic.stopTransmit(leg); } catch (Exception ignored) {}
117
+ try { leg.stopTransmit(speaker); } catch (Exception ignored) {}
118
+ }
119
+ }
120
+ } catch (Exception ignored) {}
121
+ }
122
+
77
123
  @Override
78
124
  public void onCallState(OnCallStateParam prm) {
79
125
  CallInfo info;
@@ -86,6 +132,7 @@ public final class ManagedCall extends Call {
86
132
  p.putInt("code", 0);
87
133
  p.putString("reason", "");
88
134
  Events.emit(ctx, Events.CALL_STATE, p);
135
+ if (cachedId >= 0) registry.remove(cachedId);
89
136
  return;
90
137
  }
91
138
  WritableMap p = Arguments.createMap();
@@ -93,11 +140,20 @@ public final class ManagedCall extends Call {
93
140
  p.putString("state", invStateName(info.getState()));
94
141
  p.putInt("code", info.getLastStatusCode());
95
142
  p.putString("reason", info.getLastReason());
143
+ // SIP Call-ID header — lets JS attach the dialog id to outgoing
144
+ // calls too (makeCall only returns the recycled PJSUA slot).
145
+ try { p.putString("sipCallId", info.getCallIdString()); } catch (Exception ignored) {}
96
146
  Events.emit(ctx, Events.CALL_STATE, p);
147
+ int state = info.getState();
148
+ if (state == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED
149
+ || state == pjsip_inv_state.PJSIP_INV_STATE_NULL) {
150
+ registry.remove(callId());
151
+ }
97
152
  }
98
153
 
99
154
  @Override
100
155
  public void onCallMediaState(OnCallMediaStateParam prm) {
156
+ connectAudioMedia();
101
157
  emitMediaState();
102
158
  }
103
159
 
@@ -23,4 +23,8 @@ public final class ManagedCallRegistry {
23
23
  }
24
24
 
25
25
  public void clear() { calls.clear(); }
26
+
27
+ public java.util.Collection<ManagedCall> snapshot() {
28
+ return calls.values();
29
+ }
26
30
  }
package/ios/VoipCloud.mm CHANGED
@@ -1,28 +1,28 @@
1
- // react-native-voipcloud — iOS placeholder.
1
+ // @voipsdk/react-native-voipcloud — iOS placeholder.
2
2
  //
3
3
  // The Android build of the SDK is complete (libvoipcloud.so + JNI
4
4
  // bridge). iOS bindings need an xcframework build of PJSIP, which
5
5
  // requires Xcode on macOS. Until then, every JS call from iOS rejects
6
6
  // with NOT_IMPLEMENTED so consumer apps notice early.
7
+ //
8
+ // Native module name must match VoipCloudModule.getName() on Android
9
+ // and NATIVE_MODULE_NAME in src/nativeModule.ts.
7
10
 
8
11
  #import <React/RCTBridgeModule.h>
9
12
 
10
- @interface VoipCloud : NSObject <RCTBridgeModule>
13
+ @interface VoipsdkReactNativeVoipcloud : NSObject <RCTBridgeModule>
11
14
  @end
12
15
 
13
- @implementation VoipCloud
16
+ @implementation VoipsdkReactNativeVoipcloud
14
17
 
15
- RCT_EXPORT_MODULE(VoipCloud);
18
+ RCT_EXPORT_MODULE();
16
19
 
17
20
  #define VC_STUB(name, ...) \
18
21
  RCT_EXPORT_METHOD(name:(__VA_ARGS__) \
19
22
  resolver:(RCTPromiseResolveBlock)resolve \
20
23
  rejecter:(RCTPromiseRejectBlock)reject) \
21
- { reject(@"VC_NOT_IMPLEMENTED", @"VoipCloud SDK iOS bindings not yet shipped.", nil); }
24
+ { reject(@"VC_NOT_IMPLEMENTED", @"@voipsdk/react-native-voipcloud iOS bindings not yet shipped.", nil); }
22
25
 
23
- VC_STUB(setLicense, NSString *token)
24
- VC_STUB(getLicenseStatus)
25
- VC_STUB(stopLicenseRefresh)
26
26
  VC_STUB(init_, NSDictionary *config) // renamed because of init clash
27
27
  VC_STUB(shutdown)
28
28
  VC_STUB(register, NSDictionary *cfg)
@@ -4,86 +4,71 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.VoipCloud = void 0;
7
- var _reactNative = require("react-native");
8
- var _License = require("./License");
7
+ var _nativeModule = require("./nativeModule");
9
8
  var _events = require("./events");
10
- const Native = _reactNative.NativeModules.VoipCloud;
9
+ /** Thrown as Promise rejection — never crashes at import time. */
10
+ function rejectNotLinked() {
11
+ return Promise.reject(Object.assign(new Error('@voipsdk/react-native-voipcloud native module is not linked. ' + 'Install the package, rebuild the Android app ' + '(./gradlew clean assembleDebug), and ensure voipcloud-release.aar is packaged.'), {
12
+ code: 'VC_NOT_LINKED'
13
+ }));
14
+ }
15
+ function callNative(fn) {
16
+ if (!_nativeModule.NativeVoipCloud) return rejectNotLinked();
17
+ return fn();
18
+ }
11
19
 
12
20
  /**
13
- * Top-level VoIP SDK. Workflow:
21
+ * Top-level VoIP SDK for {@code @voipsdk/react-native-voipcloud}. Workflow:
14
22
  *
15
- * 1. {@link License.set} — install a token (paste from your portal).
16
- * 2. {@link init} — start the PJSIP endpoint.
17
- * 3. {@link register} — get an `accountId` back.
18
- * 4. {@link makeCall} / {@link answer} / {@link hangup}.
23
+ * 1. {@link init} — start the PJSIP endpoint.
24
+ * 2. {@link register} — get an `accountId` back.
25
+ * 3. {@link makeCall} / {@link answer} / {@link hangup}.
19
26
  *
20
- * Every method returns a Promise. License-gate failures surface as a
21
- * Promise rejection with `code = "VC_<NAME>"` matching the
22
- * `PJ_EVOIPCLOUD_*` enum from `voipcloud_errno.h`.
27
+ * Every method returns a Promise. Failures reject with a `VC_*` code.
23
28
  */
24
29
  const VoipCloud = exports.VoipCloud = {
25
- // ---------------------- License ---------------------------------
26
- License: _License.License,
27
- // ---------------------- Lifecycle -------------------------------
28
30
  init(cfg = {}) {
29
- return Native.init(cfg);
31
+ return callNative(() => _nativeModule.NativeVoipCloud.init(cfg ?? {}));
30
32
  },
31
33
  shutdown() {
32
- return Native.shutdown();
34
+ return callNative(() => _nativeModule.NativeVoipCloud.shutdown());
33
35
  },
34
- // ---------------------- Accounts --------------------------------
35
- /** Register a new SIP account. Resolves with the account id. */
36
36
  register(account) {
37
- return Native.register(account);
37
+ return callNative(() => _nativeModule.NativeVoipCloud.register(account));
38
38
  },
39
39
  unregister(accountId) {
40
- return Native.unregister(accountId);
40
+ return callNative(() => _nativeModule.NativeVoipCloud.unregister(accountId));
41
41
  },
42
- // ---------------------- Calls -----------------------------------
43
- /** Place an outbound call. Resolves with the new callId. */
44
42
  makeCall(accountId, destinationUri) {
45
- return Native.makeCall(accountId, destinationUri);
43
+ return callNative(() => _nativeModule.NativeVoipCloud.makeCall(accountId, destinationUri));
46
44
  },
47
45
  answer(callId) {
48
- return Native.answer(callId);
46
+ return callNative(() => _nativeModule.NativeVoipCloud.answer(callId));
49
47
  },
50
- hangup(callId) {
51
- return Native.hangup(callId);
48
+ hangup(callId, mode = 'normal') {
49
+ return callNative(() => _nativeModule.NativeVoipCloud.hangup(callId, mode));
52
50
  },
53
51
  hold(callId) {
54
- return Native.hold(callId);
52
+ return callNative(() => _nativeModule.NativeVoipCloud.hold(callId));
55
53
  },
56
54
  unhold(callId) {
57
- return Native.unhold(callId);
55
+ return callNative(() => _nativeModule.NativeVoipCloud.unhold(callId));
58
56
  },
59
- /**
60
- * Mute / unmute the local microphone for a call. Implemented by
61
- * stopping / starting the capture device's transmission to the
62
- * call's active audio media — independent of `hold`. A
63
- * `callMediaState` event fires after the toggle so the UI can
64
- * mirror the new `isMuted` flag without polling.
65
- */
66
57
  mute(callId, on) {
67
- return Native.mute(callId, on);
58
+ return callNative(() => _nativeModule.NativeVoipCloud.mute(callId, on));
68
59
  },
69
60
  sendDtmf(callId, digits) {
70
- return Native.sendDtmf(callId, digits);
61
+ return callNative(() => _nativeModule.NativeVoipCloud.sendDtmf(callId, digits));
71
62
  },
72
- /**
73
- * Blind-transfer a call (SIP REFER) to a new destination. The
74
- * local leg moves to DISCONNECTED once the remote party accepts.
75
- */
76
63
  transferCall(callId, destinationUri) {
77
- return Native.transferCall(callId, destinationUri);
64
+ return callNative(() => _nativeModule.NativeVoipCloud.transferCall(callId, destinationUri));
78
65
  },
79
- /**
80
- * End every active call. Each call still emits its own
81
- * `callState` event with state=DISCONNECTED.
82
- */
83
66
  hangupAllCalls() {
84
- return Native.hangupAllCalls();
67
+ return callNative(() => _nativeModule.NativeVoipCloud.hangupAllCalls());
68
+ },
69
+ reconnectCallAudio(callId) {
70
+ return callNative(() => _nativeModule.NativeVoipCloud.reconnectCallAudio(callId));
85
71
  },
86
- // ---------------------- Events ----------------------------------
87
72
  on: _events.on
88
73
  };
89
74
  //# sourceMappingURL=VoipCloud.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_License","_events","Native","NativeModules","VoipCloud","exports","License","init","cfg","shutdown","register","account","unregister","accountId","makeCall","destinationUri","answer","callId","hangup","hold","unhold","mute","on","sendDtmf","digits","transferCall","hangupAllCalls"],"sourceRoot":"../../src","sources":["VoipCloud.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAEA,MAAMG,MAAM,GAAGC,0BAAa,CAACC,SAAS;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAAG;EACrB;EACAE,OAAO,EAAPA,gBAAO;EAEP;EACAC,IAAIA,CAACC,GAAe,GAAG,CAAC,CAAC,EAAiB;IACtC,OAAON,MAAM,CAACK,IAAI,CAACC,GAAG,CAAC;EAC3B,CAAC;EAEDC,QAAQA,CAAA,EAAkB;IACtB,OAAOP,MAAM,CAACO,QAAQ,CAAC,CAAC;EAC5B,CAAC;EAED;EACA;EACAC,QAAQA,CAACC,OAAsB,EAAmB;IAC9C,OAAOT,MAAM,CAACQ,QAAQ,CAACC,OAAO,CAAC;EACnC,CAAC;EAEDC,UAAUA,CAACC,SAAiB,EAAiB;IACzC,OAAOX,MAAM,CAACU,UAAU,CAACC,SAAS,CAAC;EACvC,CAAC;EAED;EACA;EACAC,QAAQA,CAACD,SAAiB,EAAEE,cAAsB,EAAmB;IACjE,OAAOb,MAAM,CAACY,QAAQ,CAACD,SAAS,EAAEE,cAAc,CAAC;EACrD,CAAC;EAEDC,MAAMA,CAACC,MAAc,EAAiB;IAClC,OAAOf,MAAM,CAACc,MAAM,CAACC,MAAM,CAAC;EAChC,CAAC;EAEDC,MAAMA,CAACD,MAAc,EAAiB;IAClC,OAAOf,MAAM,CAACgB,MAAM,CAACD,MAAM,CAAC;EAChC,CAAC;EAEDE,IAAIA,CAACF,MAAc,EAAiB;IAChC,OAAOf,MAAM,CAACiB,IAAI,CAACF,MAAM,CAAC;EAC9B,CAAC;EAEDG,MAAMA,CAACH,MAAc,EAAiB;IAClC,OAAOf,MAAM,CAACkB,MAAM,CAACH,MAAM,CAAC;EAChC,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;EACII,IAAIA,CAACJ,MAAc,EAAEK,EAAW,EAAiB;IAC7C,OAAOpB,MAAM,CAACmB,IAAI,CAACJ,MAAM,EAAEK,EAAE,CAAC;EAClC,CAAC;EAEDC,QAAQA,CAACN,MAAc,EAAEO,MAAc,EAAiB;IACpD,OAAOtB,MAAM,CAACqB,QAAQ,CAACN,MAAM,EAAEO,MAAM,CAAC;EAC1C,CAAC;EAED;AACJ;AACA;AACA;EACIC,YAAYA,CAACR,MAAc,EAAEF,cAAsB,EAAiB;IAChE,OAAOb,MAAM,CAACuB,YAAY,CAACR,MAAM,EAAEF,cAAc,CAAC;EACtD,CAAC;EAED;AACJ;AACA;AACA;EACIW,cAAcA,CAAA,EAAkB;IAC5B,OAAOxB,MAAM,CAACwB,cAAc,CAAC,CAAC;EAClC,CAAC;EAED;EACAJ,EAAE,EAAFA;AACJ,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_nativeModule","require","_events","rejectNotLinked","Promise","reject","Object","assign","Error","code","callNative","fn","NativeVoipCloud","VoipCloud","exports","init","cfg","shutdown","register","account","unregister","accountId","makeCall","destinationUri","answer","callId","hangup","mode","hold","unhold","mute","on","sendDtmf","digits","transferCall","hangupAllCalls","reconnectCallAudio"],"sourceRoot":"../../src","sources":["VoipCloud.ts"],"mappings":"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","ignoreList":[]}
@@ -3,17 +3,21 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "NATIVE_MODULE_NAME", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _nativeModule.NATIVE_MODULE_NAME;
10
+ }
11
+ });
6
12
  exports.on = on;
7
13
  var _reactNative = require("react-native");
8
- const Native = _reactNative.NativeModules.VoipCloud;
9
-
10
- // Lazy emitter — must point at the module to satisfy the contract
11
- // NativeEventEmitter expects on RN 0.65+.
12
- const emitter = Native ? new _reactNative.NativeEventEmitter(Native) : null;
14
+ var _nativeModule = require("./nativeModule");
15
+ const emitter = _nativeModule.NativeVoipCloud ? new _reactNative.NativeEventEmitter(_nativeModule.NativeVoipCloud) : null;
13
16
 
14
17
  /**
15
- * Subscribe to a typed event. Returns a handle whose `remove()` must
16
- * be called from a React `useEffect` cleanup to avoid leaks.
18
+ * Subscribe to a typed event from {@code @voipsdk/react-native-voipcloud}.
19
+ * Returns a handle whose `remove()` must be called from a React `useEffect`
20
+ * cleanup to avoid leaks.
17
21
  */
18
22
  function on(name, callback) {
19
23
  if (!emitter) {
@@ -26,4 +30,6 @@ function on(name, callback) {
26
30
  remove: () => sub.remove()
27
31
  };
28
32
  }
33
+
34
+ /** Native module name registered with React Native (for debugging). */
29
35
  //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","Native","NativeModules","VoipCloud","emitter","NativeEventEmitter","on","name","callback","remove","sub","addListener"],"sourceRoot":"../../src","sources":["events.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,MAAMC,MAAM,GAAGC,0BAAa,CAACC,SAAS;;AAEtC;AACA;AACA,MAAMC,OAAO,GAAGH,MAAM,GAAG,IAAII,+BAAkB,CAACJ,MAAM,CAAC,GAAG,IAAI;;AAE9D;AACA;AACA;AACA;AACO,SAASK,EAAEA,CACdC,IAAO,EACPC,QAAsC,EAC1B;EACZ,IAAI,CAACJ,OAAO,EAAE;IACV,OAAO;MAAEK,MAAM,EAAEA,CAAA,KAAM,CAAC;IAAE,CAAC;EAC/B;EACA,MAAMC,GAAG,GAAGN,OAAO,CAACO,WAAW,CAACJ,IAAI,EAAEC,QAAgC,CAAC;EACvE,OAAO;IAAEC,MAAM,EAAEA,CAAA,KAAMC,GAAG,CAACD,MAAM,CAAC;EAAE,CAAC;AACzC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_nativeModule","emitter","NativeVoipCloud","NativeEventEmitter","on","name","callback","remove","sub","addListener"],"sourceRoot":"../../src","sources":["events.ts"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,IAAAC,aAAA,GAAAD,OAAA;AAEA,MAAME,OAAO,GAAGC,6BAAe,GAAG,IAAIC,+BAAkB,CAACD,6BAAe,CAAC,GAAG,IAAI;;AAEhF;AACA;AACA;AACA;AACA;AACO,SAASE,EAAEA,CACdC,IAAO,EACPC,QAAsC,EAC1B;EACZ,IAAI,CAACL,OAAO,EAAE;IACV,OAAO;MAAEM,MAAM,EAAEA,CAAA,KAAM,CAAC;IAAE,CAAC;EAC/B;EACA,MAAMC,GAAG,GAAGP,OAAO,CAACQ,WAAW,CAACJ,IAAI,EAAEC,QAAgC,CAAC;EACvE,OAAO;IAAEC,MAAM,EAAEA,CAAA,KAAMC,GAAG,CAACD,MAAM,CAAC;EAAE,CAAC;AACzC;;AAEA","ignoreList":[]}
@@ -3,10 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "License", {
6
+ Object.defineProperty(exports, "NATIVE_MODULE_NAME", {
7
7
  enumerable: true,
8
8
  get: function () {
9
- return _License.License;
9
+ return _events.NATIVE_MODULE_NAME;
10
10
  }
11
11
  });
12
12
  Object.defineProperty(exports, "VoipCloud", {
@@ -22,6 +22,5 @@ Object.defineProperty(exports, "addEventListener", {
22
22
  }
23
23
  });
24
24
  var _VoipCloud = require("./VoipCloud");
25
- var _License = require("./License");
26
25
  var _events = require("./events");
27
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_VoipCloud","require","_License","_events"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["_VoipCloud","require","_events"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NativeVoipCloud = exports.NATIVE_MODULE_NAME = void 0;
7
+ var _reactNative = require("react-native");
8
+ /**
9
+ * Native module name — must match {@code VoipCloudModule.getName()} on Android
10
+ * and the future iOS RCT export. Derived from npm package
11
+ * {@code @voipsdk/react-native-voipcloud}.
12
+ */
13
+ const NATIVE_MODULE_NAME = exports.NATIVE_MODULE_NAME = 'VoipsdkReactNativeVoipcloud';
14
+ const NativeVoipCloud = exports.NativeVoipCloud = _reactNative.NativeModules[NATIVE_MODULE_NAME];
15
+ if (!NativeVoipCloud) {
16
+ console.warn('[@voipsdk/react-native-voipcloud] Native module not linked. ' + 'Methods will reject with VC_NOT_LINKED until the app is rebuilt.');
17
+ }
18
+ //# sourceMappingURL=nativeModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","NATIVE_MODULE_NAME","exports","NativeVoipCloud","NativeModules","console","warn"],"sourceRoot":"../../src","sources":["nativeModule.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AACO,MAAMC,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,GAAG,6BAA6B;AAExD,MAAME,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAGC,0BAAa,CAACH,kBAAkB,CAAC;AAEhE,IAAI,CAACE,eAAe,EAAE;EAClBE,OAAO,CAACC,IAAI,CACR,8DAA8D,GAC9D,kEACJ,CAAC;AACL","ignoreList":[]}