node-red-contrib-ble-scanner 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 node-red-contrib
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # node-red-contrib-ble-scanner
2
+
3
+ Strict TypeScript Node.js library, CLI, and Node-RED nodes for collecting raw Bluetooth LE notification messages.
4
+
5
+ The package supports two BLE backend implementations:
6
+
7
+ - `auto`: uses BlueZ on Linux when available, otherwise noble
8
+ - `bluez`: uses Linux BlueZ over D-Bus
9
+ - `noble`: uses `@abandonware/noble`
10
+
11
+ ## Library
12
+
13
+ The package exports a typed ESM API from `dist/index.js`:
14
+
15
+ - `discoverDevices(options)` returns matching BLE devices
16
+ - `readDevices(options)` discovers, connects, subscribes, and collects raw notifications
17
+ - `readDevice(device, options)` reads one discovered device
18
+ - `connectReaders(options)` discovers and connects once, then returns persistent readers with `read()` and `disconnect()`
19
+ - `shutdownBluetooth()` stops active BLE sessions
20
+
21
+ Each reading contains device metadata, a timestamp, the subscribed notification characteristic UUID, and a `messages` array. Every raw message includes the original Buffer as `data` plus `hex`, `base64`, `bytes`, `length`, and `timestamp`.
22
+
23
+ ```js
24
+ import { connectReaders } from 'node-red-contrib-ble-scanner';
25
+
26
+ const readers = await connectReaders({
27
+ deviceName: 'My BLE Device',
28
+ scanServiceUuid: 'fff0',
29
+ matchServiceUuid: 'fff0',
30
+ notifyUuid: 'fff1',
31
+ listenMs: 5000
32
+ });
33
+
34
+ try {
35
+ const reading = await readers[0].read();
36
+ console.log(reading.messages.map((message) => message.hex));
37
+ } finally {
38
+ await Promise.all(readers.map((reader) => reader.disconnect()));
39
+ }
40
+ ```
41
+
42
+ ## Nodes
43
+
44
+ - `ble-reader-device`: config node for BLE discovery, device selection, and notification UUID
45
+ - `ble-reader-read`: input node that collects raw notifications
46
+
47
+ Use the config node's search button to discover devices from the Node-RED editor. Select one exact advertised device name, or keep "All discovered devices".
48
+
49
+ The output is placed in `msg.payload` as an array with zero, one, or multiple readings.
50
+
51
+ Incoming `msg.payload` may contain `{ deviceName, listenMs, serviceUuid, notifyUuid }` to override the configured values for one read.
52
+
53
+ ## CLI
54
+
55
+ ```sh
56
+ npm install
57
+ npm run build
58
+ npm run discover
59
+ npm run read
60
+ ```
61
+
62
+ Useful options:
63
+
64
+ ```sh
65
+ node ./bin/ble-reader.js discover
66
+ node ./bin/ble-reader.js discover --name-prefix SK
67
+ node ./bin/ble-reader.js discover --service-uuid fff0
68
+ node ./bin/ble-reader.js read "My BLE Device" --notify-uuid fff1 --listen-ms 5000
69
+ node ./bin/ble-reader.js read --bluetooth bluez --debug
70
+ node ./bin/ble-reader.js read "My BLE Device" --interval 5
71
+ ```
72
+
73
+ `read --interval 5` keeps the BLE session open and collects notifications every five seconds until stopped.
74
+
75
+ ## Development
76
+
77
+ ```sh
78
+ npm run build
79
+ npm run lint
80
+ npm test
81
+ npm run check
82
+ ```
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../dist/cli.js';
3
+
4
+ main()
5
+ .then(() => {
6
+ process.exit(process.exitCode ?? 0);
7
+ })
8
+ .catch((error) => {
9
+ console.error(error?.stack || error?.message || String(error));
10
+ process.exit(1);
11
+ });
@@ -0,0 +1,82 @@
1
+ export type BluetoothBackendName = 'auto' | 'bluez' | 'noble';
2
+ export type ResolvedBluetoothBackendName = Exclude<BluetoothBackendName, 'auto'>;
3
+ export type Logger = (message: string) => void;
4
+ export interface BleDiscoveredDevice {
5
+ id: string;
6
+ name: string | null;
7
+ address: string | null;
8
+ addressType?: string | null;
9
+ rssi: number | null;
10
+ backend: ResolvedBluetoothBackendName;
11
+ }
12
+ export interface RawBleMessage {
13
+ timestamp: string;
14
+ uuid: string;
15
+ length: number;
16
+ data: Buffer;
17
+ hex: string;
18
+ base64: string;
19
+ bytes: number[];
20
+ }
21
+ export interface BleReading {
22
+ device: BleDiscoveredDevice;
23
+ timestamp: string;
24
+ notifyUuid: string;
25
+ messages: RawBleMessage[];
26
+ }
27
+ export interface ReadOptions {
28
+ bluetooth?: BluetoothBackendName;
29
+ namePrefix?: string;
30
+ deviceName?: string;
31
+ timeoutMs?: number;
32
+ listenMs?: number;
33
+ connectTimeoutMs?: number;
34
+ notifyUuid?: string;
35
+ scanServiceUuid?: string | null;
36
+ matchServiceUuid?: string | null;
37
+ logger?: Logger;
38
+ }
39
+ export interface DiscoverOptions {
40
+ bluetooth?: BluetoothBackendName;
41
+ namePrefix?: string;
42
+ deviceName?: string;
43
+ timeoutMs?: number;
44
+ scanServiceUuid?: string | null;
45
+ matchServiceUuid?: string | null;
46
+ logger?: Logger;
47
+ }
48
+ export interface ResolvedDiscoverOptions {
49
+ namePrefix: string;
50
+ deviceName: string | null;
51
+ timeoutMs: number;
52
+ scanServiceUuid: string | null;
53
+ matchServiceUuid: string | null;
54
+ logger: Logger;
55
+ }
56
+ export interface ResolvedConnectOptions {
57
+ device: BleDiscoveredDevice;
58
+ timeoutMs: number;
59
+ connectTimeoutMs: number;
60
+ notifyUuid: string;
61
+ logger: Logger;
62
+ }
63
+ export interface BleCharacteristic {
64
+ uuid: string;
65
+ properties: string[];
66
+ write(data: Buffer, withoutResponse?: boolean): Promise<void>;
67
+ subscribe(): Promise<void>;
68
+ onData(listener: (data: Buffer) => void): void;
69
+ removeDataListener(listener: (data: Buffer) => void): void;
70
+ }
71
+ export interface BleSession {
72
+ device: BleDiscoveredDevice;
73
+ notify: BleCharacteristic;
74
+ disconnect(): Promise<void>;
75
+ }
76
+ export interface BluetoothBackend {
77
+ name: ResolvedBluetoothBackendName;
78
+ isAvailable(logger?: Logger): Promise<boolean>;
79
+ discover(options: ResolvedDiscoverOptions): Promise<BleDiscoveredDevice[]>;
80
+ connect(options: ResolvedConnectOptions): Promise<BleSession>;
81
+ shutdown(): Promise<void>;
82
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/ble/backend.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { BluetoothBackend, Logger } from './backend.js';
2
+ type BluezVariantConstructor = new (signature: string, value: unknown) => unknown;
3
+ interface BluezAdapter {
4
+ StartDiscovery(): Promise<void>;
5
+ StopDiscovery(): Promise<void>;
6
+ SetDiscoveryFilter(filter: Record<string, unknown>): Promise<void>;
7
+ }
8
+ export declare const bluezBackend: BluetoothBackend;
9
+ export declare function setBluezDiscoveryFilter(adapter: BluezAdapter, Variant: BluezVariantConstructor, serviceUuid: string | null, logger: Logger): Promise<void>;
10
+ export {};
@@ -0,0 +1,317 @@
1
+ import { createRequire } from 'node:module';
2
+ import { setTimeout as delay } from 'node:timers/promises';
3
+ import { errorMessage, formatCanonicalUuid, matchesBleDevice, normalizeUuid, nullableNumber, nullableString, unboxBluezValue, uniqueDevices } from './utils.js';
4
+ const requireOptional = createRequire(import.meta.url);
5
+ const DISCOVERY_POLL_MS = 500;
6
+ let activeSessions = new Set();
7
+ export const bluezBackend = {
8
+ name: 'bluez',
9
+ isAvailable: isBluezAvailable,
10
+ discover: discoverBluezDevices,
11
+ connect: connectBluezDevice,
12
+ shutdown: shutdownBluez
13
+ };
14
+ async function isBluezAvailable(logger = () => { }) {
15
+ if (process.platform !== 'linux')
16
+ return false;
17
+ try {
18
+ const { systemBus } = loadDbusNext();
19
+ const bus = systemBus();
20
+ try {
21
+ const object = await bus.getProxyObject('org.bluez', '/');
22
+ const objectManager = object.getInterface('org.freedesktop.DBus.ObjectManager');
23
+ const objects = await objectManager.GetManagedObjects();
24
+ return findBluezAdapterPath(objects) !== null;
25
+ }
26
+ finally {
27
+ bus.disconnect();
28
+ }
29
+ }
30
+ catch (error) {
31
+ logger(`BlueZ backend is not available: ${errorMessage(error)}.`);
32
+ return false;
33
+ }
34
+ }
35
+ async function discoverBluezDevices(options) {
36
+ if (process.platform !== 'linux')
37
+ throw new Error('BlueZ backend is only available on Linux.');
38
+ const { systemBus, Variant } = loadDbusNext();
39
+ const bus = systemBus();
40
+ try {
41
+ const { objectManager, adapter } = await openBluezAdapter(bus);
42
+ const canonicalScanServiceUuid = options.scanServiceUuid ? formatCanonicalUuid(options.scanServiceUuid) : null;
43
+ if (options.deviceName) {
44
+ const cachedMatches = uniqueDevices(findBluezDevices(await objectManager.GetManagedObjects(), options));
45
+ if (cachedMatches.length > 0) {
46
+ options.logger(`BlueZ found ${cachedMatches[0].name || cachedMatches[0].address || cachedMatches[0].id} in managed objects.`);
47
+ return cachedMatches;
48
+ }
49
+ }
50
+ await setBluezDiscoveryFilter(adapter, Variant, canonicalScanServiceUuid, options.logger);
51
+ await adapter.StartDiscovery();
52
+ options.logger(`BlueZ discovery started. Waiting ${options.timeoutMs}ms.`);
53
+ const devices = [];
54
+ const startedAt = Date.now();
55
+ try {
56
+ while (Date.now() - startedAt < options.timeoutMs) {
57
+ const objects = await objectManager.GetManagedObjects();
58
+ devices.push(...findBluezDevices(objects, options));
59
+ if (options.deviceName && devices.length > 0)
60
+ break;
61
+ await delay(DISCOVERY_POLL_MS);
62
+ }
63
+ }
64
+ finally {
65
+ await adapter.StopDiscovery().catch((error) => options.logger(`Warning: could not stop BlueZ discovery: ${errorMessage(error)}.`));
66
+ }
67
+ return uniqueDevices(devices);
68
+ }
69
+ finally {
70
+ bus.disconnect();
71
+ }
72
+ }
73
+ async function connectBluezDevice({ device, timeoutMs, connectTimeoutMs, notifyUuid, logger }) {
74
+ if (process.platform !== 'linux')
75
+ throw new Error('BlueZ backend is only available on Linux.');
76
+ const { systemBus } = loadDbusNext();
77
+ const bus = systemBus();
78
+ try {
79
+ const objectManagerObject = await bus.getProxyObject('org.bluez', '/');
80
+ const objectManager = objectManagerObject.getInterface('org.freedesktop.DBus.ObjectManager');
81
+ let objects = await objectManager.GetManagedObjects();
82
+ let target = findBluezDeviceByDiscovered(objects, device);
83
+ if (!target) {
84
+ const matches = await discoverBluezDevices({
85
+ namePrefix: '',
86
+ deviceName: device.name,
87
+ timeoutMs,
88
+ scanServiceUuid: null,
89
+ matchServiceUuid: null,
90
+ logger
91
+ });
92
+ const refreshed = matches.find((match) => match.name === device.name || match.address === device.address || match.id === device.id);
93
+ if (!refreshed)
94
+ throw new Error(`Could not rediscover ${device.name || device.address || device.id}.`);
95
+ objects = await objectManager.GetManagedObjects();
96
+ target = findBluezDeviceByDiscovered(objects, refreshed);
97
+ }
98
+ if (!target)
99
+ throw new Error(`Could not find ${device.name || device.address || device.id} in BlueZ managed objects.`);
100
+ logger(`BlueZ connecting to ${target.address || '<unknown address>'} at ${target.path}.`);
101
+ const deviceObject = await bus.getProxyObject('org.bluez', target.path);
102
+ const bluezDevice = deviceObject.getInterface('org.bluez.Device1');
103
+ const deviceProperties = deviceObject.getInterface('org.freedesktop.DBus.Properties');
104
+ if (!(await getBluezBoolean(deviceProperties, 'org.bluez.Device1', 'Connected'))) {
105
+ await withTimeout(bluezDevice.Connect(), connectTimeoutMs, 'BlueZ Device1.Connect()');
106
+ }
107
+ await waitForBluezBooleanProperty(deviceProperties, 'org.bluez.Device1', 'ServicesResolved', true, timeoutMs);
108
+ logger('BlueZ connected and services resolved.');
109
+ const refreshedObjects = await objectManager.GetManagedObjects();
110
+ const characteristics = await buildBluezCharacteristics({ bus, objects: refreshedObjects, devicePath: target.path, notifyUuid, logger });
111
+ await characteristics.notify.subscribe();
112
+ logger(`Subscribed to BLE notification characteristic ${characteristics.notify.uuid} via BlueZ.`);
113
+ const session = {
114
+ device: toDiscoveredDevice(target.path, refreshedObjects[target.path]?.['org.bluez.Device1'] || {}, 'bluez'),
115
+ notify: characteristics.notify,
116
+ disconnect: async () => {
117
+ activeSessions.delete(session);
118
+ await bluezDevice.Disconnect().catch(() => { });
119
+ bus.disconnect();
120
+ }
121
+ };
122
+ activeSessions.add(session);
123
+ return session;
124
+ }
125
+ catch (error) {
126
+ bus.disconnect();
127
+ throw error;
128
+ }
129
+ }
130
+ async function openBluezAdapter(bus) {
131
+ const objectManagerObject = await bus.getProxyObject('org.bluez', '/');
132
+ const objectManager = objectManagerObject.getInterface('org.freedesktop.DBus.ObjectManager');
133
+ const objects = await objectManager.GetManagedObjects();
134
+ const adapterPath = findBluezAdapterPath(objects);
135
+ if (!adapterPath)
136
+ throw new Error('Could not find a BlueZ adapter via org.bluez ObjectManager.');
137
+ const adapterObject = await bus.getProxyObject('org.bluez', adapterPath);
138
+ const adapter = adapterObject.getInterface('org.bluez.Adapter1');
139
+ return { objectManager, adapter, adapterPath };
140
+ }
141
+ async function buildBluezCharacteristics({ bus, objects, devicePath, notifyUuid, logger }) {
142
+ const byUuid = new Map();
143
+ for (const [path, interfaces] of Object.entries(objects)) {
144
+ if (!path.startsWith(`${devicePath}/`))
145
+ continue;
146
+ const characteristic = interfaces['org.bluez.GattCharacteristic1'];
147
+ if (!characteristic)
148
+ continue;
149
+ const uuid = nullableString(unboxBluezValue(characteristic.UUID));
150
+ if (!uuid)
151
+ continue;
152
+ byUuid.set(normalizeUuid(uuid), { path, properties: characteristic });
153
+ }
154
+ logger(`BlueZ discovered ${byUuid.size} GATT characteristic(s): ${[...byUuid.keys()].sort().join(', ')}.`);
155
+ const notify = byUuid.get(normalizeUuid(notifyUuid));
156
+ if (!notify) {
157
+ throw new Error(`Missing BLE notify characteristic ${notifyUuid} via BlueZ. Found: ${[...byUuid.keys()].sort().join(', ')}`);
158
+ }
159
+ return {
160
+ notify: await wrapBluezCharacteristic(bus, notify.path, notify.properties)
161
+ };
162
+ }
163
+ async function wrapBluezCharacteristic(bus, path, initialProperties) {
164
+ const object = await bus.getProxyObject('org.bluez', path);
165
+ const characteristic = object.getInterface('org.bluez.GattCharacteristic1');
166
+ const properties = object.getInterface('org.freedesktop.DBus.Properties');
167
+ const listeners = new Set();
168
+ const flags = Array.isArray(unboxBluezValue(initialProperties.Flags)) ? unboxBluezValue(initialProperties.Flags).map(String) : [];
169
+ let writeQueue = Promise.resolve();
170
+ const onPropertiesChanged = (interfaceName, changed) => {
171
+ if (interfaceName !== 'org.bluez.GattCharacteristic1' || !('Value' in changed))
172
+ return;
173
+ const value = Buffer.from(unboxBluezValue(changed.Value) || []);
174
+ for (const listener of listeners)
175
+ listener(value);
176
+ };
177
+ properties.on('PropertiesChanged', onPropertiesChanged);
178
+ return {
179
+ uuid: normalizeUuid(String(unboxBluezValue(initialProperties.UUID) || '')),
180
+ properties: flags,
181
+ async write(data, withoutResponse = false) {
182
+ const options = withoutResponse ? { type: new (loadDbusNext().Variant)('s', 'command') } : {};
183
+ writeQueue = writeQueue.then(() => writeBluezValueWithRetry(characteristic, [...data], options));
184
+ await writeQueue;
185
+ },
186
+ async subscribe() {
187
+ await characteristic.StartNotify();
188
+ },
189
+ onData(listener) {
190
+ listeners.add(listener);
191
+ },
192
+ removeDataListener(listener) {
193
+ listeners.delete(listener);
194
+ }
195
+ };
196
+ }
197
+ function findBluezAdapterPath(objects) {
198
+ for (const [path, interfaces] of Object.entries(objects)) {
199
+ if (interfaces['org.bluez.Adapter1'])
200
+ return path;
201
+ }
202
+ return null;
203
+ }
204
+ function findBluezDevices(objects, options) {
205
+ const devices = [];
206
+ for (const [path, interfaces] of Object.entries(objects)) {
207
+ const device = interfaces['org.bluez.Device1'];
208
+ if (!device)
209
+ continue;
210
+ const uuids = readBluezUuids(device);
211
+ const discovered = toDiscoveredDevice(path, device, 'bluez');
212
+ if (matchesBleDevice({ name: discovered.name, address: discovered.address, serviceUuids: uuids }, { namePrefix: options.namePrefix, deviceName: options.deviceName, serviceUuid: options.matchServiceUuid })) {
213
+ devices.push(discovered);
214
+ }
215
+ }
216
+ return devices;
217
+ }
218
+ function findBluezDeviceByDiscovered(objects, selected) {
219
+ for (const [path, interfaces] of Object.entries(objects)) {
220
+ const device = interfaces['org.bluez.Device1'];
221
+ if (!device)
222
+ continue;
223
+ const discovered = toDiscoveredDevice(path, device, 'bluez');
224
+ if (selected.id === path || (!!selected.name && selected.name === discovered.name) || (!!selected.address && selected.address.toUpperCase() === discovered.address?.toUpperCase())) {
225
+ return { path, address: discovered.address };
226
+ }
227
+ }
228
+ return null;
229
+ }
230
+ function toDiscoveredDevice(path, device, backend) {
231
+ return {
232
+ id: path,
233
+ address: nullableString(unboxBluezValue(device.Address)),
234
+ addressType: null,
235
+ name: nullableString(unboxBluezValue(device.Name)) || nullableString(unboxBluezValue(device.Alias)),
236
+ rssi: nullableNumber(unboxBluezValue(device.RSSI)),
237
+ backend
238
+ };
239
+ }
240
+ function readBluezUuids(device) {
241
+ const value = unboxBluezValue(device.UUIDs);
242
+ return Array.isArray(value) ? value.map((uuid) => String(uuid)) : [];
243
+ }
244
+ export async function setBluezDiscoveryFilter(adapter, Variant, serviceUuid, logger) {
245
+ const filter = {
246
+ Transport: new Variant('s', 'le'),
247
+ DuplicateData: new Variant('b', false)
248
+ };
249
+ if (serviceUuid)
250
+ filter.UUIDs = new Variant('as', [serviceUuid]);
251
+ const names = ['transport', 'duplicates'];
252
+ if (serviceUuid)
253
+ names.push('service UUID');
254
+ await adapter.SetDiscoveryFilter(filter)
255
+ .then(() => logger(`BlueZ discovery filter applied: ${names.join(', ')}.`))
256
+ .catch((error) => logger(`Warning: could not set BlueZ discovery filter (${names.join(', ')}): ${errorMessage(error)}.`));
257
+ }
258
+ async function getBluezBoolean(properties, interfaceName, propertyName) {
259
+ const value = await properties.Get(interfaceName, propertyName).catch(() => null);
260
+ const unboxed = unboxBluezValue(value);
261
+ return typeof unboxed === 'boolean' ? unboxed : null;
262
+ }
263
+ async function waitForBluezBooleanProperty(properties, interfaceName, propertyName, expected, timeoutMs) {
264
+ const startedAt = Date.now();
265
+ while (Date.now() - startedAt < timeoutMs) {
266
+ if ((await getBluezBoolean(properties, interfaceName, propertyName)) === expected)
267
+ return;
268
+ await delay(250);
269
+ }
270
+ throw new Error(`Timed out after ${timeoutMs}ms waiting for BlueZ ${propertyName}=${expected}.`);
271
+ }
272
+ async function writeBluezValueWithRetry(characteristic, value, options) {
273
+ let lastError;
274
+ for (let attempt = 0; attempt < 12; attempt += 1) {
275
+ try {
276
+ await characteristic.WriteValue(value, options);
277
+ return;
278
+ }
279
+ catch (error) {
280
+ lastError = error;
281
+ if (!isBluezInProgressError(error))
282
+ throw error;
283
+ await delay(80);
284
+ }
285
+ }
286
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
287
+ }
288
+ function isBluezInProgressError(error) {
289
+ const message = errorMessage(error).toLowerCase();
290
+ return message.includes('in progress') || message.includes('inprogress');
291
+ }
292
+ function withTimeout(promise, timeoutMs, label) {
293
+ return new Promise((resolve, reject) => {
294
+ const timeout = setTimeout(() => reject(new Error(`Timed out after ${timeoutMs}ms during ${label}.`)), timeoutMs);
295
+ promise.then((value) => {
296
+ clearTimeout(timeout);
297
+ resolve(value);
298
+ }, (error) => {
299
+ clearTimeout(timeout);
300
+ reject(error);
301
+ });
302
+ });
303
+ }
304
+ async function shutdownBluez() {
305
+ const sessions = [...activeSessions];
306
+ activeSessions = new Set();
307
+ await Promise.all(sessions.map((session) => session.disconnect().catch(() => { })));
308
+ }
309
+ function loadDbusNext() {
310
+ try {
311
+ return requireOptional('dbus-next');
312
+ }
313
+ catch (error) {
314
+ throw new Error(`BlueZ backend requires the "dbus-next" dependency. Run npm install. ${errorMessage(error)}`);
315
+ }
316
+ }
317
+ //# sourceMappingURL=bluez.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bluez.js","sourceRoot":"","sources":["../../src/ble/bluez.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { BluetoothBackend } from './backend.js';
2
+ export declare const nobleBackend: BluetoothBackend;