react-native-ble-nitro 1.0.0-alpha.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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +298 -0
  3. package/android/build.gradle +55 -0
  4. package/android/src/main/AndroidManifest.xml +23 -0
  5. package/android/src/main/kotlin/co/zyke/ble/BleNitroBleManager.kt +651 -0
  6. package/android/src/main/kotlin/co/zyke/ble/BleNitroPackage.kt +37 -0
  7. package/ios/BleNitro.podspec +37 -0
  8. package/ios/BleNitroBleManager.swift +509 -0
  9. package/ios/BleNitroModule.swift +31 -0
  10. package/lib/BleManagerCompatFactory.d.ts +53 -0
  11. package/lib/BleManagerCompatFactory.js +191 -0
  12. package/lib/BleManagerFactory.d.ts +12 -0
  13. package/lib/BleManagerFactory.js +22 -0
  14. package/lib/compatibility/constants.d.ts +49 -0
  15. package/lib/compatibility/constants.js +50 -0
  16. package/lib/compatibility/deviceWrapper.d.ts +99 -0
  17. package/lib/compatibility/deviceWrapper.js +259 -0
  18. package/lib/compatibility/enums.d.ts +43 -0
  19. package/lib/compatibility/enums.js +124 -0
  20. package/lib/compatibility/index.d.ts +11 -0
  21. package/lib/compatibility/index.js +12 -0
  22. package/lib/compatibility/serviceData.d.ts +51 -0
  23. package/lib/compatibility/serviceData.js +70 -0
  24. package/lib/errors/BleError.d.ts +59 -0
  25. package/lib/errors/BleError.js +120 -0
  26. package/lib/index.d.ts +7 -0
  27. package/lib/index.js +12 -0
  28. package/lib/specs/BleManager.nitro.d.ts +36 -0
  29. package/lib/specs/BleManager.nitro.js +1 -0
  30. package/lib/specs/Characteristic.nitro.d.ts +26 -0
  31. package/lib/specs/Characteristic.nitro.js +1 -0
  32. package/lib/specs/Descriptor.nitro.d.ts +17 -0
  33. package/lib/specs/Descriptor.nitro.js +1 -0
  34. package/lib/specs/Device.nitro.d.ts +37 -0
  35. package/lib/specs/Device.nitro.js +1 -0
  36. package/lib/specs/Service.nitro.d.ts +19 -0
  37. package/lib/specs/Service.nitro.js +1 -0
  38. package/lib/specs/types.d.ts +228 -0
  39. package/lib/specs/types.js +146 -0
  40. package/lib/utils/base64.d.ts +25 -0
  41. package/lib/utils/base64.js +80 -0
  42. package/lib/utils/index.d.ts +2 -0
  43. package/lib/utils/index.js +2 -0
  44. package/lib/utils/uuid.d.ts +9 -0
  45. package/lib/utils/uuid.js +37 -0
  46. package/nitro.json +15 -0
  47. package/package.json +102 -0
  48. package/plugin/build/index.d.ts +28 -0
  49. package/plugin/build/index.js +29 -0
  50. package/plugin/build/withBleNitro.d.ts +31 -0
  51. package/plugin/build/withBleNitro.js +87 -0
  52. package/react-native.config.js +13 -0
  53. package/src/BleManagerCompatFactory.ts +373 -0
  54. package/src/BleManagerFactory.ts +30 -0
  55. package/src/__tests__/BleManager.test.ts +327 -0
  56. package/src/__tests__/compatibility/deviceWrapper.test.ts +563 -0
  57. package/src/__tests__/compatibility/enums.test.ts +254 -0
  58. package/src/compatibility/constants.ts +71 -0
  59. package/src/compatibility/deviceWrapper.ts +427 -0
  60. package/src/compatibility/enums.ts +160 -0
  61. package/src/compatibility/index.ts +24 -0
  62. package/src/compatibility/serviceData.ts +85 -0
  63. package/src/errors/BleError.ts +193 -0
  64. package/src/index.ts +30 -0
  65. package/src/specs/BleManager.nitro.ts +152 -0
  66. package/src/specs/Characteristic.nitro.ts +61 -0
  67. package/src/specs/Descriptor.nitro.ts +28 -0
  68. package/src/specs/Device.nitro.ts +104 -0
  69. package/src/specs/Service.nitro.ts +64 -0
  70. package/src/specs/types.ts +259 -0
  71. package/src/utils/base64.ts +80 -0
  72. package/src/utils/index.ts +2 -0
  73. package/src/utils/uuid.ts +45 -0
