react-native-ble-nitro 1.3.0 → 1.4.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.
Files changed (37) hide show
  1. package/README.md +32 -10
  2. package/android/src/main/java/com/margelo/nitro/co/zyke/ble/BleNitroBleManager.kt +6 -0
  3. package/ios/BleNitroBleManager.swift +84 -2
  4. package/lib/commonjs/index.d.ts +4 -188
  5. package/lib/commonjs/index.d.ts.map +1 -1
  6. package/lib/commonjs/index.js +6 -441
  7. package/lib/commonjs/index.js.map +1 -1
  8. package/lib/commonjs/manager.d.ts +204 -0
  9. package/lib/commonjs/manager.d.ts.map +1 -0
  10. package/lib/commonjs/manager.js +469 -0
  11. package/lib/commonjs/manager.js.map +1 -0
  12. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts +2 -0
  13. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts.map +1 -1
  14. package/lib/index.d.ts +4 -188
  15. package/lib/index.js +3 -436
  16. package/lib/manager.d.ts +203 -0
  17. package/lib/manager.js +455 -0
  18. package/lib/specs/NativeBleNitro.nitro.d.ts +2 -0
  19. package/nitrogen/generated/android/BleNitroOnLoad.cpp +2 -0
  20. package/nitrogen/generated/android/c++/JFunc_void_std__vector_BLEDevice_.hpp +102 -0
  21. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.cpp +6 -1
  22. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.hpp +1 -0
  23. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Func_void_std__vector_BLEDevice_.kt +81 -0
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroSpec.kt +9 -0
  25. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.cpp +8 -0
  26. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.hpp +38 -16
  27. package/nitrogen/generated/ios/c++/HybridNativeBleNitroSpecSwift.hpp +15 -9
  28. package/nitrogen/generated/ios/swift/Func_void_std__vector_BLEDevice_.swift +47 -0
  29. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec.swift +1 -0
  30. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec_cxx.swift +22 -0
  31. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.cpp +1 -0
  32. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.hpp +6 -5
  33. package/package.json +9 -1
  34. package/src/__tests__/index.test.ts +24 -21
  35. package/src/index.ts +24 -600
  36. package/src/manager.ts +627 -0
  37. package/src/specs/NativeBleNitro.nitro.ts +4 -0
