@voipsdk/react-native-voipcloud 0.2.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 (43) hide show
  1. package/README.md +172 -0
  2. package/android/build.gradle +61 -0
  3. package/android/src/main/AndroidManifest.xml +2 -0
  4. package/android/src/main/java/com/voipcloud/sdk/rn/VoipCloudModule.java +428 -0
  5. package/android/src/main/java/com/voipcloud/sdk/rn/VoipCloudPackage.java +21 -0
  6. package/android/src/main/java/com/voipcloud/sdk/rn/internal/Events.java +38 -0
  7. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedAccount.java +63 -0
  8. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedCall.java +179 -0
  9. package/android/src/main/java/com/voipcloud/sdk/rn/internal/ManagedCallRegistry.java +26 -0
  10. package/android/src/main/libs/voipcloud-release.aar +0 -0
  11. package/ios/VoipCloud.mm +40 -0
  12. package/lib/commonjs/License.js +51 -0
  13. package/lib/commonjs/License.js.map +1 -0
  14. package/lib/commonjs/VoipCloud.js +89 -0
  15. package/lib/commonjs/VoipCloud.js.map +1 -0
  16. package/lib/commonjs/events.js +29 -0
  17. package/lib/commonjs/events.js.map +1 -0
  18. package/lib/commonjs/index.js +27 -0
  19. package/lib/commonjs/index.js.map +1 -0
  20. package/lib/commonjs/types.js +2 -0
  21. package/lib/commonjs/types.js.map +1 -0
  22. package/lib/module/License.js +45 -0
  23. package/lib/module/License.js.map +1 -0
  24. package/lib/module/VoipCloud.js +83 -0
  25. package/lib/module/VoipCloud.js.map +1 -0
  26. package/lib/module/events.js +23 -0
  27. package/lib/module/events.js.map +1 -0
  28. package/lib/module/index.js +4 -0
  29. package/lib/module/index.js.map +1 -0
  30. package/lib/module/types.js +2 -0
  31. package/lib/module/types.js.map +1 -0
  32. package/lib/typescript/License.d.ts +31 -0
  33. package/lib/typescript/VoipCloud.d.ts +52 -0
  34. package/lib/typescript/events.d.ts +6 -0
  35. package/lib/typescript/index.d.ts +4 -0
  36. package/lib/typescript/types.d.ts +136 -0
  37. package/package.json +76 -0
  38. package/react-native-voipcloud.podspec +16 -0
  39. package/src/License.ts +52 -0
  40. package/src/VoipCloud.ts +98 -0
  41. package/src/events.ts +23 -0
  42. package/src/index.ts +23 -0
  43. package/src/types.ts +144 -0
