unified-ble-manager 4.0.10 → 4.0.11
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 +10 -0
- package/MIGRATION_4.0.md +1 -1
- package/README.md +39 -14
- package/RELEASE.md +23 -2
- package/SBOM.cdx.json +5 -5
- package/THIRD_PARTY_LICENSES.json +2 -2
- package/docs/CONNECTION_MANAGER.md +34 -0
- package/docs/ELECTRON.md +1 -1
- package/docs/EXPO_PLUGIN.md +1 -1
- package/docs/GAPS.4.0.md +1 -1
- package/docs/GETTING_STARTED.md +3 -3
- package/docs/NODE.md +1 -1
- package/docs/WEB.md +215 -75
- package/docs/generated/PLATFORM_SUPPORT.md +1 -1
- package/lib/commonjs/implementation-version.js +1 -1
- package/lib/module/implementation-version.js +1 -1
- package/lib/typescript/commonjs/src/backends/bluez/bluez-backend-provider.d.ts +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-apple-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/backends/winrt/winrt-provider.d.ts +1 -1
- package/lib/typescript/commonjs/src/implementation-version.d.ts +1 -1
- package/lib/typescript/module/src/backends/bluez/bluez-backend-provider.d.ts +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-apple-provider.d.ts +1 -1
- package/lib/typescript/module/src/backends/winrt/winrt-provider.d.ts +1 -1
- package/lib/typescript/module/src/implementation-version.d.ts +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/package.json +4 -3
- package/src/implementation-version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ All notable changes to `unified-ble-manager` are documented here.
|
|
|
6
6
|
|
|
7
7
|
No changes yet.
|
|
8
8
|
|
|
9
|
+
## [4.0.11] - 2026-08-30
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
- Document adapter interruption recovery through `manager.adapter.watchState()`
|
|
14
|
+
in the README and connection guide, and add the same flow to the Expo
|
|
15
|
+
example. UBM invalidates affected generations and leaves reconnect policy
|
|
16
|
+
with the host; the example displays live adapter power, availability, and
|
|
17
|
+
authorization instead of polling or silently reconnecting.
|
|
18
|
+
|
|
9
19
|
## [4.0.10] - 2026-08-30
|
|
10
20
|
|
|
11
21
|
### Fixes
|
package/MIGRATION_4.0.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Migrating from react-native-ble-plx
|
|
4
4
|
|
|
5
|
-
This source targets `4.0.
|
|
5
|
+
This source targets `4.0.11`. 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
|
@@ -12,7 +12,7 @@ root import does not pick a radio. Package SemVer and backend support labels are
|
|
|
12
12
|
independent: each radio backend keeps its evidence-derived label. See
|
|
13
13
|
[`docs/PLATFORMS.md`](docs/PLATFORMS.md).
|
|
14
14
|
|
|
15
|
-
This source tree is versioned `4.0.
|
|
15
|
+
This source tree is versioned `4.0.11`. Install the exact version shown in the npm
|
|
16
16
|
registry. During release preparation, the version in `package.json` can be ahead
|
|
17
17
|
of npm until the matching tag-driven workflow publishes it; the registry and
|
|
18
18
|
GitHub release remain authoritative.
|
|
@@ -62,7 +62,7 @@ The root import selects no radio. Import the host you actually run.
|
|
|
62
62
|
| ---------------------------------------- | ------------------------------------------------------------------------------ |
|
|
63
63
|
| `unified-ble-manager` | Host-neutral manager, handles, helpers, and shared types |
|
|
64
64
|
| `unified-ble-manager/react-native` | React Native Android / Apple manager |
|
|
65
|
-
| `unified-ble-manager/react`
|
|
65
|
+
| `unified-ble-manager/react` | React provider, hooks, and React-facing type utilities |
|
|
66
66
|
| `unified-ble-manager/expo` | Expo development-build manager, readiness, and native configuration checks |
|
|
67
67
|
| `unified-ble-manager/web` | Web Bluetooth chooser + matched manager |
|
|
68
68
|
| `unified-ble-manager/electron/main` | Trusted Electron-main radio + IPC router |
|
|
@@ -106,6 +106,31 @@ On Android, `manager.peers.bonded()` lists paired system peers and
|
|
|
106
106
|
reachable. See [`docs/PEERS.md`](docs/PEERS.md) for the persistence and error
|
|
107
107
|
semantics.
|
|
108
108
|
|
|
109
|
+
### Recovering after an adapter interruption
|
|
110
|
+
|
|
111
|
+
Adapter power and authorization changes are observable through the same public
|
|
112
|
+
contract on every backend:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const watch = await manager.adapter.watchState()
|
|
116
|
+
let previous = watch.initial
|
|
117
|
+
for await (const item of watch.values) {
|
|
118
|
+
if (item.kind !== 'value') continue
|
|
119
|
+
const state = item.value
|
|
120
|
+
const restored = previous.power !== 'on' && state.power === 'on'
|
|
121
|
+
previous = state
|
|
122
|
+
if (restored && state.availability === 'available' && state.authorization === 'granted') {
|
|
123
|
+
// Reconcile your saved peer/reference and reconnect using your product policy.
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
await watch.stop()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
UBM invalidates affected connections when the adapter is unavailable and does
|
|
130
|
+
not reconnect silently. The host observes `watchState()`, resolves a fresh
|
|
131
|
+
peer/reference, and starts a new connection generation. Do not poll, create a
|
|
132
|
+
second manager, or reuse old GATT/database handles.
|
|
133
|
+
|
|
109
134
|
### Expo plugin
|
|
110
135
|
|
|
111
136
|
Use an Expo development build, never Expo Go. Plugin options live in
|
|
@@ -174,7 +199,7 @@ try {
|
|
|
174
199
|
|
|
175
200
|
Battery Level and Heart Rate Control Point are optional or conditional; see [`docs/TUTORIALS.md`](docs/TUTORIALS.md). Persistent subscriptions also live there.
|
|
176
201
|
|
|
177
|
-
Web Bluetooth replaces the scan with `ble.choose(...)` from a user gesture. Tauri and the Electron renderer use different host entrypoints — see those host pages.
|
|
202
|
+
Web Bluetooth replaces the scan with `ble.choose(...)` from a user gesture. The [complete Web Bluetooth guide](docs/WEB.md) and [TypeScript/Vite example](example-web/) cover chooser permissions, authorized peers, bounded operations, notifications, structured errors, and safe cleanup. Tauri and the Electron renderer use different host entrypoints — see those host pages.
|
|
178
203
|
|
|
179
204
|
## Why the API looks like this
|
|
180
205
|
|
|
@@ -293,17 +318,17 @@ after disconnect, service change, or rediscovery.
|
|
|
293
318
|
|
|
294
319
|
### Host factories
|
|
295
320
|
|
|
296
|
-
| Factory | Returns
|
|
297
|
-
| -------------------------------------------------------------------------------------- |
|
|
298
|
-
| `createReactNativeBleManager` | Zero-plumbing public React Native manager
|
|
299
|
-
| `createReactNativeBleManagerWithEnvironment` | Injectable RN factory for tests
|
|
300
|
-
| `createExpoBleManager` | Expo development-build manager with readiness and native configuration checks
|
|
301
|
-
| `createWebBleManager` | Zero-plumbing public Web manager; use `ble.choose()` from a user gesture
|
|
302
|
-
| `createCoreBluetoothBleManager` / `createWinRtBleManager` / `createBluezBleManager` | One-call Node managers
|
|
303
|
-
| `createElectronMainCoreBluetoothBackendProvider` / `WinRt` | Main-process provider; you still build a `BleManager`
|
|
304
|
-
| `createElectronRendererBleManager` / `createElectronRendererBleManagerWithEnvironment` | Public renderer `BleManager` over a preload transport; the renderer never loads a radio backend
|
|
305
|
-
| `createTauriBleManager` | Zero-plumbing Tauri `BleManager`; tests use `createTauriBleManagerWithEnvironment`
|
|
306
|
-
| `createBleManagerFromProvider` | Advanced provider construction
|
|
321
|
+
| Factory | Returns |
|
|
322
|
+
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
323
|
+
| `createReactNativeBleManager` | Zero-plumbing public React Native manager |
|
|
324
|
+
| `createReactNativeBleManagerWithEnvironment` | Injectable RN factory for tests |
|
|
325
|
+
| `createExpoBleManager` | Expo development-build manager with readiness and native configuration checks |
|
|
326
|
+
| `createWebBleManager` | Zero-plumbing public Web manager; use `ble.choose()` from a user gesture |
|
|
327
|
+
| `createCoreBluetoothBleManager` / `createWinRtBleManager` / `createBluezBleManager` | One-call Node managers |
|
|
328
|
+
| `createElectronMainCoreBluetoothBackendProvider` / `WinRt` | Main-process provider; you still build a `BleManager` |
|
|
329
|
+
| `createElectronRendererBleManager` / `createElectronRendererBleManagerWithEnvironment` | Public renderer `BleManager` over a preload transport; the renderer never loads a radio backend |
|
|
330
|
+
| `createTauriBleManager` | Zero-plumbing Tauri `BleManager`; tests use `createTauriBleManagerWithEnvironment` |
|
|
331
|
+
| `createBleManagerFromProvider` | Advanced provider construction |
|
|
307
332
|
| `createPublicBleManagerFacade` | Projects an already-owned `/advanced` manager into the root public `BleManager`; creates no advanced manager, backend, or radio |
|
|
308
333
|
|
|
309
334
|
## Other hosts
|
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` through `4.0.
|
|
84
|
+
once tagged. Stable `4.0.0` through `4.0.10` are immutable. `4.0.11` is the current train head.
|
|
85
85
|
|
|
86
86
|
```sh
|
|
87
87
|
release_candidate=4.0.0-rc.N
|
|
@@ -133,6 +133,27 @@ The `v4.0.3` tag is immutable published history. Do not recreate or move it.
|
|
|
133
133
|
git tag -a v4.0.3 -m "v4.0.3"
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
+
## Releasing 4.0.11
|
|
137
|
+
|
|
138
|
+
The `v4.0.11` tag must identify the exact current `main` commit after canonical
|
|
139
|
+
CI passes. Do not tag this feature branch directly.
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
git fetch origin --tags
|
|
143
|
+
git checkout main
|
|
144
|
+
git pull --ff-only origin main
|
|
145
|
+
|
|
146
|
+
test "$(git branch --show-current)" = "main"
|
|
147
|
+
test "$(node -p "require('./package.json').version")" = "4.0.11"
|
|
148
|
+
git diff --exit-code
|
|
149
|
+
git diff --cached --exit-code
|
|
150
|
+
|
|
151
|
+
git tag -a v4.0.11 -m "v4.0.11"
|
|
152
|
+
git push origin v4.0.11
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Before tagging, confirm release-note extraction finds `## [4.0.11]`.
|
|
156
|
+
|
|
136
157
|
## Releasing 4.0.10
|
|
137
158
|
|
|
138
159
|
The `v4.0.10` tag must identify the exact current `main` commit after canonical
|
|
@@ -277,7 +298,7 @@ a green publish job and a package a consumer can actually install are not the
|
|
|
277
298
|
same claim.
|
|
278
299
|
|
|
279
300
|
```sh
|
|
280
|
-
version=4.0.
|
|
301
|
+
version=4.0.11
|
|
281
302
|
|
|
282
303
|
npm view "unified-ble-manager@$version" version
|
|
283
304
|
npm view unified-ble-manager dist-tags --json
|
package/SBOM.cdx.json
CHANGED
|
@@ -6,20 +6,20 @@
|
|
|
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.11",
|
|
10
10
|
"name": "unified-ble-manager",
|
|
11
|
-
"version": "4.0.
|
|
11
|
+
"version": "4.0.11",
|
|
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.11"
|
|
18
18
|
},
|
|
19
19
|
"properties": [
|
|
20
20
|
{
|
|
21
21
|
"name": "unified-ble-manager:pnpm-lock-sha256",
|
|
22
|
-
"value": "
|
|
22
|
+
"value": "58c2b09c18f10de1e250a357e5ce9445fe6bcace614e3778bc60166b9db31fa1"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"name": "unified-ble-manager:dependency-scope",
|
|
@@ -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.11",
|
|
541
541
|
"dependsOn": [
|
|
542
542
|
"pkg:npm/%40babel/runtime@7.29.7",
|
|
543
543
|
"pkg:npm/node-addon-api@8.9.0",
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
"schemaVersion": "1.0.0",
|
|
5
5
|
"package": {
|
|
6
6
|
"name": "unified-ble-manager",
|
|
7
|
-
"version": "4.0.
|
|
7
|
+
"version": "4.0.11"
|
|
8
8
|
},
|
|
9
9
|
"source": {
|
|
10
10
|
"method": "pnpm-lock production graph with installed-manifest license audit",
|
|
11
11
|
"lockfile": "pnpm-lock.yaml",
|
|
12
|
-
"lockfileSha256": "
|
|
12
|
+
"lockfileSha256": "58c2b09c18f10de1e250a357e5ce9445fe6bcace614e3778bc60166b9db31fa1"
|
|
13
13
|
},
|
|
14
14
|
"reviewedOverrides": [
|
|
15
15
|
{
|
|
@@ -95,6 +95,40 @@ reconnect. See [`BACKGROUND.md`](BACKGROUND.md) and
|
|
|
95
95
|
[`EXPO_PLUGIN.md`](EXPO_PLUGIN.md). Electron renderer resources remain owned by
|
|
96
96
|
their authorized renderer lease; the main process owns the physical backend.
|
|
97
97
|
|
|
98
|
+
## Adapter interruption and recovery
|
|
99
|
+
|
|
100
|
+
An adapter power transition is not a peer disappearance. UBM publishes the
|
|
101
|
+
typed transition through `manager.adapter.watchState()` and invalidates active
|
|
102
|
+
connection generations while the adapter is unavailable. This behavior is
|
|
103
|
+
shared by the React Native Android, React Native Apple, BlueZ, WinRT, Electron,
|
|
104
|
+
Tauri, and Web backends wherever the platform exposes adapter state.
|
|
105
|
+
|
|
106
|
+
The application remains the reconnect authority:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const watch = await manager.adapter.watchState()
|
|
110
|
+
let prior = watch.initial
|
|
111
|
+
for await (const item of watch.values) {
|
|
112
|
+
if (item.kind !== 'value') continue
|
|
113
|
+
const current = item.value
|
|
114
|
+
const becameReady = prior.power !== 'on'
|
|
115
|
+
&& current.power === 'on'
|
|
116
|
+
&& current.availability === 'available'
|
|
117
|
+
&& current.authorization === 'granted'
|
|
118
|
+
prior = current
|
|
119
|
+
if (becameReady) {
|
|
120
|
+
// Resolve a fresh peer/reference and invoke the caller-owned retry policy.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await watch.stop()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Do not create a second manager or reuse a connection/database from before the
|
|
127
|
+
adapter loss. A backend may report a cleanup retry while native operations are
|
|
128
|
+
settling; wait for a ready state and retry the application operation with a new
|
|
129
|
+
generation. Backends that cannot observe a given adapter transition expose the
|
|
130
|
+
truthful snapshot they have and never fabricate reconnect behavior.
|
|
131
|
+
|
|
98
132
|
## Cleanup failures
|
|
99
133
|
|
|
100
134
|
Cleanup records are data. A `release-failed` result retains retry ownership and
|
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
|
-
This source targets `4.0.
|
|
7
|
+
This source targets `4.0.11`. Tagged releases ship 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 this `4.0.
|
|
10
|
+
Use the v2 plugin options in this `4.0.11` source. 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
|
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
|
-
This source targets `unified-ble-manager@4.0.
|
|
17
|
+
This source targets `unified-ble-manager@4.0.11`; the npm registry and release
|
|
18
18
|
provenance, not a source version string, determine whether it is published.
|
|
19
19
|
Earlier stable releases remain immutable published history. Backend support labels remain
|
|
20
20
|
evidence-derived. This package does not rewrite the evidence inventory: a backend remains at the support level
|
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
|
-
This source targets `4.0.
|
|
7
|
+
This source targets `4.0.11`; verify the published version in the npm registry.
|
|
8
8
|
|
|
9
9
|
## Pick a host
|
|
10
10
|
|
|
@@ -38,11 +38,11 @@ request runtime permissions on Android 12+, add
|
|
|
38
38
|
#### Expo / CNG v2
|
|
39
39
|
|
|
40
40
|
The Expo v2 schema and `unified-ble-manager/expo` factory are in this source.
|
|
41
|
-
After the npm registry lists `4.0.
|
|
41
|
+
After the npm registry lists `4.0.11`, install that exact version and keep it in
|
|
42
42
|
your lockfile while validating the native build:
|
|
43
43
|
|
|
44
44
|
```sh
|
|
45
|
-
pnpm add unified-ble-manager@4.0.
|
|
45
|
+
pnpm add unified-ble-manager@4.0.11
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
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
|
-
This source targets `4.0.
|
|
13
|
+
This source targets `4.0.11`. Tagged releases ship 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/WEB.md
CHANGED
|
@@ -2,112 +2,252 @@
|
|
|
2
2
|
|
|
3
3
|
# Web Bluetooth
|
|
4
4
|
|
|
5
|
-
Use `unified-ble-manager/web` in a
|
|
5
|
+
Use `unified-ble-manager/web` to run the public UBM manager directly in a browser. The Web backend uses the browser’s device chooser instead of continuous scanning, then exposes the same connection and GATT handles as the other UBM hosts.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The complete runnable TypeScript/Vite application is in [`example-web/`](../example-web/).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This guide targets `4.0.11`. Web Bluetooth support still depends on the browser, operating system, adapter, and peripheral. UBM reports those runtime boundaries; it does not fabricate a fallback backend.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Use Chrome or another browser that implements Web Bluetooth.
|
|
14
|
+
- Serve the page over HTTPS. `http://localhost` is also treated as a secure development context.
|
|
15
|
+
- Start the system chooser from a click or another transient user activation.
|
|
16
|
+
- If the page is inside an iframe, its container must grant the `bluetooth` Permissions Policy.
|
|
17
|
+
- Keep the requested peripheral near the browser and ensure another central is not already occupying its connection.
|
|
18
|
+
|
|
19
|
+
Web Bluetooth does not provide UBM’s continuous `scan()` capability, background monitoring after the page closes, or process-level restoration. `manager.scan()` therefore rejects with `capability.unsupported`; use `manager.choose()` (often named `ble.choose()` in smaller examples).
|
|
20
|
+
|
|
21
|
+
## Install and create the manager
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pnpm add unified-ble-manager
|
|
25
|
+
```
|
|
10
26
|
|
|
11
27
|
```ts
|
|
12
28
|
import { createWebBleManager } from 'unified-ble-manager/web'
|
|
13
29
|
|
|
14
|
-
const
|
|
30
|
+
const manager = await createWebBleManager()
|
|
15
31
|
```
|
|
16
32
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Permissions Policy. Then connect and use the generation-bound GATT objects.
|
|
33
|
+
The factory returns the same host-neutral `BleManager` interface used elsewhere. Importing `unified-ble-manager/web` is explicit: failure to load Web Bluetooth never substitutes React Native, Node, a simulator, or a mock.
|
|
34
|
+
|
|
35
|
+
## Complete browser lifecycle
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
This example chooses a standard Heart Rate Service peripheral, grants optional access to Battery Service, connects, discovers GATT, reads Battery Level, and consumes Heart Rate notifications.
|
|
23
38
|
|
|
24
39
|
```ts
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
import { BleError, type BleManager } from 'unified-ble-manager'
|
|
41
|
+
import { createWebBleManager } from 'unified-ble-manager/web'
|
|
42
|
+
import {
|
|
43
|
+
BATTERY_LEVEL_CHARACTERISTIC,
|
|
44
|
+
BATTERY_SERVICE,
|
|
45
|
+
parseBatteryLevel
|
|
46
|
+
} from 'unified-ble-manager/profiles/battery-service'
|
|
47
|
+
import {
|
|
48
|
+
HEART_RATE_MEASUREMENT_CHARACTERISTIC,
|
|
49
|
+
HEART_RATE_SERVICE,
|
|
50
|
+
parseHeartRateMeasurement
|
|
51
|
+
} from 'unified-ble-manager/profiles/heart-rate'
|
|
52
|
+
|
|
53
|
+
let manager: BleManager | null = null
|
|
54
|
+
|
|
55
|
+
async function chooseReadAndSubscribe(): Promise<void> {
|
|
56
|
+
manager = await createWebBleManager()
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Keep this call directly in the click-handler path.
|
|
60
|
+
const peer = await manager.choose({
|
|
61
|
+
filters: [{ serviceUuids: [HEART_RATE_SERVICE] }],
|
|
62
|
+
optionalServices: [BATTERY_SERVICE],
|
|
63
|
+
timeoutMs: 60_000
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const connection = await manager.connect(peer, { timeoutMs: 60_000 })
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const gatt = await connection.discover({ timeoutMs: 20_000 })
|
|
70
|
+
|
|
71
|
+
const battery = gatt.characteristic(BATTERY_SERVICE, BATTERY_LEVEL_CHARACTERISTIC)
|
|
72
|
+
const batteryPercent = parseBatteryLevel(await battery.read({ timeoutMs: 10_000 }))
|
|
73
|
+
console.log('Battery', batteryPercent)
|
|
74
|
+
|
|
75
|
+
const heartRate = gatt.characteristic(HEART_RATE_SERVICE, HEART_RATE_MEASUREMENT_CHARACTERISTIC)
|
|
76
|
+
const subscription = await heartRate.subscribe({
|
|
77
|
+
timeoutMs: 10_000,
|
|
78
|
+
delivery: 'prefer-notification',
|
|
79
|
+
stream: 'balanced'
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
for await (const event of subscription.values) {
|
|
84
|
+
if (event.kind === 'value') {
|
|
85
|
+
const measurement = parseHeartRateMeasurement(event.value.value)
|
|
86
|
+
console.log('Heart rate', measurement.beatsPerMinute)
|
|
87
|
+
} else if (event.kind === 'overflow') {
|
|
88
|
+
console.warn('Dropped notification items', event.droppedItems)
|
|
89
|
+
} else {
|
|
90
|
+
console.log('Subscription ended', event.reason)
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} finally {
|
|
95
|
+
await subscription.remove()
|
|
70
96
|
}
|
|
97
|
+
} finally {
|
|
98
|
+
await connection.disconnect()
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error instanceof BleError) {
|
|
102
|
+
console.error({
|
|
103
|
+
code: error.code,
|
|
104
|
+
domain: error.domain,
|
|
105
|
+
operation: error.operation,
|
|
106
|
+
browserCause: error.platform?.metadata.browserErrorName,
|
|
107
|
+
recovery: error.recovery
|
|
108
|
+
})
|
|
71
109
|
}
|
|
110
|
+
throw error
|
|
111
|
+
} finally {
|
|
112
|
+
await manager.destroy()
|
|
113
|
+
manager = null
|
|
72
114
|
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
document.querySelector('#connect')?.addEventListener('click', () => {
|
|
118
|
+
void chooseReadAndSubscribe()
|
|
73
119
|
})
|
|
74
120
|
```
|
|
75
121
|
|
|
76
|
-
|
|
122
|
+
For an application with separate Connect, Disconnect, Reconnect, and Destroy controls, use the runnable [`example-web/src/main.ts`](../example-web/src/main.ts).
|
|
77
123
|
|
|
78
|
-
##
|
|
124
|
+
## Filters and service permission
|
|
79
125
|
|
|
80
|
-
|
|
126
|
+
Chooser `filters` decide which devices the browser may display. Separate filter objects are OR branches; the fields inside one filter are AND constraints.
|
|
81
127
|
|
|
82
128
|
```ts
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
import { createWebBleManager } from 'unified-ble-manager/web'
|
|
86
|
-
|
|
87
|
-
const ble = await createWebBleManager()
|
|
88
|
-
|
|
89
|
-
const peer = await ble.choose({
|
|
90
|
-
filters: [{ serviceUuids: [HEART_RATE_SERVICE] }],
|
|
129
|
+
const peer = await manager.choose({
|
|
130
|
+
filters: [{ serviceUuids: [HEART_RATE_SERVICE], namePrefix: 'My device' }],
|
|
91
131
|
optionalServices: [BATTERY_SERVICE],
|
|
92
|
-
timeoutMs:
|
|
132
|
+
timeoutMs: 60_000
|
|
93
133
|
})
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`optionalServices` grants later GATT access to services that were not part of the matching filter. It accepts service UUIDs, not characteristic UUIDs. Request every service the application will access, but do not request unrelated services.
|
|
137
|
+
|
|
138
|
+
The chooser itself belongs to the browser. UBM cannot auto-select a new device, extend the browser’s native discovery UI, or tell whether Chrome’s `NotFoundError` came from an explicit Cancel action versus the chooser closing without a compatible selection. UBM preserves the browser cause in `error.platform` and reports the stable public code `chooser.cancelled`.
|
|
94
139
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
140
|
+
## Previously authorized devices
|
|
141
|
+
|
|
142
|
+
When the browser exposes `navigator.bluetooth.getDevices()`, UBM projects those origin grants through the peer directory:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
const manager = await createWebBleManager()
|
|
146
|
+
const authorized = await manager.peers.authorized({ timeoutMs: 10_000 })
|
|
147
|
+
|
|
148
|
+
if (authorized.length === 1) {
|
|
149
|
+
const connection = await manager.connect(authorized[0], { timeoutMs: 60_000 })
|
|
150
|
+
await connection.disconnect()
|
|
151
|
+
}
|
|
99
152
|
```
|
|
100
153
|
|
|
101
|
-
|
|
154
|
+
An authorized Web peer means the current origin has permission to address that browser device. It is not an Android-style system bond, proof that the device is nearby, or proof that another central is not connected. Do not guess when several authorized peers exist; ask the user to choose explicitly or use an application-owned persisted `PeerReference` and `manager.peers.resolve()`.
|
|
155
|
+
|
|
156
|
+
Origin authorization can survive a reload, but an in-memory peer or connection handle cannot. Create a new manager after reload and query or resolve the peer again.
|
|
157
|
+
|
|
158
|
+
## Deadlines, cancellation, and safe retry
|
|
102
159
|
|
|
103
|
-
|
|
160
|
+
All public operations accept `timeoutMs`; cancellable operations also accept `signal`. Each timeout applies to that operation, not to an entire multi-step journey.
|
|
104
161
|
|
|
105
162
|
```ts
|
|
106
|
-
|
|
163
|
+
const abort = new AbortController()
|
|
164
|
+
const connection = await manager.connect(peer, {
|
|
165
|
+
signal: abort.signal,
|
|
166
|
+
timeoutMs: 60_000
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
There is one important browser boundary: `BluetoothRemoteGATTServer.connect()` returns a native promise with no cancellation API. If `manager.connect()` reaches its deadline, UBM reports `operation.timed-out` but retains pending ownership so a second native connection cannot race the first one.
|
|
171
|
+
|
|
172
|
+
Do not immediately call `connect()` again on that same manager and peer. That correctly fails with `connection.already-owned`. Instead, destroy the manager, await cleanup, then start a fresh user-driven attempt:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
try {
|
|
176
|
+
await manager.connect(peer, { timeoutMs: 60_000 })
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (
|
|
179
|
+
error instanceof BleError &&
|
|
180
|
+
error.code === 'operation.timed-out' &&
|
|
181
|
+
error.operation === 'web-connection.connect'
|
|
182
|
+
) {
|
|
183
|
+
await manager.destroy()
|
|
184
|
+
manager = await createWebBleManager()
|
|
185
|
+
}
|
|
186
|
+
throw error
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Destroy compensation also handles a late native success by disconnecting it. Clearing ownership early would permit overlapping browser connections and is intentionally not supported.
|
|
191
|
+
|
|
192
|
+
## Notifications and cleanup
|
|
193
|
+
|
|
194
|
+
Subscription values are a bounded async stream. Handle all three event kinds:
|
|
195
|
+
|
|
196
|
+
- `value`: a notification or indication payload;
|
|
197
|
+
- `overflow`: visible data loss because the consumer did not drain fast enough;
|
|
198
|
+
- `terminal`: the stream ended because of removal, disconnect, adapter loss, or teardown.
|
|
199
|
+
|
|
200
|
+
Release resources from the inside out:
|
|
201
|
+
|
|
202
|
+
1. `await subscription.remove()`;
|
|
203
|
+
2. `await connection.disconnect()`;
|
|
204
|
+
3. `await manager.destroy()`.
|
|
205
|
+
|
|
206
|
+
Each cleanup returns a receipt. Production applications should verify `state === 'released'` and preserve any reported cleanup failures. Also destroy the manager during page teardown as a best-effort safeguard, while keeping primary cleanup in explicit application actions.
|
|
207
|
+
|
|
208
|
+
## Errors users can act on
|
|
209
|
+
|
|
210
|
+
Catch `BleError` from the root package and retain its structured fields. Do not replace every failure with one generic message.
|
|
211
|
+
|
|
212
|
+
| Field | Meaning |
|
|
213
|
+
| ----------- | ---------------------------------------------------------------------------------------------- |
|
|
214
|
+
| `code` | Stable UBM category such as `chooser.cancelled`, `operation.timed-out`, or `connection.failed` |
|
|
215
|
+
| `domain` | UBM subsystem such as `chooser`, `connection`, or `gatt` |
|
|
216
|
+
| `operation` | Exact operation boundary, for example `web-connection.connect` |
|
|
217
|
+
| `platform` | Safe browser detail, including `browserErrorName` when Chrome supplies one |
|
|
218
|
+
| `recovery` | Deterministic recovery disposition and suggested actions |
|
|
219
|
+
|
|
220
|
+
Common boundaries:
|
|
221
|
+
|
|
222
|
+
- `chooser.cancelled` + `NotFoundError`: the chooser ended without returning a compatible device;
|
|
223
|
+
- `connection.failed` + `NetworkError`: Chrome selected the device but could not open GATT;
|
|
224
|
+
- `operation.timed-out` at `web-connection.connect`: the bounded native connection did not settle;
|
|
225
|
+
- `gatt.not-found`: the connection opened, but a requested service or characteristic was unavailable or not granted;
|
|
226
|
+
- `operation.disconnected`: the link ended during another operation.
|
|
227
|
+
|
|
228
|
+
## Iframes and deployment
|
|
229
|
+
|
|
230
|
+
A top-level HTTPS page needs no extra header. An embedded application needs its container to allow Bluetooth, for example:
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<iframe src="https://example.test/app" allow="bluetooth"></iframe>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The embedding server may also restrict or grant access using the `Permissions-Policy` response header. Browser and administrator policies can still disable Web Bluetooth.
|
|
237
|
+
|
|
238
|
+
## Testing
|
|
239
|
+
|
|
240
|
+
Application tests should inject `createWebBleManagerWithEnvironment()` only at a test boundary. Production code should use `createWebBleManager()`.
|
|
241
|
+
|
|
242
|
+
The repository example builds against the public package entrypoints:
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
pnpm build:example:web
|
|
246
|
+
pnpm example:web
|
|
107
247
|
```
|
|
108
248
|
|
|
109
|
-
A
|
|
249
|
+
Open <http://localhost:5173>. A successful local run is useful evidence, but it is not by itself a cross-browser or cross-platform support claim.
|
|
110
250
|
|
|
111
251
|
## Maintainers
|
|
112
252
|
|
|
113
|
-
[`UNIFIED_BLE_4.0_IMPLEMENTATION_PLAN.md`](UNIFIED_BLE_4.0_IMPLEMENTATION_PLAN.md)
|
|
253
|
+
See [`PLATFORMS.md`](PLATFORMS.md), [`PEERS.md`](PEERS.md), and [`UNIFIED_BLE_4.0_IMPLEMENTATION_PLAN.md`](UNIFIED_BLE_4.0_IMPLEMENTATION_PLAN.md).
|
|
@@ -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.11`
|
|
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
|
|
|
@@ -7,5 +7,5 @@ exports.UNIFIED_BLE_IMPLEMENTATION_VERSION = void 0;
|
|
|
7
7
|
// src/implementation-version.ts
|
|
8
8
|
|
|
9
9
|
/** The one production version stamped into every first-party backend identity. */
|
|
10
|
-
const UNIFIED_BLE_IMPLEMENTATION_VERSION = exports.UNIFIED_BLE_IMPLEMENTATION_VERSION = '4.0.
|
|
10
|
+
const UNIFIED_BLE_IMPLEMENTATION_VERSION = exports.UNIFIED_BLE_IMPLEMENTATION_VERSION = '4.0.11';
|
|
11
11
|
//# sourceMappingURL=implementation-version.js.map
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
// src/implementation-version.ts
|
|
4
4
|
|
|
5
5
|
/** The one production version stamped into every first-party backend identity. */
|
|
6
|
-
export const UNIFIED_BLE_IMPLEMENTATION_VERSION = '4.0.
|
|
6
|
+
export const UNIFIED_BLE_IMPLEMENTATION_VERSION = '4.0.11';
|
|
7
7
|
//# sourceMappingURL=implementation-version.js.map
|
|
@@ -4,7 +4,7 @@ import { type BackendCompatibilityOffer } from '../../backend-contract/primitive
|
|
|
4
4
|
import { type BluezBusKind, type BluezDbusBoundaryFactory } from './bluez-dbus-contract';
|
|
5
5
|
export declare const BLUEZ_BACKEND_ID = "unified-ble:bluez-dbus";
|
|
6
6
|
export declare const BLUEZ_PLATFORM_ID = "unified-ble:linux-bluez";
|
|
7
|
-
export declare const BLUEZ_IMPLEMENTATION_VERSION = "4.0.
|
|
7
|
+
export declare const BLUEZ_IMPLEMENTATION_VERSION = "4.0.11";
|
|
8
8
|
export declare const bluezCompatibility: BackendCompatibilityOffer;
|
|
9
9
|
export interface BluezBackendProviderOptions {
|
|
10
10
|
readonly busKind: BluezBusKind;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type FeatureRegistry } from '../../backend-contract/capabilities';
|
|
2
2
|
export declare const COREBLUETOOTH_BACKEND_ID = "unified-ble:corebluetooth";
|
|
3
3
|
export declare const COREBLUETOOTH_PLATFORM_ID = "unified-ble:macos-corebluetooth";
|
|
4
|
-
export declare const COREBLUETOOTH_IMPLEMENTATION_VERSION = "4.0.
|
|
4
|
+
export declare const COREBLUETOOTH_IMPLEMENTATION_VERSION = "4.0.11";
|
|
5
5
|
/** Identity metadata for a direct-GATT boundary that shares this backend core. */
|
|
6
6
|
export interface DirectGattBackendIdentityOptions {
|
|
7
7
|
readonly registeredBackendId: string;
|
|
@@ -9,7 +9,7 @@ import { ReactNativeAndroidProtocolBoundary } from '../../native-protocol/rn-and
|
|
|
9
9
|
import { ReactNativeRestorationCoordinator, type ReactNativeRestorationActivation, type ReactNativeRestorationBackendProvider } from './react-native-restoration';
|
|
10
10
|
export declare const REACT_NATIVE_ANDROID_BACKEND_ID = "unified-ble:react-native-android";
|
|
11
11
|
export declare const REACT_NATIVE_ANDROID_PLATFORM_ID = "unified-ble:android-gatt";
|
|
12
|
-
export declare const REACT_NATIVE_ANDROID_IMPLEMENTATION_VERSION = "4.0.
|
|
12
|
+
export declare const REACT_NATIVE_ANDROID_IMPLEMENTATION_VERSION = "4.0.11";
|
|
13
13
|
export declare const REACT_NATIVE_ANDROID_DEFAULT_ADAPTER_NATIVE_ID = "android-default-adapter";
|
|
14
14
|
export declare const reactNativeAndroidCompatibility: NativeCompatibilityOffer;
|
|
15
15
|
export interface ReactNativeAndroidBackendProviderOptions {
|
|
@@ -3,7 +3,7 @@ import type { Spec as NativeProtocolControl } from '../../NativeUnifiedBleProtoc
|
|
|
3
3
|
import { type ReactNativeRestorationBackendProvider } from './react-native-restoration';
|
|
4
4
|
export declare const REACT_NATIVE_APPLE_BACKEND_ID = "unified-ble:react-native-apple";
|
|
5
5
|
export declare const REACT_NATIVE_APPLE_PLATFORM_ID = "unified-ble:apple-corebluetooth";
|
|
6
|
-
export declare const REACT_NATIVE_APPLE_IMPLEMENTATION_VERSION = "4.0.
|
|
6
|
+
export declare const REACT_NATIVE_APPLE_IMPLEMENTATION_VERSION = "4.0.11";
|
|
7
7
|
export declare const REACT_NATIVE_APPLE_DEFAULT_ADAPTER_NATIVE_ID = "apple-corebluetooth-default-adapter";
|
|
8
8
|
export declare const reactNativeAppleCompatibility: NativeCompatibilityOffer;
|
|
9
9
|
export interface ReactNativeAppleBackendProviderOptions {
|
|
@@ -3,7 +3,7 @@ import { type BackendCompatibilityOffer } from '../../backend-contract/primitive
|
|
|
3
3
|
import { type WinRtAdapterRecord, type WinRtBoundary } from './winrt-boundary';
|
|
4
4
|
export declare const WINRT_BACKEND_ID = "unified-ble:winrt";
|
|
5
5
|
export declare const WINRT_PLATFORM_ID = "unified-ble:windows-winrt";
|
|
6
|
-
export declare const WINRT_IMPLEMENTATION_VERSION = "4.0.
|
|
6
|
+
export declare const WINRT_IMPLEMENTATION_VERSION = "4.0.11";
|
|
7
7
|
export declare const winRtCompatibility: BackendCompatibilityOffer;
|
|
8
8
|
export interface WinRtBackendProviderOptions {
|
|
9
9
|
readonly boundaryFactory: () => WinRtBoundary;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** The one production version stamped into every first-party backend identity. */
|
|
2
|
-
export declare const UNIFIED_BLE_IMPLEMENTATION_VERSION = "4.0.
|
|
2
|
+
export declare const UNIFIED_BLE_IMPLEMENTATION_VERSION = "4.0.11";
|
|
3
3
|
//# sourceMappingURL=implementation-version.d.ts.map
|
|
@@ -4,7 +4,7 @@ import { type BackendCompatibilityOffer } from '../../backend-contract/primitive
|
|
|
4
4
|
import { type BluezBusKind, type BluezDbusBoundaryFactory } from './bluez-dbus-contract.js';
|
|
5
5
|
export declare const BLUEZ_BACKEND_ID = "unified-ble:bluez-dbus";
|
|
6
6
|
export declare const BLUEZ_PLATFORM_ID = "unified-ble:linux-bluez";
|
|
7
|
-
export declare const BLUEZ_IMPLEMENTATION_VERSION = "4.0.
|
|
7
|
+
export declare const BLUEZ_IMPLEMENTATION_VERSION = "4.0.11";
|
|
8
8
|
export declare const bluezCompatibility: BackendCompatibilityOffer;
|
|
9
9
|
export interface BluezBackendProviderOptions {
|
|
10
10
|
readonly busKind: BluezBusKind;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type FeatureRegistry } from '../../backend-contract/capabilities.js';
|
|
2
2
|
export declare const COREBLUETOOTH_BACKEND_ID = "unified-ble:corebluetooth";
|
|
3
3
|
export declare const COREBLUETOOTH_PLATFORM_ID = "unified-ble:macos-corebluetooth";
|
|
4
|
-
export declare const COREBLUETOOTH_IMPLEMENTATION_VERSION = "4.0.
|
|
4
|
+
export declare const COREBLUETOOTH_IMPLEMENTATION_VERSION = "4.0.11";
|
|
5
5
|
/** Identity metadata for a direct-GATT boundary that shares this backend core. */
|
|
6
6
|
export interface DirectGattBackendIdentityOptions {
|
|
7
7
|
readonly registeredBackendId: string;
|
|
@@ -9,7 +9,7 @@ import { ReactNativeAndroidProtocolBoundary } from '../../native-protocol/rn-and
|
|
|
9
9
|
import { ReactNativeRestorationCoordinator, type ReactNativeRestorationActivation, type ReactNativeRestorationBackendProvider } from './react-native-restoration.js';
|
|
10
10
|
export declare const REACT_NATIVE_ANDROID_BACKEND_ID = "unified-ble:react-native-android";
|
|
11
11
|
export declare const REACT_NATIVE_ANDROID_PLATFORM_ID = "unified-ble:android-gatt";
|
|
12
|
-
export declare const REACT_NATIVE_ANDROID_IMPLEMENTATION_VERSION = "4.0.
|
|
12
|
+
export declare const REACT_NATIVE_ANDROID_IMPLEMENTATION_VERSION = "4.0.11";
|
|
13
13
|
export declare const REACT_NATIVE_ANDROID_DEFAULT_ADAPTER_NATIVE_ID = "android-default-adapter";
|
|
14
14
|
export declare const reactNativeAndroidCompatibility: NativeCompatibilityOffer;
|
|
15
15
|
export interface ReactNativeAndroidBackendProviderOptions {
|
|
@@ -3,7 +3,7 @@ import type { Spec as NativeProtocolControl } from '../../NativeUnifiedBleProtoc
|
|
|
3
3
|
import { type ReactNativeRestorationBackendProvider } from './react-native-restoration.js';
|
|
4
4
|
export declare const REACT_NATIVE_APPLE_BACKEND_ID = "unified-ble:react-native-apple";
|
|
5
5
|
export declare const REACT_NATIVE_APPLE_PLATFORM_ID = "unified-ble:apple-corebluetooth";
|
|
6
|
-
export declare const REACT_NATIVE_APPLE_IMPLEMENTATION_VERSION = "4.0.
|
|
6
|
+
export declare const REACT_NATIVE_APPLE_IMPLEMENTATION_VERSION = "4.0.11";
|
|
7
7
|
export declare const REACT_NATIVE_APPLE_DEFAULT_ADAPTER_NATIVE_ID = "apple-corebluetooth-default-adapter";
|
|
8
8
|
export declare const reactNativeAppleCompatibility: NativeCompatibilityOffer;
|
|
9
9
|
export interface ReactNativeAppleBackendProviderOptions {
|
|
@@ -3,7 +3,7 @@ import { type BackendCompatibilityOffer } from '../../backend-contract/primitive
|
|
|
3
3
|
import { type WinRtAdapterRecord, type WinRtBoundary } from './winrt-boundary.js';
|
|
4
4
|
export declare const WINRT_BACKEND_ID = "unified-ble:winrt";
|
|
5
5
|
export declare const WINRT_PLATFORM_ID = "unified-ble:windows-winrt";
|
|
6
|
-
export declare const WINRT_IMPLEMENTATION_VERSION = "4.0.
|
|
6
|
+
export declare const WINRT_IMPLEMENTATION_VERSION = "4.0.11";
|
|
7
7
|
export declare const winRtCompatibility: BackendCompatibilityOffer;
|
|
8
8
|
export interface WinRtBackendProviderOptions {
|
|
9
9
|
readonly boundaryFactory: () => WinRtBoundary;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** The one production version stamped into every first-party backend identity. */
|
|
2
|
-
export declare const UNIFIED_BLE_IMPLEMENTATION_VERSION = "4.0.
|
|
2
|
+
export declare const UNIFIED_BLE_IMPLEMENTATION_VERSION = "4.0.11";
|
|
3
3
|
//# sourceMappingURL=implementation-version.d.ts.map
|
package/native/PREBUILDS.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"package": "unified-ble-manager@4.0.
|
|
3
|
+
"package": "unified-ble-manager@4.0.11",
|
|
4
4
|
"nodeApiVersion": 8,
|
|
5
5
|
"entries": [
|
|
6
6
|
{
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"nodeApiVersion": 8,
|
|
11
11
|
"path": "native/electron/corebluetooth/prebuilds/darwin-arm64/unified_ble_corebluetooth.node",
|
|
12
12
|
"bytes": 332368,
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "a92a962daa5414838ebdfd2ac4af42eea610856839099425a5906e8550537bc2"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"backend": "corebluetooth",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"nodeApiVersion": 8,
|
|
20
20
|
"path": "native/electron/corebluetooth/prebuilds/darwin-x64/unified_ble_corebluetooth.node",
|
|
21
21
|
"bytes": 314872,
|
|
22
|
-
"sha256": "
|
|
22
|
+
"sha256": "592b048bcc6288066ce199bfdc55ce5fe36e40539bc6cbd8db90dc0b541d975e"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"backend": "winrt",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"nodeApiVersion": 8,
|
|
29
29
|
"path": "native/electron/winrt/prebuilds/win32-arm64/unified_ble_winrt.node",
|
|
30
30
|
"bytes": 644608,
|
|
31
|
-
"sha256": "
|
|
31
|
+
"sha256": "c16ed73cc4600077e1eae1fd94e264b826c729b8cdb3b6a74b29e9a457327b9d"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"backend": "winrt",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"nodeApiVersion": 8,
|
|
38
38
|
"path": "native/electron/winrt/prebuilds/win32-x64/unified_ble_winrt.node",
|
|
39
39
|
"bytes": 614400,
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "e617546d3b1b3f71f583cd27fcf5f5cd4923e4eee08f0ad66fd864fabb6215c1"
|
|
41
41
|
}
|
|
42
42
|
]
|
|
43
43
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unified-ble-manager",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
4
4
|
"description": "Unified Bluetooth Low Energy manager for React Native, Electron, Tauri, Web, and desktop",
|
|
5
5
|
"packageManager": "pnpm@10.14.0",
|
|
6
6
|
"main": "lib/commonjs/index.js",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"native-prebuild:build": "node scripts/native-prebuilds/build.js",
|
|
101
101
|
"native-prebuild:verify": "node scripts/native-prebuilds/verify.js",
|
|
102
102
|
"example:electron": "pnpm prepack && node example-electron/smoke.js",
|
|
103
|
-
"build:example:web": "
|
|
104
|
-
"example:web": "pnpm prepack &&
|
|
103
|
+
"build:example:web": "tsc --noEmit -p example-web/tsconfig.json && vite build --config example-web/vite.config.mts",
|
|
104
|
+
"example:web": "pnpm prepack && vite --config example-web/vite.config.mts",
|
|
105
105
|
"prepare": "pnpm clean:plugin && pnpm build:plugin && pnpm exec bob build",
|
|
106
106
|
"lint:plugin": "eslint plugin/src/*"
|
|
107
107
|
},
|
|
@@ -188,6 +188,7 @@
|
|
|
188
188
|
"styled-components": "^6.1.11",
|
|
189
189
|
"turbo": "^1.10.7",
|
|
190
190
|
"typescript": "^5.2.2",
|
|
191
|
+
"vite": "^8.2.2",
|
|
191
192
|
"webpack": "5.109.2",
|
|
192
193
|
"yaml": "2.9.0"
|
|
193
194
|
},
|