react-native-ble-nitro 1.0.0-beta.0 → 1.0.0-beta.2
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/android/src/main/kotlin/co/zyke/ble/BleNitroBleManager.kt +103 -0
- package/ios/BleNitroBleManager.swift +73 -0
- package/lib/BleManagerCompatFactory.d.ts +2 -1
- package/lib/BleManagerCompatFactory.js +6 -3
- package/lib/BleManagerFactory.d.ts +19 -1
- package/lib/BleManagerFactory.js +53 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/specs/BleManager.nitro.d.ts +8 -0
- package/lib/utils/base64.d.ts +1 -1
- package/lib/utils/index.d.ts +2 -2
- package/lib/utils/index.js +2 -2
- package/lib/utils/uuid.d.ts +1 -1
- package/package.json +2 -2
- package/src/BleManagerCompatFactory.ts +4 -4
- package/src/BleManagerFactory.ts +67 -4
- package/src/__tests__/compatibility/enums.test.ts +0 -1
- package/src/index.ts +3 -0
- package/src/specs/BleManager.nitro.ts +16 -3
- package/src/utils/base64.ts +1 -1
- package/src/utils/index.ts +2 -2
- package/src/utils/uuid.ts +1 -1
|
@@ -57,6 +57,11 @@ class BleNitroBleManager(private val context: ReactApplicationContext) : HybridB
|
|
|
57
57
|
private var logLevel: LogLevel = LogLevel.None
|
|
58
58
|
private var isScanning = false
|
|
59
59
|
private var scanCallback: ScanCallback? = null
|
|
60
|
+
|
|
61
|
+
// State restoration
|
|
62
|
+
private var restoreIdentifier: String? = null
|
|
63
|
+
private var isInitialized = false
|
|
64
|
+
private var restoredState: BleRestoredState? = null
|
|
60
65
|
private var scanListener: ((NativeBleError?, NativeDevice?) -> Unit)? = null
|
|
61
66
|
private var stateChangeListener: ((State) -> Unit)? = null
|
|
62
67
|
|
|
@@ -100,6 +105,104 @@ class BleNitroBleManager(private val context: ReactApplicationContext) : HybridB
|
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
override fun initialize(options: BleManagerNitroOptions): Promise<Unit> = Promise.resolve {
|
|
109
|
+
options.restoreStateIdentifier?.let { restoreId ->
|
|
110
|
+
this.restoreIdentifier = restoreId
|
|
111
|
+
|
|
112
|
+
// Attempt to restore previous state from SharedPreferences
|
|
113
|
+
restoreConnectionState(restoreId)
|
|
114
|
+
|
|
115
|
+
Log.d(TAG, "BleNitro: Initialized with restore state identifier: $restoreId")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.isInitialized = true
|
|
119
|
+
Log.d(TAG, "BleNitro: BLE Manager initialized")
|
|
120
|
+
Unit
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override fun getRestoredState(): Promise<BleRestoredState?> = Promise.resolve {
|
|
124
|
+
restoredState
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private fun restoreConnectionState(restoreId: String) {
|
|
128
|
+
try {
|
|
129
|
+
val sharedPrefs = context.getSharedPreferences("BleNitro_$restoreId", Context.MODE_PRIVATE)
|
|
130
|
+
val connectedDevicesJson = sharedPrefs.getString("connected_devices", null)
|
|
131
|
+
|
|
132
|
+
connectedDevicesJson?.let { json ->
|
|
133
|
+
// Parse stored device IDs and attempt to reconnect
|
|
134
|
+
val deviceIds = json.split(",").filter { it.isNotEmpty() }
|
|
135
|
+
|
|
136
|
+
if (deviceIds.isNotEmpty()) {
|
|
137
|
+
Log.d(TAG, "BleNitro: Restoring ${deviceIds.size} devices")
|
|
138
|
+
|
|
139
|
+
deviceIds.forEach { deviceId ->
|
|
140
|
+
// Attempt to reconnect to previously connected devices
|
|
141
|
+
restoreDeviceConnection(deviceId)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Store restored state (initially empty, will be populated as devices reconnect)
|
|
145
|
+
val initialDevices = deviceIds.mapNotNull { deviceId ->
|
|
146
|
+
bluetoothAdapter?.getRemoteDevice(deviceId)?.let { device ->
|
|
147
|
+
createNativeDevice(device, null, -1) // Initial state without GATT
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (initialDevices.isNotEmpty()) {
|
|
152
|
+
this.restoredState = BleRestoredState(initialDevices)
|
|
153
|
+
Log.d(TAG, "BleNitro: Stored restored state with ${initialDevices.size} devices")
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} catch (e: Exception) {
|
|
158
|
+
Log.e(TAG, "BleNitro: Error restoring connection state", e)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private fun restoreDeviceConnection(deviceId: String) {
|
|
163
|
+
try {
|
|
164
|
+
val bluetoothDevice = bluetoothAdapter?.getRemoteDevice(deviceId)
|
|
165
|
+
bluetoothDevice?.let { device ->
|
|
166
|
+
Log.d(TAG, "BleNitro: Attempting to restore connection to $deviceId")
|
|
167
|
+
|
|
168
|
+
val gatt = device.connectGatt(context, true, object : BluetoothGattCallback() {
|
|
169
|
+
override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
|
|
170
|
+
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
|
171
|
+
connectedDevices[deviceId] = gatt!!
|
|
172
|
+
Log.d(TAG, "BleNitro: Successfully restored connection to $deviceId")
|
|
173
|
+
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
|
174
|
+
Log.d(TAG, "BleNitro: Failed to restore connection to $deviceId")
|
|
175
|
+
gatt?.close()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
if (gatt != null) {
|
|
181
|
+
deviceCallbacks[deviceId] = gatt
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
} catch (e: Exception) {
|
|
185
|
+
Log.e(TAG, "BleNitro: Error restoring device connection for $deviceId", e)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun saveConnectionState() {
|
|
190
|
+
restoreIdentifier?.let { restoreId ->
|
|
191
|
+
try {
|
|
192
|
+
val sharedPrefs = context.getSharedPreferences("BleNitro_$restoreId", Context.MODE_PRIVATE)
|
|
193
|
+
val deviceIds = connectedDevices.keys.joinToString(",")
|
|
194
|
+
|
|
195
|
+
sharedPrefs.edit()
|
|
196
|
+
.putString("connected_devices", deviceIds)
|
|
197
|
+
.apply()
|
|
198
|
+
|
|
199
|
+
Log.d(TAG, "BleNitro: Saved connection state for ${connectedDevices.size} devices")
|
|
200
|
+
} catch (e: Exception) {
|
|
201
|
+
Log.e(TAG, "BleNitro: Error saving connection state", e)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
103
206
|
override fun setLogLevel(logLevel: LogLevel): Promise<LogLevel> = Promise.resolve {
|
|
104
207
|
this.logLevel = logLevel
|
|
105
208
|
logLevel
|
|
@@ -26,12 +26,28 @@ public class BleNitroBleManager: HybridBleManagerSpec, CBCentralManagerDelegate
|
|
|
26
26
|
private var characteristicMonitors: [String: ((_ error: NativeBleError?, _ characteristic: NativeCharacteristic?) -> Void)] = [:]
|
|
27
27
|
private var pendingOperations: [String: Any] = [:]
|
|
28
28
|
|
|
29
|
+
// State restoration
|
|
30
|
+
private var restoreIdentifier: String?
|
|
31
|
+
private var isInitialized = false
|
|
32
|
+
private var restoredState: BleRestoredState?
|
|
33
|
+
|
|
29
34
|
// MARK: - Initialization
|
|
30
35
|
public override init() {
|
|
31
36
|
super.init()
|
|
37
|
+
// Initialize with default options - will be reconfigured in initialize() method
|
|
32
38
|
self.centralManager = CBCentralManager(delegate: self, queue: nil)
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
private func reinitializeCentralManager() {
|
|
42
|
+
// Create CBCentralManager with state restoration if identifier is provided
|
|
43
|
+
var options: [String: Any] = [:]
|
|
44
|
+
if let restoreId = restoreIdentifier {
|
|
45
|
+
options[CBCentralManagerOptionRestoreIdentifierKey] = restoreId
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.centralManager = CBCentralManager(delegate: self, queue: nil, options: options.isEmpty ? nil : options)
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
public override var memorySize: Int {
|
|
36
52
|
return MemorySize.MemorySize_estimate(self)
|
|
37
53
|
}
|
|
@@ -51,6 +67,29 @@ public class BleNitroBleManager: HybridBleManagerSpec, CBCentralManagerDelegate
|
|
|
51
67
|
}
|
|
52
68
|
}
|
|
53
69
|
|
|
70
|
+
public func initialize(options: BleManagerNitroOptions) throws -> Promise<Void> {
|
|
71
|
+
return Promise.resolve(withBlock: {
|
|
72
|
+
if let restoreId = options.restoreStateIdentifier {
|
|
73
|
+
// Store the restore identifier
|
|
74
|
+
self.restoreIdentifier = restoreId
|
|
75
|
+
|
|
76
|
+
// Reinitialize the central manager with state restoration
|
|
77
|
+
self.reinitializeCentralManager()
|
|
78
|
+
|
|
79
|
+
print("BleNitro: Initialized with restore state identifier: \(restoreId)")
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
self.isInitialized = true
|
|
83
|
+
print("BleNitro: BLE Manager initialized")
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public func getRestoredState() throws -> Promise<BleRestoredState?> {
|
|
88
|
+
return Promise.resolve(withBlock: {
|
|
89
|
+
return self.restoredState
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
54
93
|
public func setLogLevel(logLevel: LogLevel) throws -> Promise<LogLevel> {
|
|
55
94
|
return Promise.resolve(withBlock: {
|
|
56
95
|
self.logLevel = logLevel
|
|
@@ -491,6 +530,40 @@ extension BleNitroBleManager: CBPeripheralDelegate {
|
|
|
491
530
|
}
|
|
492
531
|
}
|
|
493
532
|
}
|
|
533
|
+
|
|
534
|
+
// MARK: - CBCentralManagerDelegate State Restoration
|
|
535
|
+
|
|
536
|
+
public func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
|
|
537
|
+
// Handle state restoration
|
|
538
|
+
if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] {
|
|
539
|
+
print("BleNitro: Restoring \(peripherals.count) peripherals")
|
|
540
|
+
|
|
541
|
+
// Add restored peripherals to our connected devices
|
|
542
|
+
for peripheral in peripherals {
|
|
543
|
+
let deviceId = peripheral.identifier.uuidString
|
|
544
|
+
connectedDevices[deviceId] = peripheral
|
|
545
|
+
peripheral.delegate = self
|
|
546
|
+
|
|
547
|
+
print("BleNitro: Restored peripheral: \(deviceId)")
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Store restored state for later retrieval
|
|
551
|
+
if !peripherals.isEmpty {
|
|
552
|
+
let restoredDevices = peripherals.map(createNativeDevice)
|
|
553
|
+
self.restoredState = BleRestoredState(connectedPeripherals: restoredDevices)
|
|
554
|
+
print("BleNitro: Stored restored state with \(restoredDevices.count) devices")
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
public func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
|
560
|
+
let newState = convertCBManagerStateToState(central.state)
|
|
561
|
+
|
|
562
|
+
// Notify state change listener if available
|
|
563
|
+
stateChangeListener?(newState)
|
|
564
|
+
|
|
565
|
+
print("BleNitro: Central manager state changed to: \(central.state.rawValue)")
|
|
566
|
+
}
|
|
494
567
|
}
|
|
495
568
|
|
|
496
569
|
/**
|
|
@@ -38,7 +38,8 @@ export declare class BleManagerCompat {
|
|
|
38
38
|
readCharacteristicForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, transactionId?: TransactionId): Promise<NativeCharacteristic>;
|
|
39
39
|
writeCharacteristicWithResponseForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, base64Value: string, transactionId?: TransactionId): Promise<NativeCharacteristic>;
|
|
40
40
|
writeCharacteristicWithoutResponseForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, base64Value: string, transactionId?: TransactionId): Promise<NativeCharacteristic>;
|
|
41
|
-
monitorCharacteristicForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, listener: (error: any | null, characteristic: NativeCharacteristic | null) => void,
|
|
41
|
+
monitorCharacteristicForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, listener: (error: any | null, characteristic: NativeCharacteristic | null) => void, // TODO: COMPAT! use proper error type like in react-native-ble-plx
|
|
42
|
+
transactionId?: TransactionId, subscriptionType?: 'notification' | 'indication'): Subscription;
|
|
42
43
|
descriptorsForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID): Promise<NativeDescriptor[]>;
|
|
43
44
|
readDescriptorForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, descriptorUUID: UUID, transactionId?: TransactionId): Promise<NativeDescriptor>;
|
|
44
45
|
writeDescriptorForDevice(deviceIdentifier: DeviceId, serviceUUID: UUID, characteristicUUID: UUID, descriptorUUID: UUID, valueBase64: string, transactionId?: TransactionId): Promise<NativeDescriptor>;
|
|
@@ -50,7 +50,8 @@ export class BleManagerCompat {
|
|
|
50
50
|
}, emitCurrentState);
|
|
51
51
|
}
|
|
52
52
|
// Device scanning with compatibility wrappers
|
|
53
|
-
async startDeviceScan(uuids, options, listener
|
|
53
|
+
async startDeviceScan(uuids, options, listener // TODO: COMPAT! remove any and move to BleError as react-native-ble-plx uses this type as well!
|
|
54
|
+
) {
|
|
54
55
|
return await this.bleManager.startDeviceScan(uuids, options, (error, device) => {
|
|
55
56
|
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
56
57
|
});
|
|
@@ -76,7 +77,8 @@ export class BleManagerCompat {
|
|
|
76
77
|
async isDeviceConnected(deviceIdentifier) {
|
|
77
78
|
return await this.bleManager.isDeviceConnected(deviceIdentifier);
|
|
78
79
|
}
|
|
79
|
-
onDeviceDisconnected(deviceIdentifier, listener
|
|
80
|
+
onDeviceDisconnected(deviceIdentifier, listener // TODO: COMPAT! use propper error type like in react-native-ble-plx!!!
|
|
81
|
+
) {
|
|
80
82
|
return this.bleManager.onDeviceDisconnected(deviceIdentifier, (error, device) => {
|
|
81
83
|
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
82
84
|
});
|
|
@@ -125,7 +127,8 @@ export class BleManagerCompat {
|
|
|
125
127
|
async writeCharacteristicWithoutResponseForDevice(deviceIdentifier, serviceUUID, characteristicUUID, base64Value, transactionId) {
|
|
126
128
|
return await this.bleManager.writeCharacteristicWithoutResponseForDevice(deviceIdentifier, serviceUUID, characteristicUUID, base64Value, transactionId);
|
|
127
129
|
}
|
|
128
|
-
monitorCharacteristicForDevice(deviceIdentifier, serviceUUID, characteristicUUID, listener,
|
|
130
|
+
monitorCharacteristicForDevice(deviceIdentifier, serviceUUID, characteristicUUID, listener, // TODO: COMPAT! use proper error type like in react-native-ble-plx
|
|
131
|
+
transactionId, subscriptionType) {
|
|
129
132
|
const nitroSubscriptionType = subscriptionType
|
|
130
133
|
? normalizeCharacteristicSubscriptionType(subscriptionType)
|
|
131
134
|
: undefined;
|
|
@@ -5,8 +5,26 @@ import type { BleManagerOptions } from './specs/types.js';
|
|
|
5
5
|
* This function maintains compatibility with react-native-ble-plx's BleManager constructor
|
|
6
6
|
*/
|
|
7
7
|
export declare function createBleManager(options?: BleManagerOptions): BleManagerInterface;
|
|
8
|
+
/**
|
|
9
|
+
* Helper function to retrieve stored callbacks for a BleManager instance
|
|
10
|
+
* This is used internally when callbacks need to be invoked
|
|
11
|
+
*/
|
|
12
|
+
export declare function getStoredCallbacks(manager: BleManagerInterface): {
|
|
13
|
+
restoreStateFunction?: (restoredState: any) => void;
|
|
14
|
+
errorCodesToMessagesMapping?: {
|
|
15
|
+
[key: number]: string;
|
|
16
|
+
};
|
|
17
|
+
} | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Helper function to get custom error message if available
|
|
20
|
+
* @param manager The BleManager instance
|
|
21
|
+
* @param errorCode The BLE error code
|
|
22
|
+
* @param defaultMessage Default error message
|
|
23
|
+
* @returns Custom message if available, otherwise default message
|
|
24
|
+
*/
|
|
25
|
+
export declare function getCustomErrorMessage(manager: BleManagerInterface, errorCode: number, defaultMessage: string): string;
|
|
8
26
|
/**
|
|
9
27
|
* Legacy compatibility: Export a BleManager constructor function
|
|
10
28
|
* This maintains compatibility with code that imports { BleManager } from 'react-native-ble-plx'
|
|
11
29
|
*/
|
|
12
|
-
export declare const BleManager:
|
|
30
|
+
export declare const BleManager: (options?: BleManagerOptions) => BleManagerInterface;
|
package/lib/BleManagerFactory.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
+
// Store callbacks that can't be passed to Nitro
|
|
3
|
+
const storedCallbacks = new WeakMap();
|
|
2
4
|
/**
|
|
3
5
|
* Creates a BleManager instance using Nitro Modules
|
|
4
6
|
* This function maintains compatibility with react-native-ble-plx's BleManager constructor
|
|
@@ -9,10 +11,59 @@ export function createBleManager(options) {
|
|
|
9
11
|
throw new Error('Failed to create BleManager: Nitro module not found. ' +
|
|
10
12
|
'Make sure react-native-ble-nitro is properly installed and linked.');
|
|
11
13
|
}
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
+
// Initialize with options if provided
|
|
15
|
+
if (options) {
|
|
16
|
+
// Extract Nitro-compatible options
|
|
17
|
+
const nitroOptions = {
|
|
18
|
+
restoreStateIdentifier: options.restoreStateIdentifier,
|
|
19
|
+
};
|
|
20
|
+
// Store callbacks and mappings that can't be passed to Nitro
|
|
21
|
+
if (options.restoreStateFunction || options.errorCodesToMessagesMapping) {
|
|
22
|
+
storedCallbacks.set(BleManagerModule, {
|
|
23
|
+
restoreStateFunction: options.restoreStateFunction,
|
|
24
|
+
errorCodesToMessagesMapping: options.errorCodesToMessagesMapping,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Note: initialize() is async but we need to maintain sync compatibility with react-native-ble-plx
|
|
28
|
+
// The initialization will happen asynchronously in the background
|
|
29
|
+
BleManagerModule.initialize(nitroOptions).then(async () => {
|
|
30
|
+
// Check for restored state and call the callback if available
|
|
31
|
+
if (options.restoreStateFunction) {
|
|
32
|
+
try {
|
|
33
|
+
const restoredState = await BleManagerModule.getRestoredState();
|
|
34
|
+
if (restoredState) {
|
|
35
|
+
options.restoreStateFunction(restoredState);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.warn('BleManager restore state callback failed:', error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}).catch(error => {
|
|
43
|
+
console.warn('BleManager initialization failed:', error);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
14
46
|
return BleManagerModule;
|
|
15
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Helper function to retrieve stored callbacks for a BleManager instance
|
|
50
|
+
* This is used internally when callbacks need to be invoked
|
|
51
|
+
*/
|
|
52
|
+
export function getStoredCallbacks(manager) {
|
|
53
|
+
return storedCallbacks.get(manager);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Helper function to get custom error message if available
|
|
57
|
+
* @param manager The BleManager instance
|
|
58
|
+
* @param errorCode The BLE error code
|
|
59
|
+
* @param defaultMessage Default error message
|
|
60
|
+
* @returns Custom message if available, otherwise default message
|
|
61
|
+
*/
|
|
62
|
+
export function getCustomErrorMessage(manager, errorCode, defaultMessage) {
|
|
63
|
+
const callbacks = storedCallbacks.get(manager);
|
|
64
|
+
const customMessage = callbacks?.errorCodesToMessagesMapping?.[errorCode];
|
|
65
|
+
return customMessage || defaultMessage;
|
|
66
|
+
}
|
|
16
67
|
/**
|
|
17
68
|
* Legacy compatibility: Export a BleManager constructor function
|
|
18
69
|
* This maintains compatibility with code that imports { BleManager } from 'react-native-ble-plx'
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './compatibility/constants.js';
|
|
2
2
|
export * from './utils/index.js';
|
|
3
3
|
export { BleManagerCompat as BleManager, createBleManagerCompat as createBleManager } from './BleManagerCompatFactory.js';
|
|
4
|
+
export { getCustomErrorMessage, getStoredCallbacks } from './BleManagerFactory.js';
|
|
4
5
|
export * from './errors/BleError.js';
|
|
5
6
|
export { DeviceWrapper as Device } from './compatibility/deviceWrapper.js';
|
|
6
7
|
export type { BleManagerOptions, ScanOptions, ConnectionOptions, NativeBleError, NativeDevice, NativeService, NativeCharacteristic, NativeDescriptor, Subscription } from './specs/types.js';
|
package/lib/index.js
CHANGED
|
@@ -4,6 +4,8 @@ export * from './compatibility/constants.js';
|
|
|
4
4
|
export * from './utils/index.js';
|
|
5
5
|
// Export the main BleManager instance with compatibility wrapper
|
|
6
6
|
export { BleManagerCompat as BleManager, createBleManagerCompat as createBleManager } from './BleManagerCompatFactory.js';
|
|
7
|
+
// Export BleManager factory utilities (for internal use by error handling)
|
|
8
|
+
export { getCustomErrorMessage, getStoredCallbacks } from './BleManagerFactory.js';
|
|
7
9
|
// Export error handling utilities
|
|
8
10
|
export * from './errors/BleError.js';
|
|
9
11
|
// Export device wrapper for compatibility
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
2
|
import type { State, LogLevel, UUID, DeviceId, TransactionId, ConnectionPriority, ScanOptions, ConnectionOptions, StateListener, DeviceScanListener, DeviceDisconnectedListener, CharacteristicMonitorListener, CharacteristicSubscriptionType, NativeDevice, NativeService, NativeCharacteristic, NativeDescriptor, Base64, Subscription } from './types.js';
|
|
3
|
+
export interface BleManagerNitroOptions {
|
|
4
|
+
restoreStateIdentifier?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface BleRestoredState {
|
|
7
|
+
connectedPeripherals: NativeDevice[];
|
|
8
|
+
}
|
|
3
9
|
export interface BleManager extends HybridObject<{
|
|
4
10
|
ios: 'swift';
|
|
5
11
|
android: 'kotlin';
|
|
6
12
|
}> {
|
|
7
13
|
destroy(): Promise<void>;
|
|
14
|
+
initialize(options: BleManagerNitroOptions): Promise<void>;
|
|
15
|
+
getRestoredState(): Promise<BleRestoredState | null>;
|
|
8
16
|
setLogLevel(logLevel: LogLevel): Promise<LogLevel>;
|
|
9
17
|
logLevel(): Promise<LogLevel>;
|
|
10
18
|
cancelTransaction(transactionId: TransactionId): Promise<void>;
|
package/lib/utils/base64.d.ts
CHANGED
package/lib/utils/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './uuid';
|
|
2
|
-
export * from './base64';
|
|
1
|
+
export * from './uuid.js';
|
|
2
|
+
export * from './base64.js';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './uuid';
|
|
2
|
-
export * from './base64';
|
|
1
|
+
export * from './uuid.js';
|
|
2
|
+
export * from './base64.js';
|
package/lib/utils/uuid.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ble-nitro",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "High-performance React Native BLE library built on Nitro Modules - drop-in replacement for react-native-ble-plx",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"nitro-codegen": "^0.26.4",
|
|
77
77
|
"react-native": "^0.76.0",
|
|
78
78
|
"ts-jest": "^29.4.0",
|
|
79
|
-
"typescript": "^5.
|
|
79
|
+
"typescript": "^5.8.3"
|
|
80
80
|
},
|
|
81
81
|
"files": [
|
|
82
82
|
"lib/",
|
|
@@ -93,7 +93,7 @@ export class BleManagerCompat {
|
|
|
93
93
|
async startDeviceScan(
|
|
94
94
|
uuids: UUID[] | null,
|
|
95
95
|
options: ScanOptions | null,
|
|
96
|
-
listener: (error: any | null, scannedDevice: DeviceWrapper | null) => void
|
|
96
|
+
listener: (error: any | null, scannedDevice: DeviceWrapper | null) => void // TODO: COMPAT! remove any and move to BleError as react-native-ble-plx uses this type as well!
|
|
97
97
|
): Promise<void> {
|
|
98
98
|
return await this.bleManager.startDeviceScan(uuids, options, (error, device) => {
|
|
99
99
|
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
@@ -131,7 +131,7 @@ export class BleManagerCompat {
|
|
|
131
131
|
|
|
132
132
|
onDeviceDisconnected(
|
|
133
133
|
deviceIdentifier: DeviceId,
|
|
134
|
-
listener: (error: any | null, device: DeviceWrapper | null) => void
|
|
134
|
+
listener: (error: any | null, device: DeviceWrapper | null) => void // TODO: COMPAT! use propper error type like in react-native-ble-plx!!!
|
|
135
135
|
): Subscription {
|
|
136
136
|
return this.bleManager.onDeviceDisconnected(deviceIdentifier, (error, device) => {
|
|
137
137
|
listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
|
|
@@ -255,7 +255,7 @@ export class BleManagerCompat {
|
|
|
255
255
|
deviceIdentifier: DeviceId,
|
|
256
256
|
serviceUUID: UUID,
|
|
257
257
|
characteristicUUID: UUID,
|
|
258
|
-
listener: (error: any | null, characteristic: NativeCharacteristic | null) => void,
|
|
258
|
+
listener: (error: any | null, characteristic: NativeCharacteristic | null) => void, // TODO: COMPAT! use proper error type like in react-native-ble-plx
|
|
259
259
|
transactionId?: TransactionId,
|
|
260
260
|
subscriptionType?: 'notification' | 'indication'
|
|
261
261
|
): Subscription {
|
|
@@ -324,7 +324,7 @@ export class BleManagerCompat {
|
|
|
324
324
|
* Helper method to create a Device wrapper from NativeDevice data
|
|
325
325
|
* This is a temporary method until we have proper Device Nitro objects
|
|
326
326
|
*/
|
|
327
|
-
private createDeviceFromNative(nativeDevice: NativeDevice)
|
|
327
|
+
private createDeviceFromNative(nativeDevice: NativeDevice) {
|
|
328
328
|
// This is a placeholder - in the actual implementation, we'd need to create
|
|
329
329
|
// proper Nitro Device objects, but for now we'll work with the native data
|
|
330
330
|
return {
|
package/src/BleManagerFactory.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
-
import type { BleManager as BleManagerInterface } from './specs/BleManager.nitro.js';
|
|
2
|
+
import type { BleManager as BleManagerInterface, BleManagerNitroOptions } from './specs/BleManager.nitro.js';
|
|
3
3
|
import type { BleManagerOptions } from './specs/types.js';
|
|
4
4
|
|
|
5
|
+
// Store callbacks that can't be passed to Nitro
|
|
6
|
+
const storedCallbacks = new WeakMap<BleManagerInterface, {
|
|
7
|
+
restoreStateFunction?: (restoredState: any) => void;
|
|
8
|
+
errorCodesToMessagesMapping?: { [key: number]: string };
|
|
9
|
+
}>();
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
12
|
* Creates a BleManager instance using Nitro Modules
|
|
7
13
|
* This function maintains compatibility with react-native-ble-plx's BleManager constructor
|
|
@@ -16,15 +22,72 @@ export function createBleManager(options?: BleManagerOptions): BleManagerInterfa
|
|
|
16
22
|
);
|
|
17
23
|
}
|
|
18
24
|
|
|
19
|
-
//
|
|
20
|
-
|
|
25
|
+
// Initialize with options if provided
|
|
26
|
+
if (options) {
|
|
27
|
+
// Extract Nitro-compatible options
|
|
28
|
+
const nitroOptions: BleManagerNitroOptions = {
|
|
29
|
+
restoreStateIdentifier: options.restoreStateIdentifier,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Store callbacks and mappings that can't be passed to Nitro
|
|
33
|
+
if (options.restoreStateFunction || options.errorCodesToMessagesMapping) {
|
|
34
|
+
storedCallbacks.set(BleManagerModule, {
|
|
35
|
+
restoreStateFunction: options.restoreStateFunction,
|
|
36
|
+
errorCodesToMessagesMapping: options.errorCodesToMessagesMapping,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Note: initialize() is async but we need to maintain sync compatibility with react-native-ble-plx
|
|
41
|
+
// The initialization will happen asynchronously in the background
|
|
42
|
+
BleManagerModule.initialize(nitroOptions).then(async () => {
|
|
43
|
+
// Check for restored state and call the callback if available
|
|
44
|
+
if (options.restoreStateFunction) {
|
|
45
|
+
try {
|
|
46
|
+
const restoredState = await BleManagerModule.getRestoredState();
|
|
47
|
+
if (restoredState) {
|
|
48
|
+
options.restoreStateFunction(restoredState);
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.warn('BleManager restore state callback failed:', error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}).catch(error => {
|
|
55
|
+
console.warn('BleManager initialization failed:', error);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
21
59
|
return BleManagerModule;
|
|
22
60
|
}
|
|
23
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Helper function to retrieve stored callbacks for a BleManager instance
|
|
64
|
+
* This is used internally when callbacks need to be invoked
|
|
65
|
+
*/
|
|
66
|
+
export function getStoredCallbacks(manager: BleManagerInterface) {
|
|
67
|
+
return storedCallbacks.get(manager);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Helper function to get custom error message if available
|
|
72
|
+
* @param manager The BleManager instance
|
|
73
|
+
* @param errorCode The BLE error code
|
|
74
|
+
* @param defaultMessage Default error message
|
|
75
|
+
* @returns Custom message if available, otherwise default message
|
|
76
|
+
*/
|
|
77
|
+
export function getCustomErrorMessage(
|
|
78
|
+
manager: BleManagerInterface,
|
|
79
|
+
errorCode: number,
|
|
80
|
+
defaultMessage: string
|
|
81
|
+
): string {
|
|
82
|
+
const callbacks = storedCallbacks.get(manager);
|
|
83
|
+
const customMessage = callbacks?.errorCodesToMessagesMapping?.[errorCode];
|
|
84
|
+
return customMessage || defaultMessage;
|
|
85
|
+
}
|
|
86
|
+
|
|
24
87
|
/**
|
|
25
88
|
* Legacy compatibility: Export a BleManager constructor function
|
|
26
89
|
* This maintains compatibility with code that imports { BleManager } from 'react-native-ble-plx'
|
|
27
90
|
*/
|
|
28
91
|
export const BleManager = function(options?: BleManagerOptions): BleManagerInterface {
|
|
29
92
|
return createBleManager(options);
|
|
30
|
-
} as
|
|
93
|
+
} as (options?: BleManagerOptions) => BleManagerInterface;
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,9 @@ export * from './utils/index.js';
|
|
|
7
7
|
// Export the main BleManager instance with compatibility wrapper
|
|
8
8
|
export { BleManagerCompat as BleManager, createBleManagerCompat as createBleManager } from './BleManagerCompatFactory.js';
|
|
9
9
|
|
|
10
|
+
// Export BleManager factory utilities (for internal use by error handling)
|
|
11
|
+
export { getCustomErrorMessage, getStoredCallbacks } from './BleManagerFactory.js';
|
|
12
|
+
|
|
10
13
|
// Export error handling utilities
|
|
11
14
|
export * from './errors/BleError.js';
|
|
12
15
|
|
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
ConnectionPriority,
|
|
9
9
|
ScanOptions,
|
|
10
10
|
ConnectionOptions,
|
|
11
|
-
BleManagerOptions,
|
|
12
11
|
StateListener,
|
|
13
12
|
DeviceScanListener,
|
|
14
13
|
DeviceDisconnectedListener,
|
|
@@ -18,16 +17,30 @@ import type {
|
|
|
18
17
|
NativeService,
|
|
19
18
|
NativeCharacteristic,
|
|
20
19
|
NativeDescriptor,
|
|
21
|
-
NativeBleError,
|
|
22
|
-
BleRestoredState,
|
|
23
20
|
Base64,
|
|
24
21
|
Subscription
|
|
25
22
|
} from './types.js';
|
|
26
23
|
|
|
24
|
+
// Nitro-compatible options interface (simplified without functions)
|
|
25
|
+
export interface BleManagerNitroOptions {
|
|
26
|
+
restoreStateIdentifier?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Interface for restored state data
|
|
30
|
+
export interface BleRestoredState {
|
|
31
|
+
connectedPeripherals: NativeDevice[];
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
export interface BleManager extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
|
|
28
35
|
// Lifecycle
|
|
29
36
|
destroy(): Promise<void>;
|
|
30
37
|
|
|
38
|
+
// Initialization - Configure the BLE manager with options
|
|
39
|
+
initialize(options: BleManagerNitroOptions): Promise<void>;
|
|
40
|
+
|
|
41
|
+
// Get restored state if available (called after initialization)
|
|
42
|
+
getRestoredState(): Promise<BleRestoredState | null>;
|
|
43
|
+
|
|
31
44
|
// Common operations
|
|
32
45
|
setLogLevel(logLevel: LogLevel): Promise<LogLevel>;
|
|
33
46
|
logLevel(): Promise<LogLevel>;
|
package/src/utils/base64.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './uuid';
|
|
2
|
-
export * from './base64';
|
|
1
|
+
export * from './uuid.js';
|
|
2
|
+
export * from './base64.js';
|
package/src/utils/uuid.ts
CHANGED