@@ -0,0 +1,38 @@
1
+ package com.voipcloud.sdk.rn.internal;
2
+
3
+ import com.facebook.react.bridge.ReactContext;
4
+ import com.facebook.react.bridge.WritableMap;
5
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
6
+
7
+ /**
8
+ * Thin wrapper around DeviceEventEmitter so the rest of the bridge
9
+ * never imports React internals directly.
10
+ */
11
+ public final class Events {
12
+ // Account / call lifecycle (emitted by PJSIP callbacks).
13
+ public static final String REGISTRATION_STATE = "registrationState";
14
+ public static final String INCOMING_CALL = "incomingCall";
15
+ public static final String CALL_STATE = "callState";
16
+ public static final String CALL_MEDIA_STATE = "callMediaState";
17
+
18
+ // Per-action confirmations (emitted by the bridge after the action
19
+ // succeeds — gives the UI a single hook per control without forcing
20
+ // it to derive intent from callMediaState diffs).
21
+ public static final String CALL_HOLD = "callHold";
22
+ public static final String CALL_UNHOLD = "callUnhold";
23
+ public static final String CALL_MUTE = "callMute";
24
+ public static final String CALL_DTMF_SENT = "callDtmfSent";
25
+ public static final String CALL_TRANSFER = "callTransfer";
26
+
27
+ // Remote-driven events forwarded from PJSIP callbacks.
28
+ public static final String CALL_TRANSFER_STATUS = "callTransferStatus";
29
+ public static final String INCOMING_DTMF = "incomingDtmf";
30
+
31
+ private Events() {}
32
+
33
+ public static void emit(ReactContext ctx, String name, WritableMap payload) {
34
+ if (ctx == null || !ctx.hasActiveReactInstance()) return;
35
+ ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
36
+ .emit(name, payload);
37
+ }
38
+ }
@@ -0,0 +1,63 @@
1
+ package com.voipcloud.sdk.rn.internal;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.ReactContext;
5
+ import com.facebook.react.bridge.WritableMap;
6
+
7
+ import com.voipcloud.sdk.Account;
8
+ import com.voipcloud.sdk.AccountInfo;
9
+ import com.voipcloud.sdk.CallOpParam;
10
+ import com.voipcloud.sdk.OnIncomingCallParam;
11
+ import com.voipcloud.sdk.OnRegStateParam;
12
+
13
+ /**
14
+ * Account subclass forwarding PJSUA2 callbacks to JS as RN events.
15
+ * One instance per registered SIP account.
16
+ */
17
+ public final class ManagedAccount extends Account {
18
+ private final ReactContext ctx;
19
+ private final ManagedCallRegistry callRegistry;
20
+
21
+ public ManagedAccount(ReactContext ctx, ManagedCallRegistry callRegistry) {
22
+ this.ctx = ctx;
23
+ this.callRegistry = callRegistry;
24
+ }
25
+
26
+ public int accountId() {
27
+ try { return getId(); } catch (Exception e) { return -1; }
28
+ }
29
+
30
+ @Override
31
+ public void onRegState(OnRegStateParam prm) {
32
+ WritableMap payload = Arguments.createMap();
33
+ payload.putInt("accountId", accountId());
34
+ payload.putInt("code", prm.getCode());
35
+ payload.putString("reason", prm.getReason());
36
+ Events.emit(ctx, Events.REGISTRATION_STATE, payload);
37
+ }
38
+
39
+ @Override
40
+ public void onIncomingCall(OnIncomingCallParam prm) {
41
+ // Allocate a ManagedCall so we can fire callState events for
42
+ // this inbound leg. The consumer must call answer(callId) or
43
+ // hangup(callId) to proceed.
44
+ ManagedCall call = new ManagedCall(ctx, this, prm.getCallId());
45
+ callRegistry.put(call);
46
+
47
+ try {
48
+ AccountInfo accInfo = getInfo();
49
+ WritableMap payload = Arguments.createMap();
50
+ payload.putInt("accountId", accountId());
51
+ payload.putInt("callId", call.callId());
52
+ payload.putString("from", call.getInfo().getRemoteUri());
53
+ payload.putString("to", accInfo.getUri());
54
+ Events.emit(ctx, Events.INCOMING_CALL, payload);
55
+ } catch (Exception ignored) {
56
+ // If we cannot pull info, still notify with what we have.
57
+ WritableMap payload = Arguments.createMap();
58
+ payload.putInt("accountId", accountId());
59
+ payload.putInt("callId", call.callId());
60
+ Events.emit(ctx, Events.INCOMING_CALL, payload);
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,179 @@
1
+ package com.voipcloud.sdk.rn.internal;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.ReactContext;
5
+ import com.facebook.react.bridge.WritableMap;
6
+
7
+ import com.voipcloud.sdk.Account;
8
+ import com.voipcloud.sdk.AudDevManager;
9
+ import com.voipcloud.sdk.AudioMedia;
10
+ import com.voipcloud.sdk.Call;
11
+ import com.voipcloud.sdk.CallInfo;
12
+ import com.voipcloud.sdk.CallMediaInfo;
13
+ import com.voipcloud.sdk.Endpoint;
14
+ import com.voipcloud.sdk.OnCallMediaStateParam;
15
+ import com.voipcloud.sdk.OnCallStateParam;
16
+ import com.voipcloud.sdk.OnCallTransferStatusParam;
17
+ import com.voipcloud.sdk.OnDtmfDigitParam;
18
+ import com.voipcloud.sdk.pjmedia_type;
19
+ import com.voipcloud.sdk.pjsip_inv_state;
20
+ import com.voipcloud.sdk.pjsua_call_media_status;
21
+
22
+ /** Call subclass forwarding state callbacks to JS. */
23
+ public final class ManagedCall extends Call {
24
+ private final ReactContext ctx;
25
+ /** Local snapshot of the PJSUA call id — Call.getId() can throw post-disconnect. */
26
+ private final int cachedId;
27
+ /** Mute is tracked at the bridge level — PJSIP does not own this state. */
28
+ private volatile boolean isMuted = false;
29
+
30
+ public ManagedCall(ReactContext ctx, Account acc) {
31
+ super(acc);
32
+ this.ctx = ctx;
33
+ this.cachedId = -1;
34
+ }
35
+
36
+ public ManagedCall(ReactContext ctx, Account acc, int callId) {
37
+ super(acc, callId);
38
+ this.ctx = ctx;
39
+ this.cachedId = callId;
40
+ }
41
+
42
+ public int callId() {
43
+ try { return getId(); } catch (Exception e) { return cachedId; }
44
+ }
45
+
46
+ public boolean isMuted() { return isMuted; }
47
+
48
+ /**
49
+ * Toggle the local microphone for this call. Implementation:
50
+ * iterate the call's audio media, and for each active leg either
51
+ * stop (mute) or start (unmute) transmission from the capture
52
+ * device to that leg. Hold and mute are independent — muting a
53
+ * held call is a no-op for the audio bridge but the flag is still
54
+ * tracked so unhold-then-emit reflects the user's intent.
55
+ */
56
+ public void setMuted(Endpoint endpoint, boolean muted) throws Exception {
57
+ AudDevManager adm = endpoint.audDevManager();
58
+ AudioMedia mic = adm.getCaptureDevMedia();
59
+ CallInfo info = getInfo();
60
+ for (int i = 0; i < info.getMedia().size(); i++) {
61
+ CallMediaInfo mi = info.getMedia().get(i);
62
+ if (mi.getType() != pjmedia_type.PJMEDIA_TYPE_AUDIO) continue;
63
+ if (mi.getStatus() != pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE) continue;
64
+ AudioMedia leg = getAudioMedia(i);
65
+ if (muted) {
66
+ mic.stopTransmit(leg);
67
+ } else {
68
+ mic.startTransmit(leg);
69
+ }
70
+ }
71
+ this.isMuted = muted;
72
+ // PJSIP will not fire onCallMediaState for a bridge-only change,
73
+ // so push an event manually to keep the JS layer in sync.
74
+ emitMediaState();
75
+ }
76
+
77
+ @Override
78
+ public void onCallState(OnCallStateParam prm) {
79
+ CallInfo info;
80
+ try { info = getInfo(); }
81
+ catch (Exception e) {
82
+ // After DISCONNECTED, getInfo may fail; emit a minimal payload.
83
+ WritableMap p = Arguments.createMap();
84
+ p.putInt("callId", cachedId);
85
+ p.putString("state", "DISCONNECTED");
86
+ p.putInt("code", 0);
87
+ p.putString("reason", "");
88
+ Events.emit(ctx, Events.CALL_STATE, p);
89
+ return;
90
+ }
91
+ WritableMap p = Arguments.createMap();
92
+ p.putInt("callId", callId());
93
+ p.putString("state", invStateName(info.getState()));
94
+ p.putInt("code", info.getLastStatusCode());
95
+ p.putString("reason", info.getLastReason());
96
+ Events.emit(ctx, Events.CALL_STATE, p);
97
+ }
98
+
99
+ @Override
100
+ public void onCallMediaState(OnCallMediaStateParam prm) {
101
+ emitMediaState();
102
+ }
103
+
104
+ /**
105
+ * Multi-stage progress notifications for a REFER (call transfer)
106
+ * we initiated. Fires for each NOTIFY received from the remote
107
+ * (typically 100 Trying → 200 OK → … → final 2xx/4xx-6xx with
108
+ * `finalNotify=true`). Consumers can use this to drive a "transfer
109
+ * pending / done / failed" UI without polling.
110
+ */
111
+ @Override
112
+ public void onCallTransferStatus(OnCallTransferStatusParam prm) {
113
+ WritableMap p = Arguments.createMap();
114
+ p.putInt("callId", callId());
115
+ p.putInt("statusCode", prm.getStatusCode());
116
+ p.putString("reason", prm.getReason());
117
+ p.putBoolean("finalNotify", prm.getFinalNotify());
118
+ Events.emit(ctx, Events.CALL_TRANSFER_STATUS, p);
119
+ }
120
+
121
+ /**
122
+ * Inbound DTMF detected on the RTP stream of this call. Forward
123
+ * each digit individually so IVR-style consumers can build up an
124
+ * input buffer. `duration` is the digit duration in PJSIP timer
125
+ * ticks (≈ ms with default sampling).
126
+ */
127
+ @Override
128
+ public void onDtmfDigit(OnDtmfDigitParam prm) {
129
+ WritableMap p = Arguments.createMap();
130
+ p.putInt("callId", callId());
131
+ p.putString("digit", prm.getDigit());
132
+ p.putDouble("duration", prm.getDuration());
133
+ Events.emit(ctx, Events.INCOMING_DTMF, p);
134
+ }
135
+
136
+ /**
137
+ * Build and emit the `callMediaState` event from the current PJSIP
138
+ * media-info snapshot plus the bridge-tracked mute flag. Safe to
139
+ * call from any thread: DeviceEventEmitter takes care of the hop
140
+ * to the JS bridge.
141
+ */
142
+ public void emitMediaState() {
143
+ WritableMap p = Arguments.createMap();
144
+ p.putInt("callId", callId());
145
+ boolean hasAudio = false;
146
+ boolean isHold = false;
147
+ try {
148
+ CallInfo info = getInfo();
149
+ for (int i = 0; i < info.getMedia().size(); ++i) {
150
+ CallMediaInfo mi = info.getMedia().get(i);
151
+ if (mi.getType() != pjmedia_type.PJMEDIA_TYPE_AUDIO) continue;
152
+ int status = mi.getStatus();
153
+ if (status == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE) {
154
+ hasAudio = true;
155
+ } else if (status == pjsua_call_media_status.PJSUA_CALL_MEDIA_LOCAL_HOLD
156
+ || status == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD) {
157
+ isHold = true;
158
+ }
159
+ }
160
+ } catch (Exception ignored) {}
161
+ p.putBoolean("hasAudio", hasAudio);
162
+ p.putBoolean("isHold", isHold);
163
+ p.putBoolean("isMuted", isMuted);
164
+ Events.emit(ctx, Events.CALL_MEDIA_STATE, p);
165
+ }
166
+
167
+ private static String invStateName(int s) {
168
+ switch (s) {
169
+ case pjsip_inv_state.PJSIP_INV_STATE_NULL: return "NULL";
170
+ case pjsip_inv_state.PJSIP_INV_STATE_CALLING: return "CALLING";
171
+ case pjsip_inv_state.PJSIP_INV_STATE_INCOMING: return "INCOMING";
172
+ case pjsip_inv_state.PJSIP_INV_STATE_EARLY: return "EARLY";
173
+ case pjsip_inv_state.PJSIP_INV_STATE_CONNECTING: return "CONNECTING";
174
+ case pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED: return "CONFIRMED";
175
+ case pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED: return "DISCONNECTED";
176
+ default: return "UNKNOWN";
177
+ }
178
+ }
179
+ }
@@ -0,0 +1,26 @@
1
+ package com.voipcloud.sdk.rn.internal;
2
+
3
+ import java.util.concurrent.ConcurrentHashMap;
4
+
5
+ /**
6
+ * Lookup of active {@link ManagedCall} instances by PJSUA call id.
7
+ * Threaded — PJSIP callbacks and JS-driven method calls can interleave.
8
+ */
9
+ public final class ManagedCallRegistry {
10
+ private final ConcurrentHashMap<Integer, ManagedCall> calls = new ConcurrentHashMap<>();
11
+
12
+ public void put(ManagedCall call) {
13
+ int id = call.callId();
14
+ if (id >= 0) calls.put(id, call);
15
+ }
16
+
17
+ public ManagedCall get(int id) {
18
+ return calls.get(id);
19
+ }
20
+
21
+ public ManagedCall remove(int id) {
22
+ return calls.remove(id);
23
+ }
24
+
25
+ public void clear() { calls.clear(); }
26
+ }
@@ -0,0 +1,40 @@
1
+ // react-native-voipcloud — iOS placeholder.
2
+ //
3
+ // The Android build of the SDK is complete (libvoipcloud.so + JNI
4
+ // bridge). iOS bindings need an xcframework build of PJSIP, which
5
+ // requires Xcode on macOS. Until then, every JS call from iOS rejects
6
+ // with NOT_IMPLEMENTED so consumer apps notice early.
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+
10
+ @interface VoipCloud : NSObject <RCTBridgeModule>
11
+ @end
12
+
13
+ @implementation VoipCloud
14
+
15
+ RCT_EXPORT_MODULE(VoipCloud);
16
+
17
+ #define VC_STUB(name, ...) \
18
+ RCT_EXPORT_METHOD(name:(__VA_ARGS__) \
19
+ resolver:(RCTPromiseResolveBlock)resolve \
20
+ rejecter:(RCTPromiseRejectBlock)reject) \
21
+ { reject(@"VC_NOT_IMPLEMENTED", @"VoipCloud SDK iOS bindings not yet shipped.", nil); }
22
+
23
+ VC_STUB(setLicense, NSString *token)
24
+ VC_STUB(getLicenseStatus)
25
+ VC_STUB(stopLicenseRefresh)
26
+ VC_STUB(init_, NSDictionary *config) // renamed because of init clash
27
+ VC_STUB(shutdown)
28
+ VC_STUB(register, NSDictionary *cfg)
29
+ VC_STUB(unregister, NSInteger accountId)
30
+ VC_STUB(makeCall, NSInteger accountId uri:(NSString *)uri)
31
+ VC_STUB(answer, NSInteger callId)
32
+ VC_STUB(hangup, NSInteger callId)
33
+ VC_STUB(hold, NSInteger callId)
34
+ VC_STUB(unhold, NSInteger callId)
35
+ VC_STUB(mute, NSInteger callId on:(BOOL)on)
36
+ VC_STUB(sendDtmf, NSInteger callId digits:(NSString *)digits)
37
+ VC_STUB(transferCall, NSInteger callId destinationUri:(NSString *)destinationUri)
38
+ VC_STUB(hangupAllCalls)
39
+
40
+ @end
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.License = void 0;
7
+ var _reactNative = require("react-native");
8
+ const Native = _reactNative.NativeModules.VoipCloud;
9
+ if (!Native) {
10
+ // Defer the error: only thrown if the consumer actually calls a
11
+ // method, so importing the package never crashes at load time.
12
+ console.warn('[react-native-voipcloud] Native module not linked. ' + 'Did you rebuild the Android app after adding the package?');
13
+ }
14
+
15
+ /**
16
+ * License management — all SDK functionality is gated behind a valid
17
+ * token. Customers paste their token (issued by your server) into the
18
+ * app; the app calls {@link set} once at startup and the SDK handles
19
+ * everything else, including periodic refresh.
20
+ */
21
+ const License = exports.License = {
22
+ /**
23
+ * Apply a license token. Resolves on success, rejects with one of
24
+ * the granular `VC_*` codes if the token is malformed, signed by
25
+ * the wrong key, expired, suspended, or for a different app bundle.
26
+ *
27
+ * Side-effect: if the token's payload includes a `ref` field, the
28
+ * background refresher is started (or restarted with the new URL)
29
+ * automatically — the consumer never types a refresh URL.
30
+ */
31
+ set(token) {
32
+ return Native.setLicense(token);
33
+ },
34
+ /**
35
+ * Query the current license state. Safe to call before `set`
36
+ * (returns valid=false, status="unset").
37
+ */
38
+ status() {
39
+ return Native.getLicenseStatus();
40
+ },
41
+ /**
42
+ * Cancel the background refresher. Optional: most apps will
43
+ * never call this. Useful when the user logs out or the SDK is
44
+ * being torn down and you do not want a long-running daemon
45
+ * thread sitting in the process.
46
+ */
47
+ stopRefresh() {
48
+ return Native.stopLicenseRefresh();
49
+ }
50
+ };
51
+ //# sourceMappingURL=License.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","Native","NativeModules","VoipCloud","console","warn","License","exports","set","token","setLicense","status","getLicenseStatus","stopRefresh","stopLicenseRefresh"],"sourceRoot":"../../src","sources":["License.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,MAAMC,MAAM,GAAGC,0BAAa,CAACC,SAAS;AAEtC,IAAI,CAACF,MAAM,EAAE;EACT;EACA;EACAG,OAAO,CAACC,IAAI,CACR,qDAAqD,GACrD,2DACJ,CAAC;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG;EACnB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACIE,GAAGA,CAACC,KAAa,EAAiB;IAC9B,OAAOR,MAAM,CAACS,UAAU,CAACD,KAAK,CAAC;EACnC,CAAC;EAED;AACJ;AACA;AACA;EACIE,MAAMA,CAAA,EAA2B;IAC7B,OAAOV,MAAM,CAACW,gBAAgB,CAAC,CAAC;EACpC,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;EACIC,WAAWA,CAAA,EAAkB;IACzB,OAAOZ,MAAM,CAACa,kBAAkB,CAAC,CAAC;EACtC;AACJ,CAAC","ignoreList":[]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.VoipCloud = void 0;
7
+ var _reactNative = require("react-native");
8
+ var _License = require("./License");
9
+ var _events = require("./events");
10
+ const Native = _reactNative.NativeModules.VoipCloud;
11
+
12
+ /**
13
+ * Top-level VoIP SDK. Workflow:
14
+ *
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}.
19
+ *
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`.
23
+ */
24
+ const VoipCloud = exports.VoipCloud = {
25
+ // ---------------------- License ---------------------------------
26
+ License: _License.License,
27
+ // ---------------------- Lifecycle -------------------------------
28
+ init(cfg = {}) {
29
+ return Native.init(cfg);
30
+ },
31
+ shutdown() {
32
+ return Native.shutdown();
33
+ },
34
+ // ---------------------- Accounts --------------------------------
35
+ /** Register a new SIP account. Resolves with the account id. */
36
+ register(account) {
37
+ return Native.register(account);
38
+ },
39
+ unregister(accountId) {
40
+ return Native.unregister(accountId);
41
+ },
42
+ // ---------------------- Calls -----------------------------------
43
+ /** Place an outbound call. Resolves with the new callId. */
44
+ makeCall(accountId, destinationUri) {
45
+ return Native.makeCall(accountId, destinationUri);
46
+ },
47
+ answer(callId) {
48
+ return Native.answer(callId);
49
+ },
50
+ hangup(callId) {
51
+ return Native.hangup(callId);
52
+ },
53
+ hold(callId) {
54
+ return Native.hold(callId);
55
+ },
56
+ unhold(callId) {
57
+ return Native.unhold(callId);
58
+ },
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
+ mute(callId, on) {
67
+ return Native.mute(callId, on);
68
+ },
69
+ sendDtmf(callId, digits) {
70
+ return Native.sendDtmf(callId, digits);
71
+ },
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
+ transferCall(callId, destinationUri) {
77
+ return Native.transferCall(callId, destinationUri);
78
+ },
79
+ /**
80
+ * End every active call. Each call still emits its own
81
+ * `callState` event with state=DISCONNECTED.
82
+ */
83
+ hangupAllCalls() {
84
+ return Native.hangupAllCalls();
85
+ },
86
+ // ---------------------- Events ----------------------------------
87
+ on: _events.on
88
+ };
89
+ //# sourceMappingURL=VoipCloud.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.on = on;
7
+ 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;
13
+
14
+ /**
15
+ * Subscribe to a typed event. Returns a handle whose `remove()` must
16
+ * be called from a React `useEffect` cleanup to avoid leaks.
17
+ */
18
+ function on(name, callback) {
19
+ if (!emitter) {
20
+ return {
21
+ remove: () => {}
22
+ };
23
+ }
24
+ const sub = emitter.addListener(name, callback);
25
+ return {
26
+ remove: () => sub.remove()
27
+ };
28
+ }
29
+ //# sourceMappingURL=events.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "License", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _License.License;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "VoipCloud", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _VoipCloud.VoipCloud;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "addEventListener", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _events.on;
22
+ }
23
+ });
24
+ var _VoipCloud = require("./VoipCloud");
25
+ var _License = require("./License");
26
+ var _events = require("./events");
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,45 @@
1
+ import { NativeModules } from 'react-native';
2
+ const Native = NativeModules.VoipCloud;
3
+ if (!Native) {
4
+ // Defer the error: only thrown if the consumer actually calls a
5
+ // method, so importing the package never crashes at load time.
6
+ console.warn('[react-native-voipcloud] Native module not linked. ' + 'Did you rebuild the Android app after adding the package?');
7
+ }
8
+
9
+ /**
10
+ * License management — all SDK functionality is gated behind a valid
11
+ * token. Customers paste their token (issued by your server) into the
12
+ * app; the app calls {@link set} once at startup and the SDK handles
13
+ * everything else, including periodic refresh.
14
+ */
15
+ export const License = {
16
+ /**
17
+ * Apply a license token. Resolves on success, rejects with one of
18
+ * the granular `VC_*` codes if the token is malformed, signed by
19
+ * the wrong key, expired, suspended, or for a different app bundle.
20
+ *
21
+ * Side-effect: if the token's payload includes a `ref` field, the
22
+ * background refresher is started (or restarted with the new URL)
23
+ * automatically — the consumer never types a refresh URL.
24
+ */
25
+ set(token) {
26
+ return Native.setLicense(token);
27
+ },
28
+ /**
29
+ * Query the current license state. Safe to call before `set`
30
+ * (returns valid=false, status="unset").
31
+ */
32
+ status() {
33
+ return Native.getLicenseStatus();
34
+ },
35
+ /**
36
+ * Cancel the background refresher. Optional: most apps will
37
+ * never call this. Useful when the user logs out or the SDK is
38
+ * being torn down and you do not want a long-running daemon
39
+ * thread sitting in the process.
40
+ */
41
+ stopRefresh() {
42
+ return Native.stopLicenseRefresh();
43
+ }
44
+ };
45
+ //# sourceMappingURL=License.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NativeModules","Native","VoipCloud","console","warn","License","set","token","setLicense","status","getLicenseStatus","stopRefresh","stopLicenseRefresh"],"sourceRoot":"../../src","sources":["License.ts"],"mappings":"AAAA,SAASA,aAAa,QAAQ,cAAc;AAG5C,MAAMC,MAAM,GAAGD,aAAa,CAACE,SAAS;AAEtC,IAAI,CAACD,MAAM,EAAE;EACT;EACA;EACAE,OAAO,CAACC,IAAI,CACR,qDAAqD,GACrD,2DACJ,CAAC;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,OAAO,GAAG;EACnB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACIC,GAAGA,CAACC,KAAa,EAAiB;IAC9B,OAAON,MAAM,CAACO,UAAU,CAACD,KAAK,CAAC;EACnC,CAAC;EAED;AACJ;AACA;AACA;EACIE,MAAMA,CAAA,EAA2B;IAC7B,OAAOR,MAAM,CAACS,gBAAgB,CAAC,CAAC;EACpC,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;EACIC,WAAWA,CAAA,EAAkB;IACzB,OAAOV,MAAM,CAACW,kBAAkB,CAAC,CAAC;EACtC;AACJ,CAAC","ignoreList":[]}