react-native-ble-nitro 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -12
- package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroBleManager.kt +12 -5
- package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroBleManagerFactory.kt +21 -0
- package/ios/BleNitroBleManager.swift +37 -24
- package/ios/BleNitroBleManagerFactory.swift +19 -0
- package/lib/commonjs/index.d.ts +2 -5
- package/lib/commonjs/index.d.ts.map +1 -1
- package/lib/commonjs/index.js +7 -15
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/manager.d.ts +43 -12
- package/lib/commonjs/manager.d.ts.map +1 -1
- package/lib/commonjs/manager.js +107 -43
- package/lib/commonjs/manager.js.map +1 -1
- package/lib/commonjs/singleton.d.ts +10 -0
- package/lib/commonjs/singleton.d.ts.map +1 -0
- package/lib/commonjs/singleton.js +20 -0
- package/lib/commonjs/singleton.js.map +1 -0
- package/lib/commonjs/specs/NativeBleNitro.d.ts +1 -1
- package/lib/commonjs/specs/NativeBleNitro.d.ts.map +1 -1
- package/lib/commonjs/specs/NativeBleNitro.js +1 -0
- package/lib/commonjs/specs/NativeBleNitro.js.map +1 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts +3 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts.map +1 -1
- package/lib/commonjs/specs/NativeBleNitro.nitro.js.map +1 -1
- package/lib/commonjs/specs/NativeBleNitroFactory.d.ts +5 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.d.ts.map +1 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.js +23 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.js.map +1 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.nitro.d.ts +9 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.nitro.d.ts.map +1 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.nitro.js +3 -0
- package/lib/commonjs/specs/NativeBleNitroFactory.nitro.js.map +1 -0
- package/lib/index.d.ts +2 -5
- package/lib/index.js +2 -11
- package/lib/manager.d.ts +43 -12
- package/lib/manager.js +100 -38
- package/lib/singleton.d.ts +9 -0
- package/lib/singleton.js +15 -0
- package/lib/specs/NativeBleNitro.d.ts +1 -1
- package/lib/specs/NativeBleNitro.js +1 -0
- package/lib/specs/NativeBleNitro.nitro.d.ts +3 -1
- package/lib/specs/NativeBleNitroFactory.d.ts +4 -0
- package/lib/specs/NativeBleNitroFactory.js +6 -0
- package/lib/specs/NativeBleNitroFactory.nitro.d.ts +8 -0
- package/lib/specs/NativeBleNitroFactory.nitro.js +1 -0
- package/nitro.json +4 -0
- package/nitrogen/generated/android/BleNitro+autolinking.cmake +2 -0
- package/nitrogen/generated/android/BleNitroOnLoad.cpp +11 -0
- package/nitrogen/generated/android/c++/JBLEDevice.hpp +6 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_BLEDevice_.hpp +12 -12
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroFactorySpec.cpp +71 -0
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroFactorySpec.hpp +64 -0
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.cpp +14 -6
- package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.hpp +3 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BLEDevice.kt +4 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Func_void_std__vector_BLEDevice_.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroFactorySpec.kt +57 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroSpec.kt +8 -4
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.hpp +53 -9
- package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Umbrella.hpp +5 -0
- package/nitrogen/generated/ios/BleNitroAutolinking.mm +8 -0
- package/nitrogen/generated/ios/BleNitroAutolinking.swift +15 -0
- package/nitrogen/generated/ios/c++/HybridNativeBleNitroFactorySpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNativeBleNitroFactorySpecSwift.hpp +94 -0
- package/nitrogen/generated/ios/c++/HybridNativeBleNitroSpecSwift.hpp +11 -5
- package/nitrogen/generated/ios/swift/BLEDevice.swift +13 -2
- package/nitrogen/generated/ios/swift/Func_void_std__vector_BLEDevice_.swift +5 -5
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroFactorySpec.swift +49 -0
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroFactorySpec_cxx.swift +149 -0
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec.swift +2 -2
- package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec_cxx.swift +24 -3
- package/nitrogen/generated/shared/c++/BLEDevice.hpp +6 -2
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroFactorySpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroFactorySpec.hpp +71 -0
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.hpp +5 -4
- package/package.json +9 -1
- package/src/__tests__/index.test.ts +53 -43
- package/src/index.ts +2 -13
- package/src/manager.ts +107 -38
- package/src/singleton.ts +17 -0
- package/src/specs/NativeBleNitro.nitro.ts +3 -1
- package/src/specs/NativeBleNitro.ts +2 -1
- package/src/specs/NativeBleNitroFactory.nitro.ts +6 -0
- package/src/specs/NativeBleNitroFactory.ts +9 -0
|
@@ -24,12 +24,12 @@ namespace margelo::nitro::co::zyke::ble { enum class BLEState; }
|
|
|
24
24
|
// Forward declaration of `OperationResult` to properly resolve imports.
|
|
25
25
|
namespace margelo::nitro::co::zyke::ble { struct OperationResult; }
|
|
26
26
|
|
|
27
|
+
#include <string>
|
|
28
|
+
#include <optional>
|
|
27
29
|
#include "BLEDevice.hpp"
|
|
28
30
|
#include <vector>
|
|
29
31
|
#include <functional>
|
|
30
32
|
#include "ScanFilter.hpp"
|
|
31
|
-
#include <optional>
|
|
32
|
-
#include <string>
|
|
33
33
|
#include <NitroModules/ArrayBuffer.hpp>
|
|
34
34
|
#include "BLEState.hpp"
|
|
35
35
|
#include "OperationResult.hpp"
|
|
@@ -62,7 +62,8 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
62
62
|
|
|
63
63
|
public:
|
|
64
64
|
// Properties
|
|
65
|
-
|
|
65
|
+
virtual std::optional<std::string> getRestoreStateIdentifier() = 0;
|
|
66
|
+
virtual void setRestoreStateIdentifier(const std::optional<std::string>& restoreStateIdentifier) = 0;
|
|
66
67
|
|
|
67
68
|
public:
|
|
68
69
|
// Methods
|
|
@@ -71,7 +72,7 @@ namespace margelo::nitro::co::zyke::ble {
|
|
|
71
72
|
virtual bool stopScan() = 0;
|
|
72
73
|
virtual bool isScanning() = 0;
|
|
73
74
|
virtual std::vector<BLEDevice> getConnectedDevices(const std::vector<std::string>& services) = 0;
|
|
74
|
-
virtual void connect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* deviceId */, const std::string& /* error */)>& callback, const std::optional<std::function<void(const std::string& /* deviceId */, bool /* interrupted */, const std::string& /* error */)>>& disconnectCallback) = 0;
|
|
75
|
+
virtual void connect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* deviceId */, const std::string& /* error */)>& callback, const std::optional<std::function<void(const std::string& /* deviceId */, bool /* interrupted */, const std::string& /* error */)>>& disconnectCallback, std::optional<bool> autoConnectAndroid) = 0;
|
|
75
76
|
virtual void disconnect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
|
|
76
77
|
virtual bool isConnected(const std::string& deviceId) = 0;
|
|
77
78
|
virtual double requestMTU(const std::string& deviceId, double mtu) = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ble-nitro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "High-performance React Native BLE library built on Nitro Modules",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
"types": "./lib/manager.d.ts",
|
|
24
24
|
"default": "./src/manager.ts"
|
|
25
25
|
},
|
|
26
|
+
"./singleton": {
|
|
27
|
+
"react-native": "./src/singleton.ts",
|
|
28
|
+
"typescript": "./src/singleton.ts",
|
|
29
|
+
"import": "./lib/singleton.js",
|
|
30
|
+
"require": "./lib/commonjs/singleton.js",
|
|
31
|
+
"types": "./lib/singleton.d.ts",
|
|
32
|
+
"default": "./src/singleton.ts"
|
|
33
|
+
},
|
|
26
34
|
"./plugin": {
|
|
27
35
|
"import": "./plugin/build/index.js",
|
|
28
36
|
"require": "./plugin/build/index.js",
|
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
// Mock the native module import
|
|
2
|
+
const mockNativeInstance = {
|
|
3
|
+
setRestoreStateCallback: jest.fn(),
|
|
4
|
+
startScan: jest.fn(),
|
|
5
|
+
stopScan: jest.fn(),
|
|
6
|
+
isScanning: jest.fn(),
|
|
7
|
+
connect: jest.fn(),
|
|
8
|
+
disconnect: jest.fn(),
|
|
9
|
+
isConnected: jest.fn(),
|
|
10
|
+
requestMTU: jest.fn(),
|
|
11
|
+
readRSSI: jest.fn(),
|
|
12
|
+
discoverServices: jest.fn(),
|
|
13
|
+
getServices: jest.fn(),
|
|
14
|
+
getCharacteristics: jest.fn(),
|
|
15
|
+
readCharacteristic: jest.fn(),
|
|
16
|
+
writeCharacteristic: jest.fn(),
|
|
17
|
+
subscribeToCharacteristic: jest.fn(),
|
|
18
|
+
unsubscribeFromCharacteristic: jest.fn(),
|
|
19
|
+
getConnectedDevices: jest.fn(),
|
|
20
|
+
requestBluetoothEnable: jest.fn(),
|
|
21
|
+
state: jest.fn(),
|
|
22
|
+
subscribeToStateChange: jest.fn(),
|
|
23
|
+
unsubscribeFromStateChange: jest.fn(),
|
|
24
|
+
openSettings: jest.fn(),
|
|
25
|
+
restoreStateIdentifier: null,
|
|
26
|
+
};
|
|
27
|
+
|
|
2
28
|
jest.mock('../specs/NativeBleNitro', () => ({
|
|
3
29
|
__esModule: true,
|
|
4
|
-
default:
|
|
5
|
-
|
|
6
|
-
startScan: jest.fn(),
|
|
7
|
-
stopScan: jest.fn(),
|
|
8
|
-
isScanning: jest.fn(),
|
|
9
|
-
connect: jest.fn(),
|
|
10
|
-
disconnect: jest.fn(),
|
|
11
|
-
isConnected: jest.fn(),
|
|
12
|
-
requestMTU: jest.fn(),
|
|
13
|
-
readRSSI: jest.fn(),
|
|
14
|
-
discoverServices: jest.fn(),
|
|
15
|
-
getServices: jest.fn(),
|
|
16
|
-
getCharacteristics: jest.fn(),
|
|
17
|
-
readCharacteristic: jest.fn(),
|
|
18
|
-
writeCharacteristic: jest.fn(),
|
|
19
|
-
subscribeToCharacteristic: jest.fn(),
|
|
20
|
-
unsubscribeFromCharacteristic: jest.fn(),
|
|
21
|
-
getConnectedDevices: jest.fn(),
|
|
22
|
-
requestBluetoothEnable: jest.fn(),
|
|
23
|
-
state: jest.fn(),
|
|
24
|
-
subscribeToStateChange: jest.fn(),
|
|
25
|
-
unsubscribeFromStateChange: jest.fn(),
|
|
26
|
-
openSettings: jest.fn(),
|
|
27
|
-
},
|
|
28
|
-
BLEState: {
|
|
30
|
+
default: mockNativeInstance,
|
|
31
|
+
BLEState: {
|
|
29
32
|
Unknown: 0,
|
|
30
33
|
Resetting: 1,
|
|
31
34
|
Unsupported: 2,
|
|
@@ -41,10 +44,17 @@ jest.mock('../specs/NativeBleNitro', () => ({
|
|
|
41
44
|
},
|
|
42
45
|
}));
|
|
43
46
|
|
|
47
|
+
jest.mock('../specs/NativeBleNitroFactory', () => ({
|
|
48
|
+
__esModule: true,
|
|
49
|
+
default: {
|
|
50
|
+
create: jest.fn(() => mockNativeInstance),
|
|
51
|
+
},
|
|
52
|
+
}));
|
|
53
|
+
|
|
44
54
|
import { BleNitro } from '../index';
|
|
45
55
|
|
|
46
56
|
// Get reference to the mocked module
|
|
47
|
-
const mockNative =
|
|
57
|
+
const mockNative = mockNativeInstance;
|
|
48
58
|
|
|
49
59
|
// Get BLE instance
|
|
50
60
|
const BleManager = BleNitro.instance();
|
|
@@ -97,8 +107,8 @@ describe('BleNitro', () => {
|
|
|
97
107
|
});
|
|
98
108
|
|
|
99
109
|
const result = await BleManager.connect(deviceId);
|
|
100
|
-
|
|
101
|
-
expect(mockNative.connect).toHaveBeenCalledWith(deviceId, expect.any(Function), undefined);
|
|
110
|
+
|
|
111
|
+
expect(mockNative.connect).toHaveBeenCalledWith(deviceId, expect.any(Function), undefined, false);
|
|
102
112
|
expect(result).toBe(deviceId);
|
|
103
113
|
});
|
|
104
114
|
|
|
@@ -142,7 +152,7 @@ describe('BleNitro', () => {
|
|
|
142
152
|
|
|
143
153
|
const data = [1, 2, 3];
|
|
144
154
|
const result = await BleManager.writeCharacteristic('device-write', 'service', 'char', data, false);
|
|
145
|
-
|
|
155
|
+
|
|
146
156
|
expect(mockNative.writeCharacteristic).toHaveBeenCalledWith(
|
|
147
157
|
'device-write',
|
|
148
158
|
'0service-0000-1000-8000-00805f9b34fb',
|
|
@@ -170,7 +180,7 @@ describe('BleNitro', () => {
|
|
|
170
180
|
|
|
171
181
|
const data = [1, 2, 3];
|
|
172
182
|
const result = await BleManager.writeCharacteristic('device-write-resp', 'service', 'char', data, true);
|
|
173
|
-
|
|
183
|
+
|
|
174
184
|
expect(mockNative.writeCharacteristic).toHaveBeenCalledWith(
|
|
175
185
|
'device-write-resp',
|
|
176
186
|
'0service-0000-1000-8000-00805f9b34fb',
|
|
@@ -196,15 +206,15 @@ describe('BleNitro', () => {
|
|
|
196
206
|
});
|
|
197
207
|
|
|
198
208
|
const result = await BleManager.readCharacteristic('device', 'service', 'char');
|
|
199
|
-
|
|
209
|
+
|
|
200
210
|
// UUIDs should be normalized in the call
|
|
201
211
|
expect(mockNative.readCharacteristic).toHaveBeenCalledWith(
|
|
202
|
-
'device',
|
|
212
|
+
'device',
|
|
203
213
|
'0service-0000-1000-8000-00805f9b34fb', // 'service' padded to 8 chars
|
|
204
214
|
'0000char-0000-1000-8000-00805f9b34fb', // 'char' padded to 8 chars
|
|
205
215
|
expect.any(Function)
|
|
206
216
|
);
|
|
207
|
-
|
|
217
|
+
|
|
208
218
|
// Result should be number array (ByteArray)
|
|
209
219
|
expect(Array.isArray(result)).toBe(true);
|
|
210
220
|
expect(result).toEqual([85]);
|
|
@@ -223,7 +233,7 @@ describe('BleNitro', () => {
|
|
|
223
233
|
});
|
|
224
234
|
|
|
225
235
|
const result = await BleManager.disconnect('device');
|
|
226
|
-
|
|
236
|
+
|
|
227
237
|
expect(mockNative.disconnect).toHaveBeenCalledWith('device', expect.any(Function));
|
|
228
238
|
expect(result).toBe(undefined);
|
|
229
239
|
});
|
|
@@ -245,10 +255,10 @@ describe('BleNitro', () => {
|
|
|
245
255
|
|
|
246
256
|
const notificationCallback = jest.fn();
|
|
247
257
|
const subscription = BleManager.subscribeToCharacteristic('device', 'service', 'char', notificationCallback);
|
|
248
|
-
|
|
258
|
+
|
|
249
259
|
expect(mockNative.subscribeToCharacteristic).toHaveBeenCalled();
|
|
250
260
|
expect(notificationCallback).toHaveBeenCalledWith('char-id', [1, 2, 3]);
|
|
251
|
-
|
|
261
|
+
|
|
252
262
|
// Verify subscription object
|
|
253
263
|
expect(subscription).toHaveProperty('remove');
|
|
254
264
|
expect(typeof subscription.remove).toBe('function');
|
|
@@ -257,10 +267,10 @@ describe('BleNitro', () => {
|
|
|
257
267
|
test('connect with disconnect event callback', async () => {
|
|
258
268
|
const deviceId = 'test-device-2'; // Use different device ID to avoid state conflicts
|
|
259
269
|
const onDisconnect = jest.fn();
|
|
260
|
-
|
|
270
|
+
|
|
261
271
|
mockNative.connect.mockImplementation((id: string, callback: (success: boolean, deviceId: string, error: string) => void, disconnectCallback?: (deviceId: string, interrupted: boolean, error: string) => void) => {
|
|
262
272
|
callback(true, id, '');
|
|
263
|
-
// Simulate a disconnect event later
|
|
273
|
+
// Simulate a disconnect event later
|
|
264
274
|
if (disconnectCallback) {
|
|
265
275
|
setTimeout(() => {
|
|
266
276
|
disconnectCallback(id, true, 'Connection lost'); // interrupted = true
|
|
@@ -269,10 +279,10 @@ describe('BleNitro', () => {
|
|
|
269
279
|
});
|
|
270
280
|
|
|
271
281
|
const result = await BleManager.connect(deviceId, onDisconnect);
|
|
272
|
-
|
|
273
|
-
expect(mockNative.connect).toHaveBeenCalledWith(deviceId, expect.any(Function), expect.any(Function));
|
|
282
|
+
|
|
283
|
+
expect(mockNative.connect).toHaveBeenCalledWith(deviceId, expect.any(Function), expect.any(Function), false);
|
|
274
284
|
expect(result).toBe(deviceId);
|
|
275
|
-
|
|
285
|
+
|
|
276
286
|
// Wait for disconnect callback
|
|
277
287
|
await new Promise(resolve => setTimeout(resolve, 30));
|
|
278
288
|
expect(onDisconnect).toHaveBeenCalledWith(deviceId, true, 'Connection lost');
|
|
@@ -297,7 +307,7 @@ describe('BleNitro', () => {
|
|
|
297
307
|
});
|
|
298
308
|
|
|
299
309
|
const rssi = await BleManager.readRSSI('device-rssi');
|
|
300
|
-
|
|
310
|
+
|
|
301
311
|
expect(mockNative.readRSSI).toHaveBeenCalledWith(
|
|
302
312
|
'device-rssi',
|
|
303
313
|
expect.any(Function)
|
|
@@ -318,7 +328,7 @@ describe('BleNitro', () => {
|
|
|
318
328
|
});
|
|
319
329
|
|
|
320
330
|
await expect(BleManager.readRSSI('device-rssi-fail')).rejects.toThrow('RSSI read failed');
|
|
321
|
-
|
|
331
|
+
|
|
322
332
|
expect(mockNative.readRSSI).toHaveBeenCalledWith(
|
|
323
333
|
'device-rssi-fail',
|
|
324
334
|
expect.any(Function)
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { BleNitroManager } from "./manager";
|
|
2
|
-
|
|
3
1
|
export {
|
|
4
2
|
type ByteArray,
|
|
5
3
|
type ScanFilter,
|
|
@@ -12,19 +10,10 @@ export {
|
|
|
12
10
|
type OperationCallback,
|
|
13
11
|
type CharacteristicUpdateCallback,
|
|
14
12
|
type Subscription,
|
|
15
|
-
type BleNitroManager,
|
|
16
13
|
type BleNitroManagerOptions,
|
|
17
14
|
BLEState,
|
|
18
15
|
AndroidScanMode,
|
|
16
|
+
BleNitroManager,
|
|
19
17
|
} from "./manager";
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export class BleNitro extends BleNitroManager {
|
|
24
|
-
public static instance() {
|
|
25
|
-
if (!_instance) {
|
|
26
|
-
_instance = new BleNitro();
|
|
27
|
-
}
|
|
28
|
-
return _instance;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
19
|
+
export { BleNitro } from './singleton';
|
package/src/manager.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BleNitroNativeFactory, { NativeBleNitro } from './specs/NativeBleNitroFactory';
|
|
2
2
|
import {
|
|
3
3
|
ScanFilter as NativeScanFilter,
|
|
4
4
|
BLEDevice as NativeBLEDevice,
|
|
@@ -32,6 +32,7 @@ export interface BLEDevice {
|
|
|
32
32
|
manufacturerData: ManufacturerData;
|
|
33
33
|
serviceUUIDs: string[];
|
|
34
34
|
isConnectable: boolean;
|
|
35
|
+
isConnected: boolean;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export type ScanCallback = (device: BLEDevice) => void;
|
|
@@ -73,6 +74,7 @@ export enum AndroidScanMode {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
export type BleNitroManagerOptions = {
|
|
77
|
+
restoreIdentifier?: string;
|
|
76
78
|
onRestoredState?: RestoreStateCallback;
|
|
77
79
|
};
|
|
78
80
|
|
|
@@ -123,16 +125,24 @@ export class BleNitroManager {
|
|
|
123
125
|
private _isScanning: boolean = false;
|
|
124
126
|
private _connectedDevices: { [deviceId: string]: boolean } = {};
|
|
125
127
|
|
|
126
|
-
private _restoredStateCallback: RestoreStateCallback | null
|
|
128
|
+
private _restoredStateCallback: RestoreStateCallback | null;
|
|
127
129
|
private _restoredState: BLEDevice[] | null = null;
|
|
130
|
+
private _restoreStateIdentifier: string | null = null;
|
|
131
|
+
|
|
132
|
+
private Instance: NativeBleNitro;
|
|
128
133
|
|
|
129
134
|
constructor(options?: BleNitroManagerOptions) {
|
|
130
|
-
this._restoredStateCallback = options?.onRestoredState
|
|
131
|
-
|
|
135
|
+
this._restoredStateCallback = options?.onRestoredState ?? null;
|
|
136
|
+
this._restoreStateIdentifier = options?.restoreIdentifier ?? null;
|
|
137
|
+
this.Instance = BleNitroNativeFactory.create(options?.restoreIdentifier, (peripherals: NativeBLEDevice[]) => this.onNativeRestoreStateCallback(peripherals));
|
|
132
138
|
}
|
|
133
139
|
|
|
134
140
|
private onNativeRestoreStateCallback(peripherals: NativeBLEDevice[]) {
|
|
141
|
+
if (!this._restoreStateIdentifier) return;
|
|
135
142
|
const bleDevices = peripherals.map((peripheral) => convertNativeBleDeviceToBleDevice(peripheral));
|
|
143
|
+
bleDevices.forEach((device) => {
|
|
144
|
+
this._connectedDevices[device.id] = device.isConnected;
|
|
145
|
+
});
|
|
136
146
|
if (this._restoredStateCallback) {
|
|
137
147
|
this._restoredStateCallback(bleDevices);
|
|
138
148
|
} else {
|
|
@@ -140,7 +150,13 @@ export class BleNitroManager {
|
|
|
140
150
|
}
|
|
141
151
|
}
|
|
142
152
|
|
|
153
|
+
/**
|
|
154
|
+
*
|
|
155
|
+
* Registers callback and returns restored peripheral state in it. Not working from 1.7.x upwards for singleton implementation!
|
|
156
|
+
* @deprecated This method is deprecated and will be removed in 2.x, use onRestoredState option in BleNitroManageroptions instead!
|
|
157
|
+
*/
|
|
143
158
|
public onRestoredState(callback: RestoreStateCallback) {
|
|
159
|
+
if (!this._restoreStateIdentifier) return;
|
|
144
160
|
if (this._restoredState) {
|
|
145
161
|
callback(this._restoredState);
|
|
146
162
|
this._restoredState = null;
|
|
@@ -176,7 +192,7 @@ export class BleNitroManager {
|
|
|
176
192
|
* Start scanning for Bluetooth devices
|
|
177
193
|
* @param filter Optional scan filter
|
|
178
194
|
* @param callback Callback function called when a device is found
|
|
179
|
-
* @returns
|
|
195
|
+
* @returns void
|
|
180
196
|
*/
|
|
181
197
|
public startScan(
|
|
182
198
|
filter: ScanFilter = {},
|
|
@@ -209,29 +225,29 @@ export class BleNitroManager {
|
|
|
209
225
|
};
|
|
210
226
|
|
|
211
227
|
// Start scan
|
|
212
|
-
|
|
228
|
+
this.Instance.startScan(nativeFilter, scanCallback);
|
|
213
229
|
this._isScanning = true;
|
|
214
230
|
}
|
|
215
231
|
|
|
216
232
|
/**
|
|
217
233
|
* Stop scanning for Bluetooth devices
|
|
218
|
-
* @returns
|
|
234
|
+
* @returns void
|
|
219
235
|
*/
|
|
220
236
|
public stopScan(): void {
|
|
221
237
|
if (!this._isScanning) {
|
|
222
238
|
return;
|
|
223
239
|
}
|
|
224
240
|
|
|
225
|
-
|
|
241
|
+
this.Instance.stopScan();
|
|
226
242
|
this._isScanning = false;
|
|
227
243
|
}
|
|
228
244
|
|
|
229
245
|
/**
|
|
230
246
|
* Check if currently scanning for devices
|
|
231
|
-
* @returns
|
|
247
|
+
* @returns Boolean indicating if currently scanning
|
|
232
248
|
*/
|
|
233
249
|
public isScanning(): boolean {
|
|
234
|
-
this._isScanning =
|
|
250
|
+
this._isScanning = this.Instance.isScanning();
|
|
235
251
|
return this._isScanning;
|
|
236
252
|
}
|
|
237
253
|
|
|
@@ -241,7 +257,7 @@ export class BleNitroManager {
|
|
|
241
257
|
* @returns Array of connected devices
|
|
242
258
|
*/
|
|
243
259
|
public getConnectedDevices(services?: string[]): BLEDevice[] {
|
|
244
|
-
const devices =
|
|
260
|
+
const devices = this.Instance.getConnectedDevices(services || []);
|
|
245
261
|
// Normalize service UUIDs - manufacturer data already comes as ArrayBuffers
|
|
246
262
|
return devices.map(device => convertNativeBleDeviceToBleDevice(device));
|
|
247
263
|
}
|
|
@@ -250,11 +266,12 @@ export class BleNitroManager {
|
|
|
250
266
|
* Connect to a Bluetooth device
|
|
251
267
|
* @param deviceId ID of the device to connect to
|
|
252
268
|
* @param onDisconnect Optional callback for disconnect events
|
|
253
|
-
* @returns Promise resolving when connected
|
|
269
|
+
* @returns Promise resolving deviceId when connected
|
|
254
270
|
*/
|
|
255
271
|
public connect(
|
|
256
272
|
deviceId: string,
|
|
257
|
-
onDisconnect?: DisconnectEventCallback
|
|
273
|
+
onDisconnect?: DisconnectEventCallback,
|
|
274
|
+
autoConnectAndroid?: boolean,
|
|
258
275
|
): Promise<string> {
|
|
259
276
|
return new Promise((resolve, reject) => {
|
|
260
277
|
// Check if already connected
|
|
@@ -263,7 +280,7 @@ export class BleNitroManager {
|
|
|
263
280
|
return;
|
|
264
281
|
}
|
|
265
282
|
|
|
266
|
-
|
|
283
|
+
this.Instance.connect(
|
|
267
284
|
deviceId,
|
|
268
285
|
(success: boolean, connectedDeviceId: string, error: string) => {
|
|
269
286
|
if (success) {
|
|
@@ -277,11 +294,45 @@ export class BleNitroManager {
|
|
|
277
294
|
// Remove from connected devices when disconnected
|
|
278
295
|
delete this._connectedDevices[deviceId];
|
|
279
296
|
onDisconnect(deviceId, interrupted, error);
|
|
280
|
-
} : undefined
|
|
297
|
+
} : undefined,
|
|
298
|
+
autoConnectAndroid ?? false,
|
|
281
299
|
);
|
|
282
300
|
});
|
|
283
301
|
}
|
|
284
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Scans for a device and connects to it
|
|
305
|
+
* @param deviceId ID of the device to connect to
|
|
306
|
+
* @param scanTimeout Optional timeout for the scan in milliseconds (default: 5000ms)
|
|
307
|
+
* @returns Promise resolving deviceId when connected
|
|
308
|
+
*/
|
|
309
|
+
public findAndConnect(deviceId: string, options?: { scanTimeout?: number, autoConnectAndroid?: boolean, onDisconnect?: DisconnectEventCallback }): Promise<string> {
|
|
310
|
+
const isConnected = this.isConnected(deviceId);
|
|
311
|
+
if (isConnected) {
|
|
312
|
+
return Promise.resolve(deviceId);
|
|
313
|
+
}
|
|
314
|
+
if (this._isScanning) {
|
|
315
|
+
this.stopScan();
|
|
316
|
+
}
|
|
317
|
+
return new Promise((resolve, reject) => {
|
|
318
|
+
const timeoutScan = setTimeout(() => {
|
|
319
|
+
this.stopScan();
|
|
320
|
+
reject(new Error('Scan timed out'));
|
|
321
|
+
}, options?.scanTimeout ?? 5000);
|
|
322
|
+
this.startScan(undefined, (device) => {
|
|
323
|
+
if (device.id === deviceId) {
|
|
324
|
+
this.stopScan();
|
|
325
|
+
clearTimeout(timeoutScan);
|
|
326
|
+
this.connect(deviceId, options?.onDisconnect, options?.autoConnectAndroid).then(async (connectedDeviceId) => {
|
|
327
|
+
resolve(connectedDeviceId);
|
|
328
|
+
}).catch((error) => {
|
|
329
|
+
reject(error);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
285
336
|
/**
|
|
286
337
|
* Disconnect from a Bluetooth device
|
|
287
338
|
* @param deviceId ID of the device to disconnect from
|
|
@@ -295,7 +346,7 @@ export class BleNitroManager {
|
|
|
295
346
|
return;
|
|
296
347
|
}
|
|
297
348
|
|
|
298
|
-
|
|
349
|
+
this.Instance.disconnect(
|
|
299
350
|
deviceId,
|
|
300
351
|
(success: boolean, error: string) => {
|
|
301
352
|
if (success) {
|
|
@@ -312,10 +363,10 @@ export class BleNitroManager {
|
|
|
312
363
|
/**
|
|
313
364
|
* Check if connected to a device
|
|
314
365
|
* @param deviceId ID of the device to check
|
|
315
|
-
* @returns
|
|
366
|
+
* @returns Boolean indicating if device is connected
|
|
316
367
|
*/
|
|
317
368
|
public isConnected(deviceId: string): boolean {
|
|
318
|
-
return
|
|
369
|
+
return this.Instance.isConnected(deviceId);
|
|
319
370
|
}
|
|
320
371
|
|
|
321
372
|
/**
|
|
@@ -326,7 +377,7 @@ export class BleNitroManager {
|
|
|
326
377
|
*/
|
|
327
378
|
public requestMTU(deviceId: string, mtu: number): number {
|
|
328
379
|
mtu = parseInt(mtu.toString(), 10);
|
|
329
|
-
const deviceMtu =
|
|
380
|
+
const deviceMtu = this.Instance.requestMTU(deviceId, mtu);
|
|
330
381
|
return deviceMtu;
|
|
331
382
|
}
|
|
332
383
|
|
|
@@ -343,7 +394,7 @@ export class BleNitroManager {
|
|
|
343
394
|
return;
|
|
344
395
|
}
|
|
345
396
|
|
|
346
|
-
|
|
397
|
+
this.Instance.readRSSI(
|
|
347
398
|
deviceId,
|
|
348
399
|
(success: boolean, rssi: number, error: string) => {
|
|
349
400
|
if (success) {
|
|
@@ -369,7 +420,7 @@ export class BleNitroManager {
|
|
|
369
420
|
return;
|
|
370
421
|
}
|
|
371
422
|
|
|
372
|
-
|
|
423
|
+
this.Instance.discoverServices(
|
|
373
424
|
deviceId,
|
|
374
425
|
(success: boolean, error: string) => {
|
|
375
426
|
if (success) {
|
|
@@ -400,7 +451,7 @@ export class BleNitroManager {
|
|
|
400
451
|
reject(new Error('Failed to discover services'));
|
|
401
452
|
return;
|
|
402
453
|
}
|
|
403
|
-
const services =
|
|
454
|
+
const services = this.Instance.getServices(deviceId);
|
|
404
455
|
resolve(BleNitroManager.normalizeGattUUIDs(services));
|
|
405
456
|
});
|
|
406
457
|
}
|
|
@@ -409,7 +460,7 @@ export class BleNitroManager {
|
|
|
409
460
|
* Get characteristics for a service
|
|
410
461
|
* @param deviceId ID of the device
|
|
411
462
|
* @param serviceId ID of the service
|
|
412
|
-
* @returns
|
|
463
|
+
* @returns array of characteristic UUIDs
|
|
413
464
|
*/
|
|
414
465
|
public getCharacteristics(
|
|
415
466
|
deviceId: string,
|
|
@@ -419,19 +470,37 @@ export class BleNitroManager {
|
|
|
419
470
|
throw new Error('Device not connected');
|
|
420
471
|
}
|
|
421
472
|
|
|
422
|
-
const characteristics =
|
|
473
|
+
const characteristics = this.Instance.getCharacteristics(
|
|
423
474
|
deviceId,
|
|
424
475
|
BleNitroManager.normalizeGattUUID(serviceId),
|
|
425
476
|
);
|
|
426
477
|
return BleNitroManager.normalizeGattUUIDs(characteristics);
|
|
427
478
|
}
|
|
428
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Get services and characteristics for a connected device
|
|
482
|
+
* @param deviceId ID of the device
|
|
483
|
+
* @returns Promise resolving to array of service and characteristic UUIDs
|
|
484
|
+
* @see getServices
|
|
485
|
+
* @see getCharacteristics
|
|
486
|
+
*/
|
|
487
|
+
public async getServicesWithCharacteristics(deviceId: string): Promise<{ uuid: string; characteristics: string[] }[]> {
|
|
488
|
+
await this.discoverServices(deviceId);
|
|
489
|
+
const services = await this.getServices(deviceId);
|
|
490
|
+
return services.map((service) => {
|
|
491
|
+
return {
|
|
492
|
+
uuid: service,
|
|
493
|
+
characteristics: this.getCharacteristics(deviceId, service),
|
|
494
|
+
};
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
429
498
|
/**
|
|
430
499
|
* Read a characteristic value
|
|
431
500
|
* @param deviceId ID of the device
|
|
432
501
|
* @param serviceId ID of the service
|
|
433
502
|
* @param characteristicId ID of the characteristic
|
|
434
|
-
* @returns Promise resolving to the characteristic data as
|
|
503
|
+
* @returns Promise resolving to the characteristic data as ByteArray
|
|
435
504
|
*/
|
|
436
505
|
public readCharacteristic(
|
|
437
506
|
deviceId: string,
|
|
@@ -445,7 +514,7 @@ export class BleNitroManager {
|
|
|
445
514
|
return;
|
|
446
515
|
}
|
|
447
516
|
|
|
448
|
-
|
|
517
|
+
this.Instance.readCharacteristic(
|
|
449
518
|
deviceId,
|
|
450
519
|
BleNitroManager.normalizeGattUUID(serviceId),
|
|
451
520
|
BleNitroManager.normalizeGattUUID(characteristicId),
|
|
@@ -483,7 +552,7 @@ export class BleNitroManager {
|
|
|
483
552
|
return;
|
|
484
553
|
}
|
|
485
554
|
|
|
486
|
-
|
|
555
|
+
this.Instance.writeCharacteristic(
|
|
487
556
|
deviceId,
|
|
488
557
|
BleNitroManager.normalizeGattUUID(serviceId),
|
|
489
558
|
BleNitroManager.normalizeGattUUID(characteristicId),
|
|
@@ -508,7 +577,7 @@ export class BleNitroManager {
|
|
|
508
577
|
* @param serviceId ID of the service
|
|
509
578
|
* @param characteristicId ID of the characteristic
|
|
510
579
|
* @param callback Callback function called when notification is received
|
|
511
|
-
* @returns
|
|
580
|
+
* @returns Subscription
|
|
512
581
|
*/
|
|
513
582
|
public subscribeToCharacteristic(
|
|
514
583
|
deviceId: string,
|
|
@@ -523,7 +592,7 @@ export class BleNitroManager {
|
|
|
523
592
|
|
|
524
593
|
let _success = false;
|
|
525
594
|
|
|
526
|
-
|
|
595
|
+
this.Instance.subscribeToCharacteristic(
|
|
527
596
|
deviceId,
|
|
528
597
|
BleNitroManager.normalizeGattUUID(serviceId),
|
|
529
598
|
BleNitroManager.normalizeGattUUID(characteristicId),
|
|
@@ -571,7 +640,7 @@ export class BleNitroManager {
|
|
|
571
640
|
return;
|
|
572
641
|
}
|
|
573
642
|
|
|
574
|
-
|
|
643
|
+
this.Instance.unsubscribeFromCharacteristic(
|
|
575
644
|
deviceId,
|
|
576
645
|
BleNitroManager.normalizeGattUUID(serviceId),
|
|
577
646
|
BleNitroManager.normalizeGattUUID(characteristicId),
|
|
@@ -588,7 +657,7 @@ export class BleNitroManager {
|
|
|
588
657
|
|
|
589
658
|
/**
|
|
590
659
|
* Check if Bluetooth is enabled
|
|
591
|
-
* @returns
|
|
660
|
+
* @returns returns Boolean according to Bluetooth state
|
|
592
661
|
*/
|
|
593
662
|
public isBluetoothEnabled(): boolean {
|
|
594
663
|
return this.state() === BLEState.PoweredOn;
|
|
@@ -600,7 +669,7 @@ export class BleNitroManager {
|
|
|
600
669
|
*/
|
|
601
670
|
public requestBluetoothEnable(): Promise<boolean> {
|
|
602
671
|
return new Promise((resolve, reject) => {
|
|
603
|
-
|
|
672
|
+
this.Instance.requestBluetoothEnable(
|
|
604
673
|
(success: boolean, error: string) => {
|
|
605
674
|
if (success) {
|
|
606
675
|
resolve(true);
|
|
@@ -614,18 +683,18 @@ export class BleNitroManager {
|
|
|
614
683
|
|
|
615
684
|
/**
|
|
616
685
|
* Get the current Bluetooth state
|
|
617
|
-
* @returns
|
|
686
|
+
* @returns Bluetooth state
|
|
618
687
|
* @see BLEState
|
|
619
688
|
*/
|
|
620
689
|
public state(): BLEState {
|
|
621
|
-
return mapNativeBLEStateToBLEState(
|
|
690
|
+
return mapNativeBLEStateToBLEState(this.Instance.state());
|
|
622
691
|
}
|
|
623
692
|
|
|
624
693
|
/**
|
|
625
694
|
* Subscribe to Bluetooth state changes
|
|
626
695
|
* @param callback Callback function called when state changes
|
|
627
696
|
* @param emitInitial Whether to emit initial state callback
|
|
628
|
-
* @returns
|
|
697
|
+
* @returns Subscription
|
|
629
698
|
* @see BLEState
|
|
630
699
|
*/
|
|
631
700
|
public subscribeToStateChange(callback: (state: BLEState) => void, emitInitial = false): Subscription {
|
|
@@ -634,13 +703,13 @@ export class BleNitroManager {
|
|
|
634
703
|
callback(state);
|
|
635
704
|
}
|
|
636
705
|
|
|
637
|
-
|
|
706
|
+
this.Instance.subscribeToStateChange((nativeState: NativeBLEState) => {
|
|
638
707
|
callback(mapNativeBLEStateToBLEState(nativeState));
|
|
639
708
|
});
|
|
640
709
|
|
|
641
710
|
return {
|
|
642
711
|
remove: () => {
|
|
643
|
-
|
|
712
|
+
this.Instance.unsubscribeFromStateChange();
|
|
644
713
|
},
|
|
645
714
|
};
|
|
646
715
|
}
|
|
@@ -650,6 +719,6 @@ export class BleNitroManager {
|
|
|
650
719
|
* @returns Promise resolving when settings are opened
|
|
651
720
|
*/
|
|
652
721
|
public openSettings(): Promise<void> {
|
|
653
|
-
return
|
|
722
|
+
return this.Instance.openSettings();
|
|
654
723
|
}
|
|
655
724
|
}
|
package/src/singleton.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BleNitroManager } from "./manager";
|
|
2
|
+
|
|
3
|
+
let _instance: BleNitroManager;
|
|
4
|
+
|
|
5
|
+
export class BleNitro extends BleNitroManager {
|
|
6
|
+
/**
|
|
7
|
+
* Get a singleton instance of BleNitro, will create one if it does not exist.
|
|
8
|
+
* Singleton implementation does not allow to use state restoration on iOS!
|
|
9
|
+
* @returns {BleNitroManager} An instance of BleNitro
|
|
10
|
+
*/
|
|
11
|
+
public static instance(): BleNitroManager {
|
|
12
|
+
if (!_instance) {
|
|
13
|
+
_instance = new BleNitro();
|
|
14
|
+
}
|
|
15
|
+
return _instance;
|
|
16
|
+
}
|
|
17
|
+
}
|