unified-ble-manager 4.0.2 → 4.0.4
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 +31 -0
- package/MIGRATION_4.0.md +1 -1
- package/README.md +2 -1
- package/RELEASE.md +21 -5
- package/SBOM.cdx.json +4 -4
- package/THIRD_PARTY_LICENSES.json +1 -1
- package/android/build.gradle +2 -0
- package/android/src/main/java/com/sfourdrinier/unifiedblemanager/protocol/UnifiedBleProtocolControlModule.java +16 -0
- package/android/src/main/java/com/sfourdrinier/unifiedblemanager/radio/OwnedAndroidGattRadio.kt +26 -7
- package/android/src/main/jni/CMakeLists.txt +7 -0
- package/docs/ELECTRON.md +1 -1
- package/docs/EXPO_PLUGIN.md +2 -2
- package/docs/GAPS.4.0.md +1 -1
- package/docs/GETTING_STARTED.md +4 -4
- package/docs/NODE.md +1 -1
- package/docs/PLATFORMS.md +1 -1
- package/docs/WEB.md +1 -1
- package/docs/generated/PLATFORM_SUPPORT.md +1 -1
- package/ios/Owned/OwnedCoreBluetoothProtocolRadio.swift +14 -20
- package/ios/Owned/OwnedCoreBluetoothProtocolRadioCancellation.swift +87 -0
- package/ios/UnifiedBleProtocolControl.mm +22 -0
- package/lib/commonjs/NativeUnifiedBleProtocolControl.js.map +1 -1
- package/lib/commonjs/advanced.js +26 -8
- package/lib/commonjs/advanced.js.map +1 -1
- package/lib/commonjs/backend-contract/index.js +6 -0
- package/lib/commonjs/backend-contract/index.js.map +1 -1
- package/lib/commonjs/backend-contract/primitives.js +6 -0
- package/lib/commonjs/backend-contract/primitives.js.map +1 -1
- package/lib/commonjs/backend-contract/serializable.js +27 -2
- package/lib/commonjs/backend-contract/serializable.js.map +1 -1
- package/lib/commonjs/backends/bluez/bluez-backend-runtime.js +31 -9
- package/lib/commonjs/backends/bluez/bluez-backend-runtime.js.map +1 -1
- package/lib/commonjs/backends/bluez/bluez-backend.js +10 -0
- package/lib/commonjs/backends/bluez/bluez-backend.js.map +1 -1
- package/lib/commonjs/backends/bluez/bluez-security.js +20 -0
- package/lib/commonjs/backends/bluez/bluez-security.js.map +1 -1
- package/lib/commonjs/backends/corebluetooth/corebluetooth-backend.js +71 -24
- package/lib/commonjs/backends/corebluetooth/corebluetooth-backend.js.map +1 -1
- package/lib/commonjs/backends/corebluetooth/corebluetooth-gatt-operations.js +16 -4
- package/lib/commonjs/backends/corebluetooth/corebluetooth-gatt-operations.js.map +1 -1
- package/lib/commonjs/backends/reactnative/react-native-android-security.js +27 -3
- package/lib/commonjs/backends/reactnative/react-native-android-security.js.map +1 -1
- package/lib/commonjs/backends/winrt/winrt-backend.js +32 -36
- package/lib/commonjs/backends/winrt/winrt-backend.js.map +1 -1
- package/lib/commonjs/backends/winrt/winrt-security.js +30 -8
- package/lib/commonjs/backends/winrt/winrt-security.js.map +1 -1
- package/lib/commonjs/core/bounded-stream.js +4 -2
- package/lib/commonjs/core/bounded-stream.js.map +1 -1
- package/lib/commonjs/core/owned-bounded-stream.js +44 -0
- package/lib/commonjs/core/owned-bounded-stream.js.map +1 -0
- package/lib/commonjs/core/unified-ble-core.js +27 -6
- package/lib/commonjs/core/unified-ble-core.js.map +1 -1
- package/lib/commonjs/electron/main-router.js +19 -1
- package/lib/commonjs/electron/main-router.js.map +1 -1
- package/lib/commonjs/implementation-version.js +1 -1
- package/lib/commonjs/ipc/manager.js +441 -101
- package/lib/commonjs/ipc/manager.js.map +1 -1
- package/lib/commonjs/ipc/public-manager.js +7 -9
- package/lib/commonjs/ipc/public-manager.js.map +1 -1
- package/lib/commonjs/node-host-manager.js +3 -1
- package/lib/commonjs/node-host-manager.js.map +1 -1
- package/lib/commonjs/public/ble-manager.js +240 -80
- package/lib/commonjs/public/ble-manager.js.map +1 -1
- package/lib/commonjs/public/error-bridge.js +19 -0
- package/lib/commonjs/public/error-bridge.js.map +1 -1
- package/lib/commonjs/public/host-identity.js +5 -17
- package/lib/commonjs/public/host-identity.js.map +1 -1
- package/lib/commonjs/public/operation-options.js +18 -7
- package/lib/commonjs/public/operation-options.js.map +1 -1
- package/lib/commonjs/public/react-adapter-watch-inspect.js +20 -0
- package/lib/commonjs/public/react-adapter-watch-inspect.js.map +1 -0
- package/lib/commonjs/public/scan-state-budget.js +16 -0
- package/lib/commonjs/public/scan-state-budget.js.map +1 -0
- package/lib/commonjs/react-native-app-manager.js +5 -1
- package/lib/commonjs/react-native-app-manager.js.map +1 -1
- package/lib/commonjs/react-native-entropy.js +40 -0
- package/lib/commonjs/react-native-entropy.js.map +1 -0
- package/lib/commonjs/react.js +693 -137
- package/lib/commonjs/react.js.map +1 -1
- package/lib/commonjs/tauri/transport.js +119 -18
- package/lib/commonjs/tauri/transport.js.map +1 -1
- package/lib/commonjs/testing/deterministic/deterministic-backend-base.js +29 -10
- package/lib/commonjs/testing/deterministic/deterministic-backend-base.js.map +1 -1
- package/lib/commonjs/testing/deterministic/deterministic-security.js +39 -14
- package/lib/commonjs/testing/deterministic/deterministic-security.js.map +1 -1
- package/lib/commonjs/testing/deterministic/deterministic-test-backend-lifecycle-helpers.js +1 -1
- package/lib/commonjs/testing/deterministic/deterministic-test-backend-lifecycle-helpers.js.map +1 -1
- package/lib/commonjs/testing/deterministic/deterministic-test-backend.js +2 -4
- package/lib/commonjs/testing/deterministic/deterministic-test-backend.js.map +1 -1
- package/lib/commonjs/web/web-bluetooth-backend.js +63 -54
- package/lib/commonjs/web/web-bluetooth-backend.js.map +1 -1
- package/lib/commonjs/web/web-bluetooth-handles.js.map +1 -1
- package/lib/commonjs/web.js +3 -1
- package/lib/commonjs/web.js.map +1 -1
- package/lib/module/NativeUnifiedBleProtocolControl.js.map +1 -1
- package/lib/module/advanced.js +5 -0
- package/lib/module/advanced.js.map +1 -1
- package/lib/module/backend-contract/index.js +1 -1
- package/lib/module/backend-contract/index.js.map +1 -1
- package/lib/module/backend-contract/primitives.js +5 -0
- package/lib/module/backend-contract/primitives.js.map +1 -1
- package/lib/module/backend-contract/serializable.js +23 -2
- package/lib/module/backend-contract/serializable.js.map +1 -1
- package/lib/module/backends/bluez/bluez-backend-runtime.js +30 -9
- package/lib/module/backends/bluez/bluez-backend-runtime.js.map +1 -1
- package/lib/module/backends/bluez/bluez-backend.js +10 -1
- package/lib/module/backends/bluez/bluez-backend.js.map +1 -1
- package/lib/module/backends/bluez/bluez-security.js +19 -0
- package/lib/module/backends/bluez/bluez-security.js.map +1 -1
- package/lib/module/backends/corebluetooth/corebluetooth-backend.js +70 -24
- package/lib/module/backends/corebluetooth/corebluetooth-backend.js.map +1 -1
- package/lib/module/backends/corebluetooth/corebluetooth-gatt-operations.js +16 -4
- package/lib/module/backends/corebluetooth/corebluetooth-gatt-operations.js.map +1 -1
- package/lib/module/backends/reactnative/react-native-android-security.js +26 -3
- package/lib/module/backends/reactnative/react-native-android-security.js.map +1 -1
- package/lib/module/backends/winrt/winrt-backend.js +31 -36
- package/lib/module/backends/winrt/winrt-backend.js.map +1 -1
- package/lib/module/backends/winrt/winrt-security.js +29 -8
- package/lib/module/backends/winrt/winrt-security.js.map +1 -1
- package/lib/module/core/bounded-stream.js +4 -2
- package/lib/module/core/bounded-stream.js.map +1 -1
- package/lib/module/core/owned-bounded-stream.js +40 -0
- package/lib/module/core/owned-bounded-stream.js.map +1 -0
- package/lib/module/core/unified-ble-core.js +27 -6
- package/lib/module/core/unified-ble-core.js.map +1 -1
- package/lib/module/electron/main-router.js +19 -1
- package/lib/module/electron/main-router.js.map +1 -1
- package/lib/module/implementation-version.js +1 -1
- package/lib/module/ipc/manager.js +440 -101
- package/lib/module/ipc/manager.js.map +1 -1
- package/lib/module/ipc/public-manager.js +8 -10
- package/lib/module/ipc/public-manager.js.map +1 -1
- package/lib/module/node-host-manager.js +3 -1
- package/lib/module/node-host-manager.js.map +1 -1
- package/lib/module/public/ble-manager.js +238 -80
- package/lib/module/public/ble-manager.js.map +1 -1
- package/lib/module/public/error-bridge.js +18 -0
- package/lib/module/public/error-bridge.js.map +1 -1
- package/lib/module/public/host-identity.js +5 -17
- package/lib/module/public/host-identity.js.map +1 -1
- package/lib/module/public/operation-options.js +17 -7
- package/lib/module/public/operation-options.js.map +1 -1
- package/lib/module/public/react-adapter-watch-inspect.js +15 -0
- package/lib/module/public/react-adapter-watch-inspect.js.map +1 -0
- package/lib/module/public/scan-state-budget.js +11 -0
- package/lib/module/public/scan-state-budget.js.map +1 -0
- package/lib/module/react-native-app-manager.js +5 -1
- package/lib/module/react-native-app-manager.js.map +1 -1
- package/lib/module/react-native-entropy.js +35 -0
- package/lib/module/react-native-entropy.js.map +1 -0
- package/lib/module/react.js +693 -137
- package/lib/module/react.js.map +1 -1
- package/lib/module/tauri/transport.js +118 -17
- package/lib/module/tauri/transport.js.map +1 -1
- package/lib/module/testing/deterministic/deterministic-backend-base.js +28 -10
- package/lib/module/testing/deterministic/deterministic-backend-base.js.map +1 -1
- package/lib/module/testing/deterministic/deterministic-security.js +38 -14
- package/lib/module/testing/deterministic/deterministic-security.js.map +1 -1
- package/lib/module/testing/deterministic/deterministic-test-backend-lifecycle-helpers.js +1 -1
- package/lib/module/testing/deterministic/deterministic-test-backend-lifecycle-helpers.js.map +1 -1
- package/lib/module/testing/deterministic/deterministic-test-backend.js +2 -4
- package/lib/module/testing/deterministic/deterministic-test-backend.js.map +1 -1
- package/lib/module/web/web-bluetooth-backend.js +63 -54
- package/lib/module/web/web-bluetooth-backend.js.map +1 -1
- package/lib/module/web/web-bluetooth-handles.js.map +1 -1
- package/lib/module/web.js +3 -1
- package/lib/module/web.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeUnifiedBleProtocolControl.d.ts +2 -0
- package/lib/typescript/commonjs/src/NativeUnifiedBleProtocolControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/advanced.d.ts +5 -0
- package/lib/typescript/commonjs/src/advanced.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backend-contract/index.d.ts +1 -1
- package/lib/typescript/commonjs/src/backend-contract/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backend-contract/primitives.d.ts +2 -0
- package/lib/typescript/commonjs/src/backend-contract/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backend-contract/serializable.d.ts +4 -0
- package/lib/typescript/commonjs/src/backend-contract/serializable.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend-runtime.d.ts +5 -0
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend-runtime.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend.d.ts +2 -0
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/bluez/bluez-security.d.ts +5 -0
- package/lib/typescript/commonjs/src/backends/bluez/bluez-security.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/corebluetooth/corebluetooth-backend.d.ts +6 -0
- package/lib/typescript/commonjs/src/backends/corebluetooth/corebluetooth-backend.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/corebluetooth/corebluetooth-gatt-operations.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/corebluetooth/corebluetooth-identity.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/reactnative/react-native-android-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/reactnative/react-native-android-security.d.ts +5 -0
- package/lib/typescript/commonjs/src/backends/reactnative/react-native-android-security.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/reactnative/react-native-apple-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/winrt/winrt-backend.d.ts +5 -0
- package/lib/typescript/commonjs/src/backends/winrt/winrt-backend.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/backends/winrt/winrt-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/winrt/winrt-security.d.ts +5 -0
- package/lib/typescript/commonjs/src/backends/winrt/winrt-security.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/bounded-stream.d.ts +1 -0
- package/lib/typescript/commonjs/src/core/bounded-stream.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/core/owned-bounded-stream.d.ts +18 -0
- package/lib/typescript/commonjs/src/core/owned-bounded-stream.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/core/unified-ble-core.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/electron/main-router.d.ts +1 -0
- package/lib/typescript/commonjs/src/electron/main-router.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/implementation-version.d.ts +1 -1
- package/lib/typescript/commonjs/src/ipc/manager.d.ts +32 -4
- package/lib/typescript/commonjs/src/ipc/manager.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ipc/public-manager.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/public/ble-manager.d.ts +17 -4
- package/lib/typescript/commonjs/src/public/ble-manager.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/public/error-bridge.d.ts +6 -1
- package/lib/typescript/commonjs/src/public/error-bridge.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/public/host-identity.d.ts +5 -0
- package/lib/typescript/commonjs/src/public/host-identity.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/public/operation-options.d.ts +1 -0
- package/lib/typescript/commonjs/src/public/operation-options.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/public/react-adapter-watch-inspect.d.ts +9 -0
- package/lib/typescript/commonjs/src/public/react-adapter-watch-inspect.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/public/scan-state-budget.d.ts +15 -0
- package/lib/typescript/commonjs/src/public/scan-state-budget.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/react-native-app-manager.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/react-native-entropy.d.ts +3 -0
- package/lib/typescript/commonjs/src/react-native-entropy.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/react.d.ts +4 -2
- package/lib/typescript/commonjs/src/react.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/tauri/transport.d.ts +12 -0
- package/lib/typescript/commonjs/src/tauri/transport.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-backend-base.d.ts +8 -2
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-backend-base.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-security.d.ts +8 -2
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-security.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-test-backend-lifecycle-helpers.d.ts +6 -2
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-test-backend-lifecycle-helpers.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/testing/deterministic/deterministic-test-backend.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/web-bluetooth-backend.d.ts +4 -3
- package/lib/typescript/commonjs/src/web/web-bluetooth-backend.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/web-bluetooth-handles.d.ts +3 -0
- package/lib/typescript/commonjs/src/web/web-bluetooth-handles.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeUnifiedBleProtocolControl.d.ts +2 -0
- package/lib/typescript/module/src/NativeUnifiedBleProtocolControl.d.ts.map +1 -1
- package/lib/typescript/module/src/advanced.d.ts +5 -0
- package/lib/typescript/module/src/advanced.d.ts.map +1 -1
- package/lib/typescript/module/src/backend-contract/index.d.ts +1 -1
- package/lib/typescript/module/src/backend-contract/index.d.ts.map +1 -1
- package/lib/typescript/module/src/backend-contract/primitives.d.ts +2 -0
- package/lib/typescript/module/src/backend-contract/primitives.d.ts.map +1 -1
- package/lib/typescript/module/src/backend-contract/serializable.d.ts +4 -0
- package/lib/typescript/module/src/backend-contract/serializable.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/bluez/bluez-backend-provider.d.ts +1 -1
- package/lib/typescript/module/src/backends/bluez/bluez-backend-runtime.d.ts +5 -0
- package/lib/typescript/module/src/backends/bluez/bluez-backend-runtime.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/bluez/bluez-backend.d.ts +2 -0
- package/lib/typescript/module/src/backends/bluez/bluez-backend.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/bluez/bluez-security.d.ts +5 -0
- package/lib/typescript/module/src/backends/bluez/bluez-security.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/corebluetooth/corebluetooth-backend.d.ts +6 -0
- package/lib/typescript/module/src/backends/corebluetooth/corebluetooth-backend.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/corebluetooth/corebluetooth-gatt-operations.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/corebluetooth/corebluetooth-identity.d.ts +1 -1
- package/lib/typescript/module/src/backends/reactnative/react-native-android-provider.d.ts +1 -1
- package/lib/typescript/module/src/backends/reactnative/react-native-android-security.d.ts +5 -0
- package/lib/typescript/module/src/backends/reactnative/react-native-android-security.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/reactnative/react-native-apple-provider.d.ts +1 -1
- package/lib/typescript/module/src/backends/winrt/winrt-backend.d.ts +5 -0
- package/lib/typescript/module/src/backends/winrt/winrt-backend.d.ts.map +1 -1
- package/lib/typescript/module/src/backends/winrt/winrt-provider.d.ts +1 -1
- package/lib/typescript/module/src/backends/winrt/winrt-security.d.ts +5 -0
- package/lib/typescript/module/src/backends/winrt/winrt-security.d.ts.map +1 -1
- package/lib/typescript/module/src/core/bounded-stream.d.ts +1 -0
- package/lib/typescript/module/src/core/bounded-stream.d.ts.map +1 -1
- package/lib/typescript/module/src/core/owned-bounded-stream.d.ts +18 -0
- package/lib/typescript/module/src/core/owned-bounded-stream.d.ts.map +1 -0
- package/lib/typescript/module/src/core/unified-ble-core.d.ts.map +1 -1
- package/lib/typescript/module/src/electron/main-router.d.ts +1 -0
- package/lib/typescript/module/src/electron/main-router.d.ts.map +1 -1
- package/lib/typescript/module/src/implementation-version.d.ts +1 -1
- package/lib/typescript/module/src/ipc/manager.d.ts +32 -4
- package/lib/typescript/module/src/ipc/manager.d.ts.map +1 -1
- package/lib/typescript/module/src/ipc/public-manager.d.ts.map +1 -1
- package/lib/typescript/module/src/public/ble-manager.d.ts +17 -4
- package/lib/typescript/module/src/public/ble-manager.d.ts.map +1 -1
- package/lib/typescript/module/src/public/error-bridge.d.ts +6 -1
- package/lib/typescript/module/src/public/error-bridge.d.ts.map +1 -1
- package/lib/typescript/module/src/public/host-identity.d.ts +5 -0
- package/lib/typescript/module/src/public/host-identity.d.ts.map +1 -1
- package/lib/typescript/module/src/public/operation-options.d.ts +1 -0
- package/lib/typescript/module/src/public/operation-options.d.ts.map +1 -1
- package/lib/typescript/module/src/public/react-adapter-watch-inspect.d.ts +9 -0
- package/lib/typescript/module/src/public/react-adapter-watch-inspect.d.ts.map +1 -0
- package/lib/typescript/module/src/public/scan-state-budget.d.ts +15 -0
- package/lib/typescript/module/src/public/scan-state-budget.d.ts.map +1 -0
- package/lib/typescript/module/src/react-native-app-manager.d.ts.map +1 -1
- package/lib/typescript/module/src/react-native-entropy.d.ts +3 -0
- package/lib/typescript/module/src/react-native-entropy.d.ts.map +1 -0
- package/lib/typescript/module/src/react.d.ts +4 -2
- package/lib/typescript/module/src/react.d.ts.map +1 -1
- package/lib/typescript/module/src/tauri/transport.d.ts +12 -0
- package/lib/typescript/module/src/tauri/transport.d.ts.map +1 -1
- package/lib/typescript/module/src/testing/deterministic/deterministic-backend-base.d.ts +8 -2
- package/lib/typescript/module/src/testing/deterministic/deterministic-backend-base.d.ts.map +1 -1
- package/lib/typescript/module/src/testing/deterministic/deterministic-security.d.ts +8 -2
- package/lib/typescript/module/src/testing/deterministic/deterministic-security.d.ts.map +1 -1
- package/lib/typescript/module/src/testing/deterministic/deterministic-test-backend-lifecycle-helpers.d.ts +6 -2
- package/lib/typescript/module/src/testing/deterministic/deterministic-test-backend-lifecycle-helpers.d.ts.map +1 -1
- package/lib/typescript/module/src/testing/deterministic/deterministic-test-backend.d.ts.map +1 -1
- package/lib/typescript/module/src/web/web-bluetooth-backend.d.ts +4 -3
- package/lib/typescript/module/src/web/web-bluetooth-backend.d.ts.map +1 -1
- package/lib/typescript/module/src/web/web-bluetooth-handles.d.ts +3 -0
- package/lib/typescript/module/src/web/web-bluetooth-handles.d.ts.map +1 -1
- package/native/PREBUILDS.json +5 -5
- package/native/electron/corebluetooth/prebuilds/darwin-arm64/unified_ble_corebluetooth.node +0 -0
- package/native/electron/corebluetooth/prebuilds/darwin-x64/unified_ble_corebluetooth.node +0 -0
- package/native/electron/winrt/prebuilds/win32-arm64/unified_ble_winrt.node +0 -0
- package/native/electron/winrt/prebuilds/win32-x64/unified_ble_winrt.node +0 -0
- package/native/tauri/Cargo.toml +3 -0
- package/native/tauri/src/btleplug_dispatcher.rs +577 -37
- package/package.json +1 -1
- package/plugin/build/expoPluginSchema.js +4 -2
- package/src/NativeUnifiedBleProtocolControl.ts +2 -0
- package/src/advanced.ts +13 -0
- package/src/backend-contract/index.ts +1 -0
- package/src/backend-contract/primitives.ts +9 -0
- package/src/backend-contract/serializable.ts +33 -2
- package/src/backends/bluez/bluez-backend-runtime.ts +38 -8
- package/src/backends/bluez/bluez-backend.ts +16 -1
- package/src/backends/bluez/bluez-security.ts +30 -1
- package/src/backends/corebluetooth/corebluetooth-backend.ts +84 -27
- package/src/backends/corebluetooth/corebluetooth-gatt-operations.ts +21 -4
- package/src/backends/reactnative/react-native-android-security.ts +38 -2
- package/src/backends/winrt/winrt-backend.ts +40 -45
- package/src/backends/winrt/winrt-security.ts +38 -7
- package/src/core/bounded-stream.ts +4 -2
- package/src/core/owned-bounded-stream.ts +47 -0
- package/src/core/unified-ble-core.ts +40 -12
- package/src/electron/main-router.ts +18 -1
- package/src/implementation-version.ts +1 -1
- package/src/ipc/manager.ts +515 -138
- package/src/ipc/public-manager.ts +8 -3
- package/src/node-host-manager.ts +1 -1
- package/src/public/ble-manager.ts +321 -128
- package/src/public/error-bridge.ts +21 -2
- package/src/public/host-identity.ts +14 -20
- package/src/public/operation-options.ts +19 -3
- package/src/public/react-adapter-watch-inspect.ts +17 -0
- package/src/public/scan-state-budget.ts +16 -0
- package/src/react-native-app-manager.ts +4 -1
- package/src/react-native-entropy.ts +37 -0
- package/src/react.ts +795 -142
- package/src/tauri/transport.ts +147 -17
- package/src/testing/deterministic/deterministic-backend-base.ts +42 -12
- package/src/testing/deterministic/deterministic-security.ts +58 -19
- package/src/testing/deterministic/deterministic-test-backend-lifecycle-helpers.ts +3 -7
- package/src/testing/deterministic/deterministic-test-backend.ts +2 -4
- package/src/web/web-bluetooth-backend.ts +73 -56
- package/src/web/web-bluetooth-handles.ts +3 -0
- package/src/web.ts +1 -1
- package/unified-ble-manager.podspec +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@ All notable changes to `unified-ble-manager` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [4.0.4] - 2026-08-25
|
|
8
|
+
|
|
9
|
+
Post-4.0.3 audit: wire/scan/IPC ownership, Android 16 KB ELF alignment, Apple teardown, abortable Web chooser honesty, React remount-owned cleanup, and React Native entropy without WebCrypto. Does not retag `v4.0.3`.
|
|
10
|
+
|
|
11
|
+
### Fixes
|
|
12
|
+
|
|
13
|
+
- Tauri wire codec budgets, public scan presence overflow, IPC contract errors, GATT admission/rediscovery, Android scanCallback/receiver commit-after-success, 16 KB native page size (#80, #81, #83, #84, #93, #85, #86, #100, #107).
|
|
14
|
+
- Apple disconnect confirmation, Service Changed CCCD retry, restored notify-off; Web chooser abort/timeout does not retain a late `requestDevice` grant (#87, #89, #90, #88).
|
|
15
|
+
- React adapter-watch fail-visible terminals, remount-owned scan/characteristic `release-failed`, scoped BleProvider barriers, composeAbortSignal listener cleanup, `managerKey` replacement (#96, #97, #98, #99, #101).
|
|
16
|
+
- React Native manager construction no longer depends on WebCrypto or a Metro-fatal `crypto` require; native CSPRNG is the default, with injectable `randomBytes` (#111, #113, #114).
|
|
17
|
+
|
|
18
|
+
### Release integrity
|
|
19
|
+
|
|
20
|
+
- Cut from the exact post-PR #110 `main` merge commit through the tag-driven trusted-publishing workflow.
|
|
21
|
+
- Intended for publication as `latest`; this does not promote backend support labels or claim physical-radio evidence.
|
|
22
|
+
|
|
23
|
+
## [4.0.3] - 2026-08-25
|
|
24
|
+
|
|
25
|
+
Lifecycle ownership is explicit through clone/decode, public stream close, IPC admission, Web/Tauri teardown, backend unregister/overflow native release, and React hook store/terminal cleanup. Does not retag `v4.0.2`.
|
|
26
|
+
|
|
27
|
+
### Fixes
|
|
28
|
+
|
|
29
|
+
- Serializable clone/decode stays fail-closed; public stream close, scan stop, and IPC/Web/Tauri teardown no longer drop `release-failed` or skip native disconnect (#58, #59, #75, #60, #72, #63, #73, #76, #74, #79, #67, #77, #78).
|
|
30
|
+
- Adapter, security, and event-stream close/overflow keep backend ownership until native release succeeds; overflowing CoreBluetooth scan owners do not stop remaining joiners (#61, #68, #69, #70, #71).
|
|
31
|
+
- React adapter-state watches cannot wedge or double-own a run; `useDiscoveredPeers` is bounded and honors lost-peer events; connection and characteristic hooks leave loading with a fail-visible terminal (#62, #65, #66).
|
|
32
|
+
|
|
33
|
+
### Release integrity
|
|
34
|
+
|
|
35
|
+
- Cut from the exact post-PR #105 `main` merge commit through the tag-driven trusted-publishing workflow.
|
|
36
|
+
- Intended for publication as `latest`; this does not promote backend support labels or claim physical-radio evidence.
|
|
37
|
+
|
|
7
38
|
## [4.0.2] - 2026-08-24
|
|
8
39
|
|
|
9
40
|
Public coalesced scans no longer lose duplicate suppression after lost-peer or presence-cap churn: fingerprint deletions now decrement the retained-byte counter. IPC pre-registration buffering is globally bounded (ID/item/byte/age) with fail-visible tombstones. Connection release attempts `connection.disconnect` even when lifecycle unsubscribe rejects or returns `release-failed`, and preserves both cleanup failures. Does not retag `v4.0.1`.
|
package/MIGRATION_4.0.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Migrating from react-native-ble-plx
|
|
4
4
|
|
|
5
|
-
The current package is `4.0.
|
|
5
|
+
The current package is `4.0.4`. The `4.0.0` release is a new package and a new contract. It is **not a source-compatible rename**. There is no `new BleManager()` facade, no Base64 characteristic values, and no public transaction IDs.
|
|
6
6
|
|
|
7
7
|
This page is for a React Native app that already uses `react-native-ble-plx`. Web, Electron, Node, and Tauri are new hosts — use those pages after you understand the RN rewrite.
|
|
8
8
|
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
It is an evolution of `react-native-ble-plx`, rewritten as a **cross-platform unified product**. One bytes-first BLE model and lifecycle semantics across hosts, with host-specific construction and ownership. The root package never picks a radio for you, and it will not quietly fall back to a simulator or a different backend.
|
|
8
8
|
|
|
9
|
-
Install `unified-ble-manager` from npm (`4.0.
|
|
9
|
+
Install `unified-ble-manager` from npm (`4.0.4` on `latest`). The root import does not pick a radio. Package SemVer and backend support labels are independent: each radio backend stays Experimental until live-radio evidence says otherwise. See [`docs/PLATFORMS.md`](docs/PLATFORMS.md).
|
|
10
10
|
|
|
11
11
|
> Sponsored by [Imagi Explain](https://imagiexplain.com) — researched, narrated whiteboard explainers from a prompt, a PDF, or your notes.
|
|
12
12
|
|
|
@@ -279,6 +279,7 @@ after disconnect, service change, or rediscovery.
|
|
|
279
279
|
| `createElectronRendererBleManager` / `createElectronRendererBleManagerWithEnvironment` | Public renderer `BleManager` over a preload transport; the renderer never loads a radio backend |
|
|
280
280
|
| `createTauriBleManager` | Zero-plumbing Tauri `BleManager`; tests use `createTauriBleManagerWithEnvironment` |
|
|
281
281
|
| `createBleManagerFromProvider` | Advanced provider construction |
|
|
282
|
+
| `createPublicBleManagerFacade` | Projects an already-owned `/advanced` manager into the root public `BleManager`; creates no advanced manager, backend, or radio |
|
|
282
283
|
|
|
283
284
|
## Other hosts
|
|
284
285
|
|
package/RELEASE.md
CHANGED
|
@@ -81,7 +81,7 @@ Active `4.0.0-rc.*` release-train candidates publish to npm `latest` so a bare `
|
|
|
81
81
|
|
|
82
82
|
On release day, set `release_candidate` to the exact candidate required by the
|
|
83
83
|
release plan. RC2, RC3, RC4, `4.0.0-rc.4.1`, and RC5 are already immutable
|
|
84
|
-
once tagged. Stable `4.0.0` and `4.0.
|
|
84
|
+
once tagged. Stable `4.0.0`, `4.0.1`, `4.0.2`, and `4.0.3` are immutable. `4.0.4` is the current train head.
|
|
85
85
|
|
|
86
86
|
```sh
|
|
87
87
|
release_candidate=4.0.0-rc.N
|
|
@@ -119,7 +119,23 @@ git tag -a v4.0.1 -m "v4.0.1"
|
|
|
119
119
|
|
|
120
120
|
## Releasing 4.0.2
|
|
121
121
|
|
|
122
|
-
The
|
|
122
|
+
The `v4.0.2` tag is immutable published history. Do not recreate or move it.
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
git tag -a v4.0.2 -m "v4.0.2"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Releasing 4.0.3
|
|
129
|
+
|
|
130
|
+
The `v4.0.3` tag is immutable published history. Do not recreate or move it.
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
git tag -a v4.0.3 -m "v4.0.3"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Releasing 4.0.4
|
|
137
|
+
|
|
138
|
+
The source version is prepared on `main` before the tag. The release workflow verifies that every initial release tag points at the exact current `main` commit before publication; do not create that tag from a side branch or an older commit. Do not retag immutable `v4.0.0`, `v4.0.1`, `v4.0.2`, or `v4.0.3`.
|
|
123
139
|
|
|
124
140
|
On release day:
|
|
125
141
|
|
|
@@ -129,12 +145,12 @@ git checkout main
|
|
|
129
145
|
git pull --ff-only origin main
|
|
130
146
|
|
|
131
147
|
test "$(git branch --show-current)" = "main"
|
|
132
|
-
test "$(node -p "require('./package.json').version")" = "4.0.
|
|
148
|
+
test "$(node -p "require('./package.json').version")" = "4.0.4"
|
|
133
149
|
git diff --exit-code
|
|
134
150
|
git diff --cached --exit-code
|
|
135
151
|
|
|
136
|
-
git tag -a v4.0.
|
|
137
|
-
git push origin v4.0.
|
|
152
|
+
git tag -a v4.0.4 -m "v4.0.4"
|
|
153
|
+
git push origin v4.0.4
|
|
138
154
|
```
|
|
139
155
|
|
|
140
156
|
Do not push another commit to `main` between the final verification and the tag push.
|
package/SBOM.cdx.json
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
"metadata": {
|
|
7
7
|
"component": {
|
|
8
8
|
"type": "library",
|
|
9
|
-
"bom-ref": "pkg:npm/unified-ble-manager@4.0.
|
|
9
|
+
"bom-ref": "pkg:npm/unified-ble-manager@4.0.4",
|
|
10
10
|
"name": "unified-ble-manager",
|
|
11
|
-
"version": "4.0.
|
|
11
|
+
"version": "4.0.4",
|
|
12
12
|
"licenses": [
|
|
13
13
|
{
|
|
14
14
|
"expression": "Apache-2.0"
|
|
15
15
|
}
|
|
16
16
|
],
|
|
17
|
-
"purl": "pkg:npm/unified-ble-manager@4.0.
|
|
17
|
+
"purl": "pkg:npm/unified-ble-manager@4.0.4"
|
|
18
18
|
},
|
|
19
19
|
"properties": [
|
|
20
20
|
{
|
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
"dependsOn": []
|
|
538
538
|
},
|
|
539
539
|
{
|
|
540
|
-
"ref": "pkg:npm/unified-ble-manager@4.0.
|
|
540
|
+
"ref": "pkg:npm/unified-ble-manager@4.0.4",
|
|
541
541
|
"dependsOn": [
|
|
542
542
|
"pkg:npm/%40tauri-apps/api@2.11.1",
|
|
543
543
|
"pkg:npm/node-addon-api@8.9.0",
|
package/android/build.gradle
CHANGED
|
@@ -453,6 +453,22 @@ public final class UnifiedBleProtocolControlModule extends NativeUnifiedBleProto
|
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
@Override
|
|
457
|
+
public void getRandomBytes(double length, Promise promise) {
|
|
458
|
+
final int n = (int) length;
|
|
459
|
+
if (n != length || n <= 0 || n > 1024) {
|
|
460
|
+
promise.reject("argument.invalid", "randomBytes.length");
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
final byte[] out = new byte[n];
|
|
464
|
+
new java.security.SecureRandom().nextBytes(out);
|
|
465
|
+
final com.facebook.react.bridge.WritableArray values = Arguments.createArray();
|
|
466
|
+
for (byte value : out) {
|
|
467
|
+
values.pushInt(value & 0xff);
|
|
468
|
+
}
|
|
469
|
+
promise.resolve(values);
|
|
470
|
+
}
|
|
471
|
+
|
|
456
472
|
@Override
|
|
457
473
|
public synchronized void installExecutionRuntime(Promise promise) {
|
|
458
474
|
try {
|
package/android/src/main/java/com/sfourdrinier/unifiedblemanager/radio/OwnedAndroidGattRadio.kt
CHANGED
|
@@ -349,7 +349,6 @@ class OwnedAndroidGattRadio(private val context: Context) {
|
|
|
349
349
|
onAdapterState?.invoke(mapAdapterState(state))
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
|
-
adapterStateReceiver = receiver
|
|
353
352
|
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
|
|
354
353
|
// System broadcast (ACTION_STATE_CHANGED) requires RECEIVER_EXPORTED on API 33+.
|
|
355
354
|
if (Build.VERSION.SDK_INT >= 33) {
|
|
@@ -358,6 +357,7 @@ class OwnedAndroidGattRadio(private val context: Context) {
|
|
|
358
357
|
@Suppress("UnspecifiedRegisterReceiverFlag")
|
|
359
358
|
context.registerReceiver(receiver, filter)
|
|
360
359
|
}
|
|
360
|
+
adapterStateReceiver = receiver
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
internal fun unregisterAdapterStateReceiver(): OwnedRadioTeardownFailure? {
|
|
@@ -444,11 +444,30 @@ class OwnedAndroidGattRadio(private val context: Context) {
|
|
|
444
444
|
onScanFailed?.invoke(errorCode)
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
447
|
+
try {
|
|
448
|
+
if (filters.isEmpty()) {
|
|
449
|
+
scanner?.startScan(null, settings, cb)
|
|
450
|
+
} else {
|
|
451
|
+
scanner?.startScan(filters, settings, cb)
|
|
452
|
+
}
|
|
453
|
+
scanCallback = cb
|
|
454
|
+
} catch (error: Throwable) {
|
|
455
|
+
val cleanupFailure =
|
|
456
|
+
try {
|
|
457
|
+
scanner?.stopScan(cb)
|
|
458
|
+
null
|
|
459
|
+
} catch (stopError: Throwable) {
|
|
460
|
+
OwnedAndroidLog.e("startScan compensating stopScan", stopError)
|
|
461
|
+
stopError
|
|
462
|
+
}
|
|
463
|
+
if (cleanupFailure == null) {
|
|
464
|
+
scanCallback = null
|
|
465
|
+
scanner = null
|
|
466
|
+
scanSeenDeviceIds.clear()
|
|
467
|
+
} else {
|
|
468
|
+
scanCallback = cb
|
|
469
|
+
}
|
|
470
|
+
throw error
|
|
452
471
|
}
|
|
453
472
|
}
|
|
454
473
|
|
|
@@ -612,13 +631,13 @@ class OwnedAndroidGattRadio(private val context: Context) {
|
|
|
612
631
|
}
|
|
613
632
|
}
|
|
614
633
|
}
|
|
615
|
-
bondStateReceiver = receiver
|
|
616
634
|
val filter = IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
|
|
617
635
|
if (Build.VERSION.SDK_INT >= 33) context.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED)
|
|
618
636
|
else {
|
|
619
637
|
@Suppress("UnspecifiedRegisterReceiverFlag")
|
|
620
638
|
context.registerReceiver(receiver, filter)
|
|
621
639
|
}
|
|
640
|
+
bondStateReceiver = receiver
|
|
622
641
|
}
|
|
623
642
|
|
|
624
643
|
internal fun unregisterBondStateReceiver(): OwnedRadioTeardownFailure? {
|
package/docs/ELECTRON.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Main owns the radio. The renderer uses a versioned IPC client and never loads a native addon.
|
|
6
6
|
|
|
7
|
-
The current package is `4.0.
|
|
7
|
+
The current package is `4.0.4`. The release ships Node-API v8 prebuilds covering macOS and Windows `arm64`/`x64` for both Node and modern Electron.
|
|
8
8
|
|
|
9
9
|
`unified-ble-manager/electron/main` and
|
|
10
10
|
`unified-ble-manager/electron/renderer` are the only Electron entrypoints.
|
package/docs/EXPO_PLUGIN.md
CHANGED
|
@@ -7,7 +7,7 @@ start a radio, request runtime permissions during prebuild, or prove physical
|
|
|
7
7
|
radio/restoration reliability. Expo Go is not a supported BLE execution
|
|
8
8
|
environment because it cannot contain this native module.
|
|
9
9
|
|
|
10
|
-
Use the v2 plugin options in the published `4.0.
|
|
10
|
+
Use the v2 plugin options in the published `4.0.4` package. Those options match
|
|
11
11
|
the schema introduced at `4.0.0-rc.4`. Expo Go cannot load this native module.
|
|
12
12
|
|
|
13
13
|
## Installation and development build
|
|
@@ -15,7 +15,7 @@ the schema introduced at `4.0.0-rc.4`. Expo Go cannot load this native module.
|
|
|
15
15
|
Pin the package so a later `latest` bump does not change native plugin options
|
|
16
16
|
without a rebuild:
|
|
17
17
|
|
|
18
|
-
pnpm add unified-ble-manager@4.0.
|
|
18
|
+
pnpm add unified-ble-manager@4.0.4
|
|
19
19
|
pnpm add expo@^57.0.0 expo-dev-client
|
|
20
20
|
npx expo prebuild --clean
|
|
21
21
|
npx expo run:ios
|
package/docs/GAPS.4.0.md
CHANGED
|
@@ -14,7 +14,7 @@ This file tracks platform code, CI, package, lab, and live-radio evidence. It do
|
|
|
14
14
|
|
|
15
15
|
The clean-baseline contract, unified core, public manager, deterministic backend, TCK, native protocol, first-party backend implementations, host-isolated package exports, SDK/CLI, and legacy-absence gates exist in the 4.0 source. Passing deterministic, compile, ABI, or package tests are implementation proof; they do not become physical-radio support evidence unless a retained record proves the corresponding live scenario.
|
|
16
16
|
|
|
17
|
-
`unified-ble-manager@4.0.
|
|
17
|
+
`unified-ble-manager@4.0.4` is the published, immutable stable package/API. Immutable `4.0.0`, `4.0.1`, `4.0.2`, and `4.0.3` remain published history. Backend support labels remain
|
|
18
18
|
evidence-derived. This package does not rewrite the evidence inventory: a backend remains at the support level
|
|
19
19
|
justified by its records. The alpha train, including `v4.0.0-alpha.40`, remains historical implementation/release
|
|
20
20
|
evidence and must not be used to claim a higher current support label than it actually proved.
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
This page gets you to a first scan, connect, read, notify, and teardown on React Native. Other hosts are linked at the bottom. The root import does not turn Bluetooth on.
|
|
6
6
|
|
|
7
|
-
The current package is `4.0.
|
|
7
|
+
The current package is `4.0.4`.
|
|
8
8
|
|
|
9
9
|
## Pick a host
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ The current package is `4.0.2`.
|
|
|
27
27
|
Pin the current package for a known native rebuild:
|
|
28
28
|
|
|
29
29
|
```sh
|
|
30
|
-
pnpm add unified-ble-manager@4.0.
|
|
30
|
+
pnpm add unified-ble-manager@4.0.4
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Declare Android Bluetooth permissions and the BLE hardware feature yourself,
|
|
@@ -37,10 +37,10 @@ request runtime permissions on Android 12+, add
|
|
|
37
37
|
#### Expo / CNG v2
|
|
38
38
|
|
|
39
39
|
The Expo v2 schema and `unified-ble-manager/expo` factory are in the published
|
|
40
|
-
`4.0.
|
|
40
|
+
`4.0.4` package. Pin that exact version:
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
|
-
pnpm add unified-ble-manager@4.0.
|
|
43
|
+
pnpm add unified-ble-manager@4.0.4
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
The package does not run in Expo Go.
|
package/docs/NODE.md
CHANGED
|
@@ -10,7 +10,7 @@ The root import does not open an adapter. Pick one backend:
|
|
|
10
10
|
| `unified-ble-manager/node/winrt` | Windows |
|
|
11
11
|
| `unified-ble-manager/node/bluez` | Linux (needs `dbus-next@^0.10.2` in the app) |
|
|
12
12
|
|
|
13
|
-
The current package is `4.0.
|
|
13
|
+
The current package is `4.0.4`. The release ships Node-API v8 prebuilds for macOS and Windows on `arm64` and `x64`. A normal install should not compile native code. BlueZ talks D-Bus and has no addon.
|
|
14
14
|
|
|
15
15
|
## One-call factories
|
|
16
16
|
|
package/docs/PLATFORMS.md
CHANGED
|
@@ -8,7 +8,7 @@ This page is an evidence index, not a static compatibility matrix. An applicatio
|
|
|
8
8
|
|
|
9
9
|
## Package stability and backend support are separate
|
|
10
10
|
|
|
11
|
-
`unified-ble-manager@4.0.
|
|
11
|
+
`unified-ble-manager@4.0.4` is the published **stable package/API** for the 4.x contract; it is immutable. Backend support labels remain evidence-derived and independent of this SemVer. Immutable `4.0.0`, `4.0.1`, `4.0.2`, and `4.0.3` remain published history.
|
|
12
12
|
|
|
13
13
|
This package is the portable API/semantics freeze; it does **not** mean every first-party backend is
|
|
14
14
|
automatically Preview, Supported, or Reliability-qualified.
|
package/docs/WEB.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Use `unified-ble-manager/web` in a secure context (HTTPS or localhost) from a user gesture. There is no background scan and no process-level restoration.
|
|
6
6
|
|
|
7
|
-
The current package is `4.0.
|
|
7
|
+
The current package is `4.0.4`. The backend is Experimental until artifact-bound physical-hardware validation says otherwise. See [`PLATFORMS.md`](PLATFORMS.md).
|
|
8
8
|
|
|
9
9
|
## Create the manager
|
|
10
10
|
|
|
@@ -6,7 +6,7 @@ This page is generated by `scripts/docs/generate-platform-support.js` from valid
|
|
|
6
6
|
|
|
7
7
|
## Current package
|
|
8
8
|
|
|
9
|
-
`unified-ble-manager@4.0.
|
|
9
|
+
`unified-ble-manager@4.0.4`
|
|
10
10
|
|
|
11
11
|
No evidence record is bound to this exact package version and artifact. Consequently, this generated page makes no Preview, Live Preview, Supported, or Reliability-qualified platform claim for the current package.
|
|
12
12
|
|
|
@@ -56,9 +56,9 @@ public final class OwnedCoreBluetoothProtocolRadio: NSObject, CBPeripheralDelega
|
|
|
56
56
|
/// retained cleanup entry, rather than an unbounded timer fan-out, is the
|
|
57
57
|
/// source of truth for the physical CCCD transition still in flight.
|
|
58
58
|
var pendingCancellationCleanupRetryScheduled = Set<String>()
|
|
59
|
-
|
|
59
|
+
var subscriptions = [CharacteristicAddress: String]()
|
|
60
60
|
var activeScanOperationIdentifier: String?
|
|
61
|
-
|
|
61
|
+
var restoredPeerIdentifiers = [String]()
|
|
62
62
|
var destroyed = false
|
|
63
63
|
|
|
64
64
|
struct CharacteristicAddress: Hashable {
|
|
@@ -158,17 +158,14 @@ public final class OwnedCoreBluetoothProtocolRadio: NSObject, CBPeripheralDelega
|
|
|
158
158
|
self.failAllPendingOperationsOnDestroy()
|
|
159
159
|
self.pendingCancellationCleanup.removeAll()
|
|
160
160
|
self.pendingCancellationCleanupRetryScheduled.removeAll()
|
|
161
|
+
self.disableActiveNotifications()
|
|
161
162
|
self.subscriptions.removeAll()
|
|
162
163
|
let restoredIdentifiers = Set(self.restoredPeerIdentifiers)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
self.peripheralByIdentifier = self.peripheralByIdentifier.filter { restoredIdentifiers.contains($0.key) }
|
|
170
|
-
self.servicesByPeer = self.servicesByPeer.filter { restoredIdentifiers.contains($0.key) }
|
|
171
|
-
completion(nil)
|
|
164
|
+
self.completeAfterPendingDisconnects(
|
|
165
|
+
preserving: restoredIdentifiers,
|
|
166
|
+
destroyRadio: false,
|
|
167
|
+
completion: completion
|
|
168
|
+
)
|
|
172
169
|
}
|
|
173
170
|
}
|
|
174
171
|
|
|
@@ -450,17 +447,14 @@ public final class OwnedCoreBluetoothProtocolRadio: NSObject, CBPeripheralDelega
|
|
|
450
447
|
self.destroyed = true
|
|
451
448
|
self.central.stopScan()
|
|
452
449
|
self.activeScanOperationIdentifier = nil
|
|
453
|
-
for peripheral in self.peripheralByIdentifier.values where peripheral.state == .connected || peripheral.state == .connecting {
|
|
454
|
-
self.central.cancelPeripheralConnection(peripheral)
|
|
455
|
-
peripheral.delegate = nil
|
|
456
|
-
}
|
|
457
450
|
self.failAllPendingOperationsOnDestroy()
|
|
451
|
+
self.disableActiveNotifications()
|
|
458
452
|
self.subscriptions.removeAll()
|
|
459
|
-
self.
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
453
|
+
self.completeAfterPendingDisconnects(
|
|
454
|
+
preserving: [],
|
|
455
|
+
destroyRadio: true,
|
|
456
|
+
completion: completion
|
|
457
|
+
)
|
|
464
458
|
}
|
|
465
459
|
}
|
|
466
460
|
|
|
@@ -209,4 +209,91 @@ extension OwnedCoreBluetoothProtocolRadio {
|
|
|
209
209
|
_ = self.retryCancellationCleanupOnQueue(operationIdentifier)
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
+
|
|
213
|
+
func disableActiveNotifications() {
|
|
214
|
+
for address in subscriptions.keys {
|
|
215
|
+
if let resolved = resolve(address) {
|
|
216
|
+
resolved.peripheral.setNotifyValue(false, for: resolved.characteristic)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
func completeAfterPendingDisconnects(
|
|
222
|
+
preserving restoredIdentifiers: Set<String>,
|
|
223
|
+
destroyRadio: Bool,
|
|
224
|
+
completion: @escaping (NSError?) -> Void
|
|
225
|
+
) {
|
|
226
|
+
final class DisconnectWaiter {
|
|
227
|
+
var remaining: Int
|
|
228
|
+
var finished = false
|
|
229
|
+
let finish: (NSError?) -> Void
|
|
230
|
+
init(remaining: Int, finish: @escaping (NSError?) -> Void) {
|
|
231
|
+
self.remaining = remaining
|
|
232
|
+
self.finish = finish
|
|
233
|
+
}
|
|
234
|
+
func decrement() {
|
|
235
|
+
remaining -= 1
|
|
236
|
+
if remaining <= 0 { complete(nil) }
|
|
237
|
+
}
|
|
238
|
+
func complete(_ error: NSError?) {
|
|
239
|
+
guard !finished else { return }
|
|
240
|
+
finished = true
|
|
241
|
+
finish(error)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
let waited: [(identifier: String, peripheral: CBPeripheral)] = peripheralByIdentifier.compactMap { identifier, peripheral in
|
|
246
|
+
guard !restoredIdentifiers.contains(identifier) else { return nil }
|
|
247
|
+
if peripheral.state == .connected || peripheral.state == .connecting || peripheral.state == .disconnecting {
|
|
248
|
+
return (identifier, peripheral)
|
|
249
|
+
}
|
|
250
|
+
peripheral.delegate = nil
|
|
251
|
+
return nil
|
|
252
|
+
}
|
|
253
|
+
let waiter = DisconnectWaiter(remaining: waited.count) { [weak self] error in
|
|
254
|
+
guard let self else {
|
|
255
|
+
completion(error)
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
for (identifier, peripheral) in self.peripheralByIdentifier where !restoredIdentifiers.contains(identifier) {
|
|
259
|
+
peripheral.delegate = nil
|
|
260
|
+
}
|
|
261
|
+
if destroyRadio {
|
|
262
|
+
for peripheral in self.peripheralByIdentifier.values {
|
|
263
|
+
peripheral.delegate = nil
|
|
264
|
+
}
|
|
265
|
+
self.peripheralByIdentifier.removeAll()
|
|
266
|
+
self.servicesByPeer.removeAll()
|
|
267
|
+
self.restoredPeerIdentifiers.removeAll()
|
|
268
|
+
self.central.delegate = nil
|
|
269
|
+
} else {
|
|
270
|
+
self.peripheralByIdentifier = self.peripheralByIdentifier.filter { restoredIdentifiers.contains($0.key) }
|
|
271
|
+
self.servicesByPeer = self.servicesByPeer.filter { restoredIdentifiers.contains($0.key) }
|
|
272
|
+
}
|
|
273
|
+
completion(error)
|
|
274
|
+
}
|
|
275
|
+
if waited.isEmpty {
|
|
276
|
+
waiter.complete(nil)
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
queue.asyncAfter(deadline: .now() + .seconds(5)) { [weak self] in
|
|
280
|
+
guard let self else { return }
|
|
281
|
+
waiter.complete(self.error(code: 1026, message: "CoreBluetooth disconnect confirmation timed out"))
|
|
282
|
+
}
|
|
283
|
+
for entry in waited {
|
|
284
|
+
let previous = pendingDisconnect[entry.identifier]
|
|
285
|
+
pendingDisconnect[entry.identifier] = PendingVoid(operationIdentifier: "teardown-\(entry.identifier)") { error in
|
|
286
|
+
previous?.completion(error)
|
|
287
|
+
waiter.decrement()
|
|
288
|
+
}
|
|
289
|
+
if entry.peripheral.state == .disconnected {
|
|
290
|
+
pendingDisconnect.removeValue(forKey: entry.identifier)?.completion(nil)
|
|
291
|
+
continue
|
|
292
|
+
}
|
|
293
|
+
central.cancelPeripheralConnection(entry.peripheral)
|
|
294
|
+
if entry.peripheral.state == .disconnected {
|
|
295
|
+
pendingDisconnect.removeValue(forKey: entry.identifier)?.completion(nil)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
212
299
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#import <Foundation/Foundation.h>
|
|
4
4
|
#import <CoreBluetooth/CoreBluetooth.h>
|
|
5
|
+
#import <Security/Security.h>
|
|
5
6
|
#import <React/RCTLog.h>
|
|
6
7
|
#import <ReactCommon/RCTTurboModule.h>
|
|
7
8
|
#import <ReactCommon/RCTTurboModuleWithJSIBindings.h>
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
#endif
|
|
13
14
|
|
|
14
15
|
#include <cmath>
|
|
16
|
+
#include <vector>
|
|
15
17
|
#include "../native/protocol/include/NativeProtocolControlRuntime.hpp"
|
|
16
18
|
#include "../native/protocol/include/NativeRestorationConfiguration.hpp"
|
|
17
19
|
#include "NativeProtocol/UnifiedBleProtocolAppleExecution.hpp"
|
|
@@ -516,6 +518,26 @@ RCT_EXPORT_MODULE(UnifiedBleProtocolControl)
|
|
|
516
518
|
});
|
|
517
519
|
}
|
|
518
520
|
|
|
521
|
+
- (void)getRandomBytes:(double)length
|
|
522
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
523
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
524
|
+
const int n = static_cast<int>(length);
|
|
525
|
+
if (length != static_cast<double>(n) || n <= 0 || n > 1024) {
|
|
526
|
+
rejectControl(reject, @"argument.invalid", @"randomBytes.length");
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
std::vector<uint8_t> bytes(static_cast<size_t>(n));
|
|
530
|
+
if (SecRandomCopyBytes(kSecRandomDefault, static_cast<size_t>(n), bytes.data()) != errSecSuccess) {
|
|
531
|
+
rejectControl(reject, @"capability.unsupported", @"host-identity.secure-randomness");
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
NSMutableArray<NSNumber *> *values = [NSMutableArray arrayWithCapacity:static_cast<NSUInteger>(n)];
|
|
535
|
+
for (int index = 0; index < n; index += 1) {
|
|
536
|
+
[values addObject:@(bytes[static_cast<size_t>(index)])];
|
|
537
|
+
}
|
|
538
|
+
resolve(values);
|
|
539
|
+
}
|
|
540
|
+
|
|
519
541
|
- (void)installExecutionRuntime:(RCTPromiseResolveBlock)resolve
|
|
520
542
|
reject:(RCTPromiseRejectBlock)reject {
|
|
521
543
|
if (_attachment == nil) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeUnifiedBleProtocolControl.ts"],"mappings":";;;;;;AAGA,IAAAA,YAAA,GAAAC,OAAA;AAHA;AAAA,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeUnifiedBleProtocolControl.ts"],"mappings":";;;;;;AAGA,IAAAA,YAAA,GAAAC,OAAA;AAHA;AAAA,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAoKeC,gCAAmB,CAACC,YAAY,CAAO,2BAA2B,CAAC","ignoreList":[]}
|