@@ -0,0 +1,28 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ import withBleNitro, { withBleNitroAndroid, withBleNitroIOS, type BleNitroPluginProps } from './withBleNitro';
3
+ /**
4
+ * Expo Config Plugin for react-native-ble-nitro
5
+ *
6
+ * Configures iOS and Android permissions and settings for BLE operations
7
+ *
8
+ * @example
9
+ * ```json
10
+ * {
11
+ * "expo": {
12
+ * "plugins": [
13
+ * [
14
+ * "react-native-ble-nitro",
15
+ * {
16
+ * "isBackgroundEnabled": true,
17
+ * "modes": ["peripheral", "central"],
18
+ * "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
19
+ * }
20
+ * ]
21
+ * ]
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ declare const plugin: ConfigPlugin<BleNitroPluginProps | void>;
27
+ export default plugin;
28
+ export { withBleNitro, withBleNitroAndroid, withBleNitroIOS, type BleNitroPluginProps };
@@ -0,0 +1,29 @@
1
+ import withBleNitro, { withBleNitroAndroid, withBleNitroIOS } from './withBleNitro';
2
+ /**
3
+ * Expo Config Plugin for react-native-ble-nitro
4
+ *
5
+ * Configures iOS and Android permissions and settings for BLE operations
6
+ *
7
+ * @example
8
+ * ```json
9
+ * {
10
+ * "expo": {
11
+ * "plugins": [
12
+ * [
13
+ * "react-native-ble-nitro",
14
+ * {
15
+ * "isBackgroundEnabled": true,
16
+ * "modes": ["peripheral", "central"],
17
+ * "bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
18
+ * }
19
+ * ]
20
+ * ]
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ const plugin = (config, props) => {
26
+ return withBleNitro(config, props || {});
27
+ };
28
+ export default plugin;
29
+ export { withBleNitro, withBleNitroAndroid, withBleNitroIOS };
@@ -0,0 +1,31 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ export interface BleNitroPluginProps {
3
+ /**
4
+ * Enable background BLE support on Android.
5
+ * Adds required permissions and features to AndroidManifest.xml
6
+ * @default false
7
+ */
8
+ isBackgroundEnabled?: boolean;
9
+ /**
10
+ * Set to true only if you can strongly assert that your app never derives
11
+ * physical location from Bluetooth scan results. The location permission
12
+ * will still be required on older Android devices.
13
+ * @default false
14
+ * @warning This parameter is experimental and BLE might not work. Test before releasing.
15
+ */
16
+ neverForLocation?: boolean;
17
+ /**
18
+ * iOS background modes for BLE operations
19
+ * @default undefined
20
+ */
21
+ modes?: ('peripheral' | 'central')[];
22
+ /**
23
+ * iOS Bluetooth permission message. Set to false to skip adding the permission.
24
+ * @default "Allow $(PRODUCT_NAME) to connect to bluetooth devices"
25
+ */
26
+ bluetoothAlwaysPermission?: string | false;
27
+ }
28
+ export declare const withBleNitroAndroid: ConfigPlugin<BleNitroPluginProps>;
29
+ export declare const withBleNitroIOS: ConfigPlugin<BleNitroPluginProps>;
30
+ declare const withBleNitro: ConfigPlugin<BleNitroPluginProps>;
31
+ export default withBleNitro;
@@ -0,0 +1,87 @@
1
+ import { AndroidConfig, WarningAggregator, withAndroidManifest, withInfoPlist, } from 'expo/config-plugins';
2
+ const BLUETOOTH_PERMISSIONS = [
3
+ 'android.permission.BLUETOOTH',
4
+ 'android.permission.BLUETOOTH_ADMIN',
5
+ 'android.permission.ACCESS_COARSE_LOCATION',
6
+ 'android.permission.ACCESS_FINE_LOCATION',
7
+ ];
8
+ const BLUETOOTH_PERMISSIONS_API_31 = [
9
+ 'android.permission.BLUETOOTH_SCAN',
10
+ 'android.permission.BLUETOOTH_ADVERTISE',
11
+ 'android.permission.BLUETOOTH_CONNECT',
12
+ ];
13
+ export const withBleNitroAndroid = (config, props = {}) => {
14
+ const { isBackgroundEnabled = false, neverForLocation = false } = props;
15
+ return withAndroidManifest(config, (config) => {
16
+ const androidManifest = config.modResults;
17
+ // Add required permissions
18
+ AndroidConfig.Permissions.ensurePermissions(config.modResults, [
19
+ ...BLUETOOTH_PERMISSIONS,
20
+ ...BLUETOOTH_PERMISSIONS_API_31,
21
+ ]);
22
+ // Add uses-feature for BLE
23
+ if (!androidManifest.manifest['uses-feature']) {
24
+ androidManifest.manifest['uses-feature'] = [];
25
+ }
26
+ const usesFeatures = androidManifest.manifest['uses-feature'];
27
+ // Add BLE feature requirement
28
+ const bleFeature = {
29
+ $: {
30
+ 'android:name': 'android.hardware.bluetooth_le',
31
+ 'android:required': (isBackgroundEnabled ? 'true' : 'false'),
32
+ },
33
+ };
34
+ if (!usesFeatures.find((f) => f.$?.['android:name'] === 'android.hardware.bluetooth_le')) {
35
+ usesFeatures.push(bleFeature);
36
+ }
37
+ // Handle location permission settings for Android 12+
38
+ if (neverForLocation) {
39
+ // Add neverForLocation attribute to location permissions for Android 12+
40
+ const permissions = androidManifest.manifest['uses-permission'] || [];
41
+ permissions.forEach((permission) => {
42
+ if (permission.$?.['android:name'] === 'android.permission.ACCESS_FINE_LOCATION' ||
43
+ permission.$?.['android:name'] === 'android.permission.ACCESS_COARSE_LOCATION') {
44
+ permission.$['android:usesPermissionFlags'] = 'neverForLocation';
45
+ }
46
+ });
47
+ }
48
+ return config;
49
+ });
50
+ };
51
+ export const withBleNitroIOS = (config, props = {}) => {
52
+ const { modes, bluetoothAlwaysPermission = 'Allow $(PRODUCT_NAME) to connect to bluetooth devices' } = props;
53
+ return withInfoPlist(config, (config) => {
54
+ // Add NSBluetoothAlwaysUsageDescription
55
+ if (bluetoothAlwaysPermission !== false) {
56
+ config.modResults.NSBluetoothAlwaysUsageDescription = bluetoothAlwaysPermission;
57
+ }
58
+ // Add background modes if specified
59
+ if (modes && modes.length > 0) {
60
+ const backgroundModes = modes.map(mode => `bluetooth-${mode}`);
61
+ if (!config.modResults.UIBackgroundModes) {
62
+ config.modResults.UIBackgroundModes = [];
63
+ }
64
+ backgroundModes.forEach(mode => {
65
+ if (!config.modResults.UIBackgroundModes.includes(mode)) {
66
+ config.modResults.UIBackgroundModes.push(mode);
67
+ }
68
+ });
69
+ }
70
+ return config;
71
+ });
72
+ };
73
+ const withBleNitro = (config, props = {}) => {
74
+ // Validate props
75
+ if (props.neverForLocation && !props.isBackgroundEnabled) {
76
+ WarningAggregator.addWarningForPlatform('android', 'react-native-ble-nitro', 'neverForLocation is set to true but isBackgroundEnabled is false. ' +
77
+ 'This might cause issues with BLE scanning on some Android devices.');
78
+ }
79
+ if (props.modes && props.modes.some(mode => !['peripheral', 'central'].includes(mode))) {
80
+ WarningAggregator.addWarningForPlatform('ios', 'react-native-ble-nitro', 'Invalid background mode specified. Only "peripheral" and "central" are supported.');
81
+ }
82
+ // Apply platform-specific configurations
83
+ config = withBleNitroAndroid(config, props);
84
+ config = withBleNitroIOS(config, props);
85
+ return config;
86
+ };
87
+ export default withBleNitro;
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ sourceDir: './android',
6
+ packageImportPath: 'import co.zyke.ble.BleNitroPackage;',
7
+ },
8
+ ios: {
9
+ project: './ios/BleNitro.xcodeproj',
10
+ },
11
+ },
12
+ },
13
+ };
@@ -0,0 +1,373 @@
1
+ /**
2
+ * BleManager Compatibility Factory
3
+ *
4
+ * Creates BleManager instances with full react-native-ble-plx compatibility
5
+ * by wrapping the Nitro implementation with compatibility shims
6
+ */
7
+
8
+ import { createBleManager } from './BleManagerFactory';
9
+ import type { BleManager as BleManagerInterface } from './specs/BleManager.nitro';
10
+ import type {
11
+ BleManagerOptions,
12
+ UUID,
13
+ DeviceId,
14
+ TransactionId,
15
+ ConnectionPriority,
16
+ ConnectionOptions,
17
+ ScanOptions,
18
+ NativeDevice,
19
+ NativeService,
20
+ NativeCharacteristic,
21
+ NativeDescriptor,
22
+ LogLevel,
23
+ State,
24
+ Subscription
25
+ } from './specs/types';
26
+ import { DeviceWrapper } from './compatibility/deviceWrapper';
27
+ import {
28
+ stateToString,
29
+ stringToState,
30
+ logLevelToString,
31
+ stringToLogLevel,
32
+ normalizeLogLevel,
33
+ normalizeCharacteristicSubscriptionType,
34
+ characteristicSubscriptionTypeToString
35
+ } from './compatibility/enums';
36
+ import { serviceDataMapToArray } from './compatibility/serviceData';
37
+
38
+ /**
39
+ * BleManager wrapper that provides react-native-ble-plx compatibility
40
+ */
41
+ export class BleManagerCompat {
42
+ private bleManager: BleManagerInterface;
43
+
44
+ constructor(options?: BleManagerOptions) {
45
+ this.bleManager = createBleManager(options);
46
+ }
47
+
48
+ // Lifecycle
49
+ async destroy(): Promise<void> {
50
+ return await this.bleManager.destroy();
51
+ }
52
+
53
+ // Common operations with compatibility
54
+ async setLogLevel(logLevel: LogLevel | string): Promise<string> {
55
+ const normalizedLogLevel = normalizeLogLevel(logLevel);
56
+ const result = await this.bleManager.setLogLevel(normalizedLogLevel);
57
+ return logLevelToString(result);
58
+ }
59
+
60
+ async logLevel(): Promise<string> {
61
+ const result = await this.bleManager.logLevel();
62
+ return logLevelToString(result);
63
+ }
64
+
65
+ async cancelTransaction(transactionId: TransactionId): Promise<void> {
66
+ return await this.bleManager.cancelTransaction(transactionId);
67
+ }
68
+
69
+ // State management with string conversion
70
+ async enable(transactionId?: TransactionId): Promise<BleManagerCompat> {
71
+ await this.bleManager.enable(transactionId);
72
+ return this;
73
+ }
74
+
75
+ async disable(transactionId?: TransactionId): Promise<BleManagerCompat> {
76
+ await this.bleManager.disable(transactionId);
77
+ return this;
78
+ }
79
+
80
+ async state(): Promise<string> {
81
+ const result = await this.bleManager.state();
82
+ return stateToString(result);
83
+ }
84
+
85
+ onStateChange(
86
+ listener: (newState: string) => void,
87
+ emitCurrentState?: boolean
88
+ ): Subscription {
89
+ return this.bleManager.onStateChange((state) => {
90
+ listener(stateToString(state));
91
+ }, emitCurrentState);
92
+ }
93
+
94
+ // Device scanning with compatibility wrappers
95
+ async startDeviceScan(
96
+ uuids: UUID[] | null,
97
+ options: ScanOptions | null,
98
+ listener: (error: any | null, scannedDevice: DeviceWrapper | null) => void
99
+ ): Promise<void> {
100
+ return await this.bleManager.startDeviceScan(uuids, options, (error, device) => {
101
+ listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
102
+ });
103
+ }
104
+
105
+ async stopDeviceScan(): Promise<void> {
106
+ return await this.bleManager.stopDeviceScan();
107
+ }
108
+
109
+ // Connection management
110
+ async connectToDevice(
111
+ deviceIdentifier: DeviceId,
112
+ options?: Partial<ConnectionOptions>
113
+ ): Promise<DeviceWrapper> {
114
+ // Provide defaults for Nitro's required fields
115
+ const connectionOptions: ConnectionOptions = {
116
+ autoConnect: options?.autoConnect ?? false,
117
+ requestMTU: options?.requestMTU ?? 23,
118
+ timeout: options?.timeout ?? 0,
119
+ };
120
+
121
+ const result = await this.bleManager.connectToDevice(deviceIdentifier, connectionOptions);
122
+ return new DeviceWrapper(this.createDeviceFromNative(result));
123
+ }
124
+
125
+ async cancelDeviceConnection(deviceIdentifier: DeviceId): Promise<DeviceWrapper> {
126
+ const result = await this.bleManager.cancelDeviceConnection(deviceIdentifier);
127
+ return new DeviceWrapper(this.createDeviceFromNative(result));
128
+ }
129
+
130
+ async isDeviceConnected(deviceIdentifier: DeviceId): Promise<boolean> {
131
+ return await this.bleManager.isDeviceConnected(deviceIdentifier);
132
+ }
133
+
134
+ onDeviceDisconnected(
135
+ deviceIdentifier: DeviceId,
136
+ listener: (error: any | null, device: DeviceWrapper | null) => void
137
+ ): Subscription {
138
+ return this.bleManager.onDeviceDisconnected(deviceIdentifier, (error, device) => {
139
+ listener(error, device ? new DeviceWrapper(this.createDeviceFromNative(device)) : null);
140
+ });
141
+ }
142
+
143
+ // Device discovery
144
+ async devices(deviceIdentifiers: DeviceId[]): Promise<DeviceWrapper[]> {
145
+ const result = await this.bleManager.devices(deviceIdentifiers);
146
+ return result.map(device => new DeviceWrapper(this.createDeviceFromNative(device)));
147
+ }
148
+
149
+ async connectedDevices(serviceUUIDs: UUID[]): Promise<DeviceWrapper[]> {
150
+ const result = await this.bleManager.connectedDevices(serviceUUIDs);
151
+ return result.map(device => new DeviceWrapper(this.createDeviceFromNative(device)));
152
+ }
153
+
154
+ // RSSI and MTU operations
155
+ async readRSSIForDevice(
156
+ deviceIdentifier: DeviceId,
157
+ transactionId?: TransactionId
158
+ ): Promise<DeviceWrapper> {
159
+ const result = await this.bleManager.readRSSIForDevice(deviceIdentifier, transactionId);
160
+ return new DeviceWrapper(this.createDeviceFromNative(result));
161
+ }
162
+
163
+ async requestMTUForDevice(
164
+ deviceIdentifier: DeviceId,
165
+ mtu: number,
166
+ transactionId?: TransactionId
167
+ ): Promise<DeviceWrapper> {
168
+ const result = await this.bleManager.requestMTUForDevice(deviceIdentifier, mtu, transactionId);
169
+ return new DeviceWrapper(this.createDeviceFromNative(result));
170
+ }
171
+
172
+ async requestConnectionPriorityForDevice(
173
+ deviceIdentifier: DeviceId,
174
+ connectionPriority: ConnectionPriority,
175
+ transactionId?: TransactionId
176
+ ): Promise<DeviceWrapper> {
177
+ const result = await this.bleManager.requestConnectionPriorityForDevice(
178
+ deviceIdentifier,
179
+ connectionPriority,
180
+ transactionId
181
+ );
182
+ return new DeviceWrapper(this.createDeviceFromNative(result));
183
+ }
184
+
185
+ // Service discovery
186
+ async discoverAllServicesAndCharacteristicsForDevice(
187
+ deviceIdentifier: DeviceId,
188
+ transactionId?: TransactionId
189
+ ): Promise<DeviceWrapper> {
190
+ const result = await this.bleManager.discoverAllServicesAndCharacteristicsForDevice(
191
+ deviceIdentifier,
192
+ transactionId
193
+ );
194
+ return new DeviceWrapper(this.createDeviceFromNative(result));
195
+ }
196
+
197
+ // Service operations
198
+ async servicesForDevice(deviceIdentifier: DeviceId): Promise<NativeService[]> {
199
+ return await this.bleManager.servicesForDevice(deviceIdentifier);
200
+ }
201
+
202
+ // Characteristic operations
203
+ async characteristicsForDevice(
204
+ deviceIdentifier: DeviceId,
205
+ serviceUUID: UUID
206
+ ): Promise<NativeCharacteristic[]> {
207
+ return await this.bleManager.characteristicsForDevice(deviceIdentifier, serviceUUID);
208
+ }
209
+
210
+ async readCharacteristicForDevice(
211
+ deviceIdentifier: DeviceId,
212
+ serviceUUID: UUID,
213
+ characteristicUUID: UUID,
214
+ transactionId?: TransactionId
215
+ ): Promise<NativeCharacteristic> {
216
+ return await this.bleManager.readCharacteristicForDevice(
217
+ deviceIdentifier,
218
+ serviceUUID,
219
+ characteristicUUID,
220
+ transactionId
221
+ );
222
+ }
223
+
224
+ async writeCharacteristicWithResponseForDevice(
225
+ deviceIdentifier: DeviceId,
226
+ serviceUUID: UUID,
227
+ characteristicUUID: UUID,
228
+ base64Value: string,
229
+ transactionId?: TransactionId
230
+ ): Promise<NativeCharacteristic> {
231
+ return await this.bleManager.writeCharacteristicWithResponseForDevice(
232
+ deviceIdentifier,
233
+ serviceUUID,
234
+ characteristicUUID,
235
+ base64Value,
236
+ transactionId
237
+ );
238
+ }
239
+
240
+ async writeCharacteristicWithoutResponseForDevice(
241
+ deviceIdentifier: DeviceId,
242
+ serviceUUID: UUID,
243
+ characteristicUUID: UUID,
244
+ base64Value: string,
245
+ transactionId?: TransactionId
246
+ ): Promise<NativeCharacteristic> {
247
+ return await this.bleManager.writeCharacteristicWithoutResponseForDevice(
248
+ deviceIdentifier,
249
+ serviceUUID,
250
+ characteristicUUID,
251
+ base64Value,
252
+ transactionId
253
+ );
254
+ }
255
+
256
+ monitorCharacteristicForDevice(
257
+ deviceIdentifier: DeviceId,
258
+ serviceUUID: UUID,
259
+ characteristicUUID: UUID,
260
+ listener: (error: any | null, characteristic: NativeCharacteristic | null) => void,
261
+ transactionId?: TransactionId,
262
+ subscriptionType?: 'notification' | 'indication'
263
+ ): Subscription {
264
+ const nitroSubscriptionType = subscriptionType
265
+ ? normalizeCharacteristicSubscriptionType(subscriptionType)
266
+ : undefined;
267
+
268
+ return this.bleManager.monitorCharacteristicForDevice(
269
+ deviceIdentifier,
270
+ serviceUUID,
271
+ characteristicUUID,
272
+ listener,
273
+ transactionId,
274
+ nitroSubscriptionType
275
+ );
276
+ }
277
+
278
+ // Descriptor operations
279
+ async descriptorsForDevice(
280
+ deviceIdentifier: DeviceId,
281
+ serviceUUID: UUID,
282
+ characteristicUUID: UUID
283
+ ): Promise<NativeDescriptor[]> {
284
+ return await this.bleManager.descriptorsForDevice(
285
+ deviceIdentifier,
286
+ serviceUUID,
287
+ characteristicUUID
288
+ );
289
+ }
290
+
291
+ async readDescriptorForDevice(
292
+ deviceIdentifier: DeviceId,
293
+ serviceUUID: UUID,
294
+ characteristicUUID: UUID,
295
+ descriptorUUID: UUID,
296
+ transactionId?: TransactionId
297
+ ): Promise<NativeDescriptor> {
298
+ return await this.bleManager.readDescriptorForDevice(
299
+ deviceIdentifier,
300
+ serviceUUID,
301
+ characteristicUUID,
302
+ descriptorUUID,
303
+ transactionId
304
+ );
305
+ }
306
+
307
+ async writeDescriptorForDevice(
308
+ deviceIdentifier: DeviceId,
309
+ serviceUUID: UUID,
310
+ characteristicUUID: UUID,
311
+ descriptorUUID: UUID,
312
+ valueBase64: string,
313
+ transactionId?: TransactionId
314
+ ): Promise<NativeDescriptor> {
315
+ return await this.bleManager.writeDescriptorForDevice(
316
+ deviceIdentifier,
317
+ serviceUUID,
318
+ characteristicUUID,
319
+ descriptorUUID,
320
+ valueBase64,
321
+ transactionId
322
+ );
323
+ }
324
+
325
+ /**
326
+ * Helper method to create a Device wrapper from NativeDevice data
327
+ * This is a temporary method until we have proper Device Nitro objects
328
+ */
329
+ private createDeviceFromNative(nativeDevice: NativeDevice): any {
330
+ // This is a placeholder - in the actual implementation, we'd need to create
331
+ // proper Nitro Device objects, but for now we'll work with the native data
332
+ return {
333
+ id: nativeDevice.id,
334
+ deviceName: nativeDevice.name,
335
+ rssi: nativeDevice.rssi,
336
+ mtu: nativeDevice.mtu,
337
+ manufacturerData: nativeDevice.manufacturerData,
338
+ rawScanRecord: nativeDevice.rawScanRecord,
339
+ serviceData: nativeDevice.serviceData,
340
+ serviceUUIDs: nativeDevice.serviceUUIDs,
341
+ localName: nativeDevice.localName,
342
+ txPowerLevel: nativeDevice.txPowerLevel,
343
+ solicitedServiceUUIDs: nativeDevice.solicitedServiceUUIDs,
344
+ isConnectable: nativeDevice.isConnectable,
345
+ overflowServiceUUIDs: nativeDevice.overflowServiceUUIDs,
346
+ // Add placeholder methods - these would be implemented in the actual Device class
347
+ requestConnectionPriority: async () => this.createDeviceFromNative(nativeDevice),
348
+ readRSSI: async () => this.createDeviceFromNative(nativeDevice),
349
+ requestMTU: async () => this.createDeviceFromNative(nativeDevice),
350
+ connect: async () => this.createDeviceFromNative(nativeDevice),
351
+ cancelConnection: async () => this.createDeviceFromNative(nativeDevice),
352
+ isConnected: async () => false,
353
+ onDisconnected: () => ({ remove: () => {} }),
354
+ discoverAllServicesAndCharacteristics: async () => this.createDeviceFromNative(nativeDevice),
355
+ services: async () => [],
356
+ characteristicsForService: async () => [],
357
+ readCharacteristicForService: async () => ({}),
358
+ writeCharacteristicWithResponseForService: async () => ({}),
359
+ writeCharacteristicWithoutResponseForService: async () => ({}),
360
+ monitorCharacteristicForService: () => ({ remove: () => {} }),
361
+ descriptorsForService: async () => [],
362
+ readDescriptorForService: async () => ({}),
363
+ writeDescriptorForService: async () => ({}),
364
+ };
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Factory function to create a compatibility BleManager
370
+ */
371
+ export function createBleManagerCompat(options?: BleManagerOptions): BleManagerCompat {
372
+ return new BleManagerCompat(options);
373
+ }
@@ -0,0 +1,30 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ import type { BleManager as BleManagerInterface } from './specs/BleManager.nitro';
3
+ import type { BleManagerOptions } from './specs/types';
4
+
5
+ /**
6
+ * Creates a BleManager instance using Nitro Modules
7
+ * This function maintains compatibility with react-native-ble-plx's BleManager constructor
8
+ */
9
+ export function createBleManager(options?: BleManagerOptions): BleManagerInterface {
10
+ const BleManagerModule = NitroModules.createHybridObject<BleManagerInterface>('BleManager');
11
+
12
+ if (!BleManagerModule) {
13
+ throw new Error(
14
+ 'Failed to create BleManager: Nitro module not found. ' +
15
+ 'Make sure react-native-ble-nitro is properly installed and linked.'
16
+ );
17
+ }
18
+
19
+ // If options are provided, we could initialize with them
20
+ // For now, we return the module directly as Nitro handles the native initialization
21
+ return BleManagerModule;
22
+ }
23
+
24
+ /**
25
+ * Legacy compatibility: Export a BleManager constructor function
26
+ * This maintains compatibility with code that imports { BleManager } from 'react-native-ble-plx'
27
+ */
28
+ export const BleManager = function(options?: BleManagerOptions): BleManagerInterface {
29
+ return createBleManager(options);
30
+ } as any;