package/src/index.ts CHANGED
@@ -1,606 +1,30 @@
1
- import BleNitroNative from './specs/NativeBleNitro';
2
- import {
3
- ScanFilter as NativeScanFilter,
4
- BLEDevice as NativeBLEDevice,
5
- BLEState as NativeBLEState,
6
- ScanCallback as NativeScanCallback,
7
- AndroidScanMode as NativeAndroidScanMode,
8
- } from './specs/NativeBleNitro';
9
-
10
-
11
- export interface ScanFilter {
12
- serviceUUIDs?: string[];
13
- rssiThreshold?: number;
14
- allowDuplicates?: boolean;
15
- androidScanMode?: AndroidScanMode;
16
- }
17
-
18
- export interface ManufacturerDataEntry {
19
- id: string;
20
- data: ArrayBuffer;
21
- }
22
-
23
- export interface ManufacturerData {
24
- companyIdentifiers: ManufacturerDataEntry[];
25
- }
26
-
27
- export interface BLEDevice {
28
- id: string;
29
- name: string;
30
- rssi: number;
31
- manufacturerData: ManufacturerData;
32
- serviceUUIDs: string[];
33
- isConnectable: boolean;
34
- }
35
-
36
- export type ScanCallback = (device: BLEDevice) => void;
37
- export type ConnectionCallback = (
38
- success: boolean,
39
- deviceId: string,
40
- error: string
41
- ) => void;
42
- export type DisconnectEventCallback = (
43
- deviceId: string,
44
- interrupted: boolean,
45
- error: string
46
- ) => void;
47
- export type OperationCallback = (success: boolean, error: string) => void;
48
- export type CharacteristicUpdateCallback = (
49
- characteristicId: string,
50
- data: ArrayBuffer
51
- ) => void;
52
-
53
- export type Subscription = {
54
- remove: () => void;
55
- };
56
-
57
- export enum BLEState {
58
- Unknown = 'Unknown',
59
- Resetting = 'Resetting',
60
- Unsupported = 'Unsupported',
61
- Unauthorized = 'Unauthorized',
62
- PoweredOff = 'PoweredOff',
63
- PoweredOn = 'PoweredOn',
64
- };
65
-
66
- export enum AndroidScanMode {
67
- LowLatency = 'LowLatency',
68
- Balanced = 'Balanced',
69
- LowPower = 'LowPower',
70
- Opportunistic = 'Opportunistic',
71
- }
72
-
73
- function mapNativeBLEStateToBLEState(nativeState: NativeBLEState): BLEState {
74
- const map = {
75
- 0: BLEState.Unknown,
76
- 1: BLEState.Resetting,
77
- 2: BLEState.Unsupported,
78
- 3: BLEState.Unauthorized,
79
- 4: BLEState.PoweredOff,
80
- 5: BLEState.PoweredOn,
81
- };
82
- return map[nativeState];
83
- }
84
-
85
- function mapAndroidScanModeToNativeAndroidScanMode(scanMode: AndroidScanMode): NativeAndroidScanMode {
86
- const map = {
87
- LowLatency: NativeAndroidScanMode.LowLatency,
88
- Balanced: NativeAndroidScanMode.Balanced,
89
- LowPower: NativeAndroidScanMode.LowPower,
90
- Opportunistic: NativeAndroidScanMode.Opportunistic,
91
- }
92
- return map[scanMode];
93
- }
94
-
95
-
96
- let _instance: BleNitro;
97
-
98
- export class BleNitro {
99
- private _isScanning: boolean = false;
100
- private _connectedDevices: { [deviceId: string]: boolean } = {};
101
-
102
- public static instance(): BleNitro {
1
+ import { BleNitroManager } from "./manager";
2
+
3
+ export {
4
+ type ByteArray,
5
+ type ScanFilter,
6
+ type BLEDevice,
7
+ type ScanCallback,
8
+ type ManufacturerDataEntry,
9
+ type ManufacturerData,
10
+ type ConnectionCallback,
11
+ type DisconnectEventCallback,
12
+ type OperationCallback,
13
+ type CharacteristicUpdateCallback,
14
+ type Subscription,
15
+ type BleNitroManager,
16
+ type BleNitroManagerOptions,
17
+ BLEState,
18
+ AndroidScanMode,
19
+ } from "./manager";
20
+
21
+ let _instance: BleNitroManager;
22
+
23
+ export class BleNitro extends BleNitroManager {
24
+ public static instance() {
103
25
  if (!_instance) {
104
26
  _instance = new BleNitro();
105
27
  }
106
28
  return _instance;
107
29
  }
108
-
109
- /**
110
- * Converts a 16- oder 32-Bit UUID to a 128-Bit UUID
111
- *
112
- * @param uuid 16-, 32- or 128-Bit UUID as string
113
- * @returns Full 128-Bit UUID
114
- */
115
- public static normalizeGattUUID(uuid: string): string {
116
- const cleanUuid = uuid.toLowerCase();
117
-
118
- // 128-Bit UUID → normalisieren
119
- if (cleanUuid.length === 36 && cleanUuid.includes("-")) {
120
- return cleanUuid;
121
- }
122
-
123
- // GATT-Service UUIDs
124
- // 16- oder 32-Bit UUID → 128-Bit UUID
125
- const padded = cleanUuid.padStart(8, "0");
126
- return `${padded}-0000-1000-8000-00805f9b34fb`;
127
- }
128
-
129
- public static normalizeGattUUIDs(uuids: string[]): string[] {
130
- return uuids.map((uuid) => BleNitro.normalizeGattUUID(uuid));
131
- }
132
-
133
- /**
134
- * Start scanning for Bluetooth devices
135
- * @param filter Optional scan filter
136
- * @param callback Callback function called when a device is found
137
- * @returns Promise resolving to success state
138
- */
139
- public startScan(
140
- filter: ScanFilter = {},
141
- callback: ScanCallback,
142
- onError?: (error: string) => void,
143
- ): void {
144
- if (this._isScanning) {
145
- return;
146
- }
147
-
148
- // Create native scan filter with defaults
149
- const nativeFilter: NativeScanFilter = {
150
- serviceUUIDs: filter.serviceUUIDs || [],
151
- rssiThreshold: filter.rssiThreshold ?? -100,
152
- allowDuplicates: filter.allowDuplicates ?? false,
153
- androidScanMode: mapAndroidScanModeToNativeAndroidScanMode(filter.androidScanMode ?? AndroidScanMode.Balanced),
154
- };
155
-
156
- // Create callback wrapper
157
- const scanCallback: NativeScanCallback = (device: NativeBLEDevice | null, error: string | null) => {
158
- if (error && !device) {
159
- this._isScanning = false;
160
- onError?.(error);
161
- return;
162
- }
163
- device = device!; // eslint-disable-line @typescript-eslint/no-non-null-assertion
164
- // Convert manufacturer data to Uint8Arrays
165
- const convertedDevice: BLEDevice = {
166
- ...device,
167
- serviceUUIDs: BleNitro.normalizeGattUUIDs(device.serviceUUIDs),
168
- manufacturerData: {
169
- companyIdentifiers: device.manufacturerData.companyIdentifiers.map(entry => ({
170
- id: entry.id,
171
- data: entry.data
172
- }))
173
- }
174
- };
175
- callback(convertedDevice);
176
- };
177
-
178
- // Start scan
179
- BleNitroNative.startScan(nativeFilter, scanCallback);
180
- this._isScanning = true;
181
- }
182
-
183
- /**
184
- * Stop scanning for Bluetooth devices
185
- * @returns Promise resolving to success state
186
- */
187
- public stopScan(): void {
188
- if (!this._isScanning) {
189
- return;
190
- }
191
-
192
- BleNitroNative.stopScan();
193
- this._isScanning = false;
194
- }
195
-
196
- /**
197
- * Check if currently scanning for devices
198
- * @returns Promise resolving to scanning state
199
- */
200
- public isScanning(): boolean {
201
- this._isScanning = BleNitroNative.isScanning();
202
- return this._isScanning;
203
- }
204
-
205
- /**
206
- * Get all currently connected devices
207
- * @param services Optional list of service UUIDs to filter by
208
- * @returns Array of connected devices
209
- */
210
- public getConnectedDevices(services?: string[]): BLEDevice[] {
211
- const devices = BleNitroNative.getConnectedDevices(services || []);
212
- // Normalize service UUIDs - manufacturer data already comes as ArrayBuffers
213
- return devices.map(device => ({
214
- ...device,
215
- serviceUUIDs: BleNitro.normalizeGattUUIDs(device.serviceUUIDs),
216
- manufacturerData: {
217
- companyIdentifiers: device.manufacturerData.companyIdentifiers.map(entry => ({
218
- id: entry.id,
219
- data: entry.data
220
- }))
221
- }
222
- }));
223
- }
224
-
225
- /**
226
- * Connect to a Bluetooth device
227
- * @param deviceId ID of the device to connect to
228
- * @param onDisconnect Optional callback for disconnect events
229
- * @returns Promise resolving when connected
230
- */
231
- public connect(
232
- deviceId: string,
233
- onDisconnect?: DisconnectEventCallback
234
- ): Promise<string> {
235
- return new Promise((resolve, reject) => {
236
- // Check if already connected
237
- if (this._connectedDevices[deviceId]) {
238
- resolve(deviceId);
239
- return;
240
- }
241
-
242
- BleNitroNative.connect(
243
- deviceId,
244
- (success: boolean, connectedDeviceId: string, error: string) => {
245
- if (success) {
246
- this._connectedDevices[deviceId] = true;
247
- resolve(connectedDeviceId);
248
- } else {
249
- reject(new Error(error));
250
- }
251
- },
252
- onDisconnect ? (deviceId: string, interrupted: boolean, error: string) => {
253
- // Remove from connected devices when disconnected
254
- delete this._connectedDevices[deviceId];
255
- onDisconnect(deviceId, interrupted, error);
256
- } : undefined
257
- );
258
- });
259
- }
260
-
261
- /**
262
- * Disconnect from a Bluetooth device
263
- * @param deviceId ID of the device to disconnect from
264
- * @returns Promise resolving when disconnected
265
- */
266
- public disconnect(deviceId: string): Promise<void> {
267
- return new Promise((resolve, reject) => {
268
- // Check if already disconnected
269
- if (!this._connectedDevices[deviceId]) {
270
- resolve();
271
- return;
272
- }
273
-
274
- BleNitroNative.disconnect(
275
- deviceId,
276
- (success: boolean, error: string) => {
277
- if (success) {
278
- delete this._connectedDevices[deviceId];
279
- resolve();
280
- } else {
281
- reject(new Error(error));
282
- }
283
- }
284
- );
285
- });
286
- }
287
-
288
- /**
289
- * Check if connected to a device
290
- * @param deviceId ID of the device to check
291
- * @returns Promise resolving to connection state
292
- */
293
- public isConnected(deviceId: string): boolean {
294
- return BleNitroNative.isConnected(deviceId);
295
- }
296
-
297
- /**
298
- * Request a new MTU size
299
- * @param deviceId ID of the device
300
- * @param mtu New MTU size, min is 23, max is 517
301
- * @returns On Android: new MTU size; on iOS: current MTU size as it is handled by iOS itself; on error: -1
302
- */
303
- public requestMTU(deviceId: string, mtu: number): number {
304
- mtu = parseInt(mtu.toString(), 10);
305
- const deviceMtu = BleNitroNative.requestMTU(deviceId, mtu);
306
- return deviceMtu;
307
- }
308
-
309
- /**
310
- * Discover services for a connected device
311
- * @param deviceId ID of the device
312
- * @returns Promise resolving when services are discovered
313
- */
314
- public discoverServices(deviceId: string): Promise<boolean> {
315
- return new Promise((resolve, reject) => {
316
- // Check if connected first
317
- if (!this._connectedDevices[deviceId]) {
318
- reject(new Error('Device not connected'));
319
- return;
320
- }
321
-
322
- BleNitroNative.discoverServices(
323
- deviceId,
324
- (success: boolean, error: string) => {
325
- if (success) {
326
- resolve(true);
327
- } else {
328
- reject(new Error(error));
329
- }
330
- }
331
- );
332
- });
333
- }
334
-
335
- /**
336
- * Get services for a connected device
337
- * @param deviceId ID of the device
338
- * @returns Promise resolving to array of service UUIDs
339
- */
340
- public getServices(deviceId: string): Promise<string[]> {
341
- return new Promise(async (resolve, reject) => {
342
- // Check if connected first
343
- if (!this._connectedDevices[deviceId]) {
344
- reject(new Error('Device not connected'));
345
- return;
346
- }
347
-
348
- const success = await this.discoverServices(deviceId);
349
- if (!success) {
350
- reject(new Error('Failed to discover services'));
351
- return;
352
- }
353
- const services = BleNitroNative.getServices(deviceId);
354
- resolve(BleNitro.normalizeGattUUIDs(services));
355
- });
356
- }
357
-
358
- /**
359
- * Get characteristics for a service
360
- * @param deviceId ID of the device
361
- * @param serviceId ID of the service
362
- * @returns Promise resolving to array of characteristic UUIDs
363
- */
364
- public getCharacteristics(
365
- deviceId: string,
366
- serviceId: string
367
- ): string[] {
368
- if (!this._connectedDevices[deviceId]) {
369
- throw new Error('Device not connected');
370
- }
371
-
372
- const characteristics = BleNitroNative.getCharacteristics(
373
- deviceId,
374
- BleNitro.normalizeGattUUID(serviceId),
375
- );
376
- return BleNitro.normalizeGattUUIDs(characteristics);
377
- }
378
-
379
- /**
380
- * Read a characteristic value
381
- * @param deviceId ID of the device
382
- * @param serviceId ID of the service
383
- * @param characteristicId ID of the characteristic
384
- * @returns Promise resolving to the characteristic data as ArrayBuffer
385
- */
386
- public readCharacteristic(
387
- deviceId: string,
388
- serviceId: string,
389
- characteristicId: string
390
- ): Promise<ArrayBuffer> {
391
- return new Promise((resolve, reject) => {
392
- // Check if connected first
393
- if (!this._connectedDevices[deviceId]) {
394
- reject(new Error('Device not connected'));
395
- return;
396
- }
397
-
398
- BleNitroNative.readCharacteristic(
399
- deviceId,
400
- BleNitro.normalizeGattUUID(serviceId),
401
- BleNitro.normalizeGattUUID(characteristicId),
402
- (success: boolean, data: ArrayBuffer, error: string) => {
403
- if (success) {
404
- resolve(data);
405
- } else {
406
- reject(new Error(error));
407
- }
408
- }
409
- );
410
- });
411
- }
412
-
413
- /**
414
- * Write a value to a characteristic
415
- * @param deviceId ID of the device
416
- * @param serviceId ID of the service
417
- * @param characteristicId ID of the characteristic
418
- * @param data Data to write as ArrayBuffer
419
- * @param withResponse Whether to wait for response
420
- * @returns Promise resolving when write is complete
421
- */
422
- public writeCharacteristic(
423
- deviceId: string,
424
- serviceId: string,
425
- characteristicId: string,
426
- data: ArrayBuffer,
427
- withResponse: boolean = true
428
- ): Promise<boolean> {
429
- return new Promise((resolve, reject) => {
430
- // Check if connected first
431
- if (!this._connectedDevices[deviceId]) {
432
- reject(new Error('Device not connected'));
433
- return;
434
- }
435
-
436
- BleNitroNative.writeCharacteristic(
437
- deviceId,
438
- BleNitro.normalizeGattUUID(serviceId),
439
- BleNitro.normalizeGattUUID(characteristicId),
440
- data,
441
- withResponse,
442
- (success: boolean, error: string) => {
443
- if (success) {
444
- resolve(true);
445
- } else {
446
- reject(new Error(error));
447
- }
448
- }
449
- );
450
- });
451
- }
452
-
453
- /**
454
- * Subscribe to characteristic notifications
455
- * @param deviceId ID of the device
456
- * @param serviceId ID of the service
457
- * @param characteristicId ID of the characteristic
458
- * @param callback Callback function called when notification is received
459
- * @returns Promise resolving when subscription is complete
460
- */
461
- public subscribeToCharacteristic(
462
- deviceId: string,
463
- serviceId: string,
464
- characteristicId: string,
465
- callback: CharacteristicUpdateCallback
466
- ): Subscription {
467
- // Check if connected first
468
- if (!this._connectedDevices[deviceId]) {
469
- throw new Error('Device not connected');
470
- }
471
-
472
- let _success = false;
473
-
474
- BleNitroNative.subscribeToCharacteristic(
475
- deviceId,
476
- BleNitro.normalizeGattUUID(serviceId),
477
- BleNitro.normalizeGattUUID(characteristicId),
478
- (charId: string, data: ArrayBuffer) => {
479
- callback(charId, data);
480
- },
481
- (success, error) => {
482
- _success = success;
483
- if (!success) {
484
- throw new Error(error);
485
- }
486
- }
487
- );
488
-
489
- return {
490
- remove: () => {
491
- if (!_success) {
492
- return;
493
- }
494
- this.unsubscribeFromCharacteristic(
495
- deviceId,
496
- serviceId,
497
- characteristicId
498
- ).catch(() => {});
499
- }
500
- };
501
- }
502
-
503
- /**
504
- * Unsubscribe from characteristic notifications
505
- * @param deviceId ID of the device
506
- * @param serviceId ID of the service
507
- * @param characteristicId ID of the characteristic
508
- * @returns Promise resolving when unsubscription is complete
509
- */
510
- public unsubscribeFromCharacteristic(
511
- deviceId: string,
512
- serviceId: string,
513
- characteristicId: string
514
- ): Promise<void> {
515
- return new Promise((resolve, reject) => {
516
- // Check if connected first
517
- if (!this._connectedDevices[deviceId]) {
518
- reject(new Error('Device not connected'));
519
- return;
520
- }
521
-
522
- BleNitroNative.unsubscribeFromCharacteristic(
523
- deviceId,
524
- BleNitro.normalizeGattUUID(serviceId),
525
- BleNitro.normalizeGattUUID(characteristicId),
526
- (success: boolean, error: string) => {
527
- if (success) {
528
- resolve();
529
- } else {
530
- reject(new Error(error));
531
- }
532
- }
533
- );
534
- });
535
- }
536
-
537
- /**
538
- * Check if Bluetooth is enabled
539
- * @returns Promise resolving to Bluetooth state
540
- */
541
- public isBluetoothEnabled(): boolean {
542
- return this.state() === BLEState.PoweredOn;
543
- }
544
-
545
- /**
546
- * Request to enable Bluetooth (Android only)
547
- * @returns Promise resolving when Bluetooth is enabled
548
- */
549
- public requestBluetoothEnable(): Promise<boolean> {
550
- return new Promise((resolve, reject) => {
551
- BleNitroNative.requestBluetoothEnable(
552
- (success: boolean, error: string) => {
553
- if (success) {
554
- resolve(true);
555
- } else {
556
- reject(new Error(error));
557
- }
558
- }
559
- );
560
- });
561
- }
562
-
563
- /**
564
- * Get the current Bluetooth state
565
- * @returns Promise resolving to Bluetooth state
566
- * @see BLEState
567
- */
568
- public state(): BLEState {
569
- return mapNativeBLEStateToBLEState(BleNitroNative.state());
570
- }
571
-
572
- /**
573
- * Subscribe to Bluetooth state changes
574
- * @param callback Callback function called when state changes
575
- * @param emitInitial Whether to emit initial state callback
576
- * @returns Promise resolving when subscription is complete
577
- * @see BLEState
578
- */
579
- public subscribeToStateChange(callback: (state: BLEState) => void, emitInitial = false): Subscription {
580
- if (emitInitial) {
581
- const state = this.state();
582
- callback(state);
583
- }
584
-
585
- BleNitroNative.subscribeToStateChange((nativeState: NativeBLEState) => {
586
- callback(mapNativeBLEStateToBLEState(nativeState));
587
- });
588
-
589
- return {
590
- remove: () => {
591
- BleNitroNative.unsubscribeFromStateChange();
592
- },
593
- };
594
- }
595
-
596
- /**
597
- * Open Bluetooth settings
598
- * @returns Promise resolving when settings are opened
599
- */
600
- public openSettings(): Promise<void> {
601
- return BleNitroNative.openSettings();
602
- }
603
30
  }
604
-
605
- // Singleton instance
606
- export const ble = BleNitro.instance();