munim-bluetooth 0.4.1 → 0.4.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.4.3](https://github.com/munimtechnologies/munim-bluetooth/compare/v0.4.2...v0.4.3) (2026-05-22)
2
+
3
+ ### 🐛 Bug Fixes
4
+
5
+ * stabilize Bluetooth device smoke test ([3463a06](https://github.com/munimtechnologies/munim-bluetooth/commit/3463a069ce18893bc509944e8fb68d05a178ccd8))
6
+
1
7
  ## [0.4.1](https://github.com/munimtechnologies/munim-bluetooth/compare/v0.4.0...v0.4.1) (2026-05-16)
2
8
 
3
9
  ### 📚 Documentation
@@ -35,6 +35,7 @@ import android.content.pm.PackageManager
35
35
  import android.os.Build
36
36
  import android.os.ParcelUuid
37
37
  import android.util.Log
38
+ import androidx.annotation.Keep
38
39
  import com.facebook.react.bridge.Arguments
39
40
  import com.facebook.react.bridge.UiThreadUtil
40
41
  import com.facebook.react.bridge.WritableArray
@@ -42,6 +43,7 @@ import com.facebook.react.bridge.WritableMap
42
43
  import com.facebook.react.modules.core.DeviceEventManagerModule
43
44
  import com.facebook.react.modules.core.PermissionAwareActivity
44
45
  import com.facebook.react.modules.core.PermissionListener
46
+ import com.facebook.proguard.annotations.DoNotStrip
45
47
  import com.margelo.nitro.NitroModules
46
48
  import com.margelo.nitro.core.Promise
47
49
  import com.margelo.nitro.munimbluetooth.AdvertisingDataTypes
@@ -77,6 +79,8 @@ import org.json.JSONObject
77
79
  import java.io.IOException
78
80
  import java.util.UUID
79
81
 
82
+ @Keep
83
+ @DoNotStrip
80
84
  class HybridMunimBluetooth : HybridMunimBluetoothSpec() {
81
85
  private val bluetoothScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
82
86
 
@@ -1328,17 +1328,20 @@ class HybridMunimBluetooth: HybridMunimBluetoothSpec {
1328
1328
 
1329
1329
  private func hexStringToData(_ hex: String) -> Data? {
1330
1330
  var data = Data()
1331
- var hex = hex
1331
+ var hex = hex.trimmingCharacters(in: .whitespacesAndNewlines)
1332
1332
 
1333
1333
  if hex.count % 2 != 0 {
1334
1334
  hex = "0" + hex
1335
1335
  }
1336
1336
 
1337
- let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
1338
- regex.enumerateMatches(in: hex, range: NSRange(hex.startIndex..., in: hex)) { match, _, _ in
1339
- let byteStr = (hex as NSString).substring(with: match!.range)
1340
- let num = UInt8(byteStr, radix: 16)!
1341
- data.append(num)
1337
+ var index = hex.startIndex
1338
+ while index < hex.endIndex {
1339
+ let nextIndex = hex.index(index, offsetBy: 2)
1340
+ guard let byte = UInt8(hex[index..<nextIndex], radix: 16) else {
1341
+ return nil
1342
+ }
1343
+ data.append(byte)
1344
+ index = nextIndex
1342
1345
  }
1343
1346
 
1344
1347
  return data.isEmpty ? nil : data
@@ -1525,13 +1528,13 @@ class HybridMunimBluetooth: HybridMunimBluetoothSpec {
1525
1528
  advertisingData[CBAdvertisementDataLocalNameKey] = localName
1526
1529
  }
1527
1530
 
1528
- let serviceUUIDs =
1529
- (data.incompleteServiceUUIDs16 ?? []) +
1530
- (data.completeServiceUUIDs16 ?? []) +
1531
- (data.incompleteServiceUUIDs32 ?? []) +
1532
- (data.completeServiceUUIDs32 ?? []) +
1533
- (data.incompleteServiceUUIDs128 ?? []) +
1534
- (data.completeServiceUUIDs128 ?? [])
1531
+ var serviceUUIDs: [String] = []
1532
+ serviceUUIDs.append(contentsOf: data.incompleteServiceUUIDs16 ?? [])
1533
+ serviceUUIDs.append(contentsOf: data.completeServiceUUIDs16 ?? [])
1534
+ serviceUUIDs.append(contentsOf: data.incompleteServiceUUIDs32 ?? [])
1535
+ serviceUUIDs.append(contentsOf: data.completeServiceUUIDs32 ?? [])
1536
+ serviceUUIDs.append(contentsOf: data.incompleteServiceUUIDs128 ?? [])
1537
+ serviceUUIDs.append(contentsOf: data.completeServiceUUIDs128 ?? [])
1535
1538
 
1536
1539
  if !serviceUUIDs.isEmpty {
1537
1540
  advertisingData[CBAdvertisementDataServiceUUIDsKey] = serviceUUIDs.map { CBUUID(string: $0) }
@@ -14,7 +14,7 @@ RCT_EXTERN_METHOD(supportedEvents)
14
14
 
15
15
  + (BOOL)requiresMainQueueSetup
16
16
  {
17
- return NO;
17
+ return YES;
18
18
  }
19
19
 
20
20
  @end
@@ -13,11 +13,11 @@ class MunimBluetoothEventEmitter: RCTEventEmitter {
13
13
 
14
14
  public static var shared: MunimBluetoothEventEmitter?
15
15
  private static var pendingEvents: [(name: String, body: [String: Any])] = []
16
+ private var hasListeners = false
16
17
 
17
18
  override init() {
18
19
  super.init()
19
20
  MunimBluetoothEventEmitter.shared = self
20
- MunimBluetoothEventEmitter.flushPendingEvents()
21
21
  }
22
22
 
23
23
  override func supportedEvents() -> [String]! {
@@ -33,6 +33,13 @@ class MunimBluetoothEventEmitter: RCTEventEmitter {
33
33
  "connectionStateChanged",
34
34
  "servicesDiscovered",
35
35
  "characteristicValueChanged",
36
+ "l2capChannelPublished",
37
+ "l2capChannelPublishFailed",
38
+ "l2capChannelUnpublished",
39
+ "l2capChannelOpened",
40
+ "l2capChannelOpenFailed",
41
+ "l2capChannelClosed",
42
+ "l2capDataReceived",
36
43
  "peripheralReadRequest",
37
44
  "peripheralWriteRequest",
38
45
  "peripheralSubscribed",
@@ -56,6 +63,15 @@ class MunimBluetoothEventEmitter: RCTEventEmitter {
56
63
  return true
57
64
  }
58
65
 
66
+ override func startObserving() {
67
+ hasListeners = true
68
+ MunimBluetoothEventEmitter.flushPendingEvents()
69
+ }
70
+
71
+ override func stopObserving() {
72
+ hasListeners = false
73
+ }
74
+
59
75
  func emitDeviceFound(_ deviceData: [String: Any]) {
60
76
  emitOnMain("deviceFound", body: deviceData)
61
77
  emitOnMain("onDeviceFound", body: deviceData)
@@ -63,11 +79,16 @@ class MunimBluetoothEventEmitter: RCTEventEmitter {
63
79
  }
64
80
 
65
81
  func emit(_ eventName: String, body: [String: Any]) {
82
+ guard hasListeners else {
83
+ MunimBluetoothEventEmitter.pendingEvents.append((name: eventName, body: body))
84
+ return
85
+ }
86
+
66
87
  emitOnMain(eventName, body: body)
67
88
  }
68
89
 
69
90
  static func emitOrQueue(_ eventName: String, body: [String: Any]) {
70
- guard let shared else {
91
+ guard let shared, shared.hasListeners else {
71
92
  pendingEvents.append((name: eventName, body: body))
72
93
  return
73
94
  }
@@ -76,7 +97,7 @@ class MunimBluetoothEventEmitter: RCTEventEmitter {
76
97
  }
77
98
 
78
99
  private static func flushPendingEvents() {
79
- guard let shared, !pendingEvents.isEmpty else {
100
+ guard let shared, shared.hasListeners, !pendingEvents.isEmpty else {
80
101
  return
81
102
  }
82
103
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "munim-bluetooth",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "A comprehensive React Native Bluetooth library for BLE central/peripheral, Android Classic Bluetooth, LE L2CAP, Apple Multipeer Connectivity, and Expo support",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",