node-red-contrib-ble-scanner 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Command, Option } from 'commander';
2
2
  import { setTimeout as delay } from 'node:timers/promises';
3
- import { DEFAULTS, connectReaders, discoverDevices, readDevices, shutdownBluetooth } from './index.js';
3
+ import { DEFAULTS, discoverDevices, readDevices, shutdownBluetooth } from './index.js';
4
4
  export async function main(argv = process.argv.slice(2)) {
5
5
  installSignalCleanup();
6
6
  const program = new Command();
7
7
  program
8
8
  .name('ble-reader')
9
- .description('Discover BLE devices and read raw notification messages.')
9
+ .description('Discover BLE devices and read raw advertisement manufacturer data.')
10
10
  .showHelpAfterError();
11
11
  addSharedOptions(program);
12
12
  addSharedOptions(program
@@ -24,9 +24,9 @@ export async function main(argv = process.argv.slice(2)) {
24
24
  });
25
25
  addSharedOptions(program
26
26
  .command('read')
27
- .description('Read raw notifications from one exact advertised device name, or all discovered matching devices.')
27
+ .description('Read raw advertisement manufacturer data from one exact advertised device name, or all matching devices.')
28
28
  .argument('[deviceName]', 'exact advertised BLE device name')
29
- .option('--interval <seconds>', 'read repeatedly every N seconds using persistent BLE sessions')).action(async (deviceName, options, command) => {
29
+ .option('--interval <seconds>', 'read repeatedly every N seconds')).action(async (deviceName, options, command) => {
30
30
  const globals = globalOptions(command, options);
31
31
  const intervalMs = parseIntervalMs(options.interval);
32
32
  if (intervalMs === null) {
@@ -62,7 +62,6 @@ export function toReadOptions(globals, deviceName) {
62
62
  bluetooth: globals.bluetooth,
63
63
  namePrefix: globals.namePrefix,
64
64
  deviceName: deviceName || undefined,
65
- notifyUuid: globals.notifyUuid,
66
65
  listenMs: parseListenMs(globals.listenMs),
67
66
  scanServiceUuid: globals.serviceUuid || null,
68
67
  matchServiceUuid: globals.serviceUuid || null,
@@ -74,8 +73,7 @@ function addSharedOptions(command) {
74
73
  .addOption(new Option('--bluetooth <backend>', 'Bluetooth backend').choices(['auto', 'bluez', 'noble']).default('auto'))
75
74
  .option('--name-prefix <prefix>', 'BLE advertised name prefix; empty matches all devices', DEFAULTS.namePrefix)
76
75
  .option('--service-uuid <uuid>', 'optional BLE service UUID used for discovery filtering')
77
- .option('--notify-uuid <uuid>', 'notification characteristic UUID to subscribe to', DEFAULTS.notifyUuid)
78
- .option('--listen-ms <ms>', 'milliseconds to collect notifications per read', String(DEFAULTS.listenMs))
76
+ .option('--listen-ms <ms>', 'milliseconds to collect advertisements per read', String(DEFAULTS.listenMs))
79
77
  .option('--debug', 'print Bluetooth diagnostics to stderr');
80
78
  }
81
79
  function globalOptions(command, options) {
@@ -83,7 +81,6 @@ function globalOptions(command, options) {
83
81
  bluetooth: optionValue(command, options, 'bluetooth', 'auto'),
84
82
  namePrefix: optionValue(command, options, 'namePrefix', DEFAULTS.namePrefix),
85
83
  serviceUuid: optionValue(command, options, 'serviceUuid', ''),
86
- notifyUuid: optionValue(command, options, 'notifyUuid', DEFAULTS.notifyUuid),
87
84
  listenMs: optionValue(command, options, 'listenMs', String(DEFAULTS.listenMs)),
88
85
  debug: optionValue(command, options, 'debug', false)
89
86
  };
@@ -104,26 +101,10 @@ async function writeJson(value) {
104
101
  });
105
102
  }
106
103
  async function readAtInterval(globals, deviceName, intervalMs) {
107
- const readers = await connectReaders(toReadOptions(globals, deviceName));
108
- if (readers.length === 0) {
109
- await writeJson([]);
110
- return;
104
+ while (true) {
105
+ await writeJson(await readDevices(toReadOptions(globals, deviceName)));
106
+ await delay(intervalMs);
111
107
  }
112
- try {
113
- while (true) {
114
- await writeJson(await readPersistentReaders(readers, globals));
115
- await delay(intervalMs);
116
- }
117
- }
118
- finally {
119
- await Promise.all(readers.map((reader) => reader.disconnect().catch(() => { })));
120
- }
121
- }
122
- async function readPersistentReaders(readers, globals) {
123
- const readings = [];
124
- for (const reader of readers)
125
- readings.push(await reader.read(toReadOptions(globals)));
126
- return readings;
127
108
  }
128
109
  function installSignalCleanup() {
129
110
  let shuttingDown = false;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,5 @@
1
1
  export declare const DEFAULTS: {
2
2
  readonly listenMs: 5000;
3
3
  readonly timeoutMs: 30000;
4
- readonly connectTimeoutMs: 15000;
5
- readonly notifyUuid: "fff1";
6
4
  readonly namePrefix: "";
7
5
  };
package/dist/constants.js CHANGED
@@ -1,8 +1,6 @@
1
1
  export const DEFAULTS = {
2
2
  listenMs: 5000,
3
3
  timeoutMs: 30000,
4
- connectTimeoutMs: 15000,
5
- notifyUuid: 'fff1',
6
4
  namePrefix: ''
7
5
  };
8
6
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,KAAK;IAChB,gBAAgB,EAAE,KAAK;IACvB,UAAU,EAAE,MAAM;IAClB,UAAU,EAAE,EAAE;CACN,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,EAAE;CACN,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { DEFAULTS } from './constants.js';
2
- export { connectDevice, connectReaders, discoverDevices, readDevice, readDevices, readSession, shutdownBluetooth, type BleReader } from './reader.js';
2
+ export { discoverDevices, readDevice, readDevices, shutdownBluetooth } from './reader.js';
3
3
  export { matchesBleDevice } from './ble/utils.js';
4
- export type { BleDiscoveredDevice, BleReading, BleSession, BluetoothBackendName, DiscoverOptions, RawBleMessage, ReadOptions } from './ble/backend.js';
4
+ export type { BleAdvertisement, BleDiscoveredDevice, BleManufacturerData, BleReading, BluetoothBackendName, DiscoverOptions, RawBleMessage, ReadOptions } from './ble/backend.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { DEFAULTS } from './constants.js';
2
- export { connectDevice, connectReaders, discoverDevices, readDevice, readDevices, readSession, shutdownBluetooth } from './reader.js';
2
+ export { discoverDevices, readDevice, readDevices, shutdownBluetooth } from './reader.js';
3
3
  export { matchesBleDevice } from './ble/utils.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAAkB,MAAM,aAAa,CAAC;AACtJ,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/reader.d.ts CHANGED
@@ -1,13 +1,5 @@
1
- import type { BleDiscoveredDevice, BleReading, BleSession, DiscoverOptions, ReadOptions } from './ble/backend.js';
2
- export interface BleReader {
3
- device: BleDiscoveredDevice;
4
- read(options?: ReadOptions): Promise<BleReading>;
5
- disconnect(): Promise<void>;
6
- }
1
+ import type { BleDiscoveredDevice, BleReading, DiscoverOptions, ReadOptions } from './ble/backend.js';
7
2
  export declare function discoverDevices(options?: DiscoverOptions): Promise<BleDiscoveredDevice[]>;
8
3
  export declare function readDevices(options?: ReadOptions): Promise<BleReading[]>;
9
4
  export declare function readDevice(device: BleDiscoveredDevice, options?: ReadOptions): Promise<BleReading>;
10
- export declare function connectReaders(options?: ReadOptions): Promise<BleReader[]>;
11
- export declare function connectDevice(device: BleDiscoveredDevice, options?: ReadOptions): Promise<BleReader>;
12
- export declare function readSession(session: BleSession, options?: ReadOptions): Promise<BleReading>;
13
5
  export declare function shutdownBluetooth(): Promise<void>;
package/dist/reader.js CHANGED
@@ -1,8 +1,6 @@
1
- import { setTimeout as delay } from 'node:timers/promises';
2
1
  import { DEFAULTS } from './constants.js';
3
2
  import { bluezBackend } from './ble/bluez.js';
4
3
  import { nobleBackend } from './ble/noble.js';
5
- import { displayDevice, normalizeUuid } from './ble/utils.js';
6
4
  export async function discoverDevices(options = {}) {
7
5
  const logger = options.logger || (() => { });
8
6
  const bluetooth = options.bluetooth || 'auto';
@@ -27,95 +25,48 @@ export async function discoverDevices(options = {}) {
27
25
  }
28
26
  export async function readDevices(options = {}) {
29
27
  const logger = options.logger || (() => { });
30
- const devices = await discoverDevices({ ...options, logger });
31
- const readings = [];
32
- for (const device of devices) {
33
- logger(`Reading raw BLE notifications from ${displayDevice(device)}.`);
34
- readings.push(await readDevice(device, { ...options, logger }));
35
- }
36
- return readings;
37
- }
38
- export async function readDevice(device, options = {}) {
39
- const reader = await connectDevice(device, options);
40
- try {
41
- return await reader.read(options);
42
- }
43
- finally {
44
- await reader.disconnect().catch(() => { });
45
- }
46
- }
47
- export async function connectReaders(options = {}) {
48
- const logger = options.logger || (() => { });
49
- const devices = await discoverDevices({ ...options, logger });
50
- const readers = [];
28
+ const bluetooth = options.bluetooth || 'auto';
29
+ const backend = await selectBluetoothBackend(bluetooth, logger);
30
+ const byDevice = new Map();
51
31
  try {
52
- for (const device of devices) {
53
- logger(`Connecting ${displayDevice(device)}.`);
54
- readers.push(await connectDevice(device, { ...options, logger }));
55
- }
56
- return readers;
32
+ await backend.scanAdvertisements({
33
+ namePrefix: options.namePrefix ?? DEFAULTS.namePrefix,
34
+ deviceName: options.deviceName || null,
35
+ timeoutMs: options.timeoutMs || DEFAULTS.timeoutMs,
36
+ listenMs: options.listenMs ?? DEFAULTS.listenMs,
37
+ scanServiceUuid: options.scanServiceUuid ?? null,
38
+ matchServiceUuid: options.matchServiceUuid ?? null,
39
+ logger,
40
+ onAdvertisement: (advertisement) => {
41
+ const reading = readingForAdvertisement(byDevice, advertisement);
42
+ reading.messages.push(advertisement.message);
43
+ logger(`BLE manufacturer data ${advertisement.message.companyIdHex}:${advertisement.message.hex} ` +
44
+ `(${advertisement.message.length} byte${advertisement.message.length === 1 ? '' : 's'}).`);
45
+ }
46
+ });
57
47
  }
58
48
  catch (error) {
59
- await Promise.all(readers.map((reader) => reader.disconnect().catch(() => { })));
49
+ if (bluetooth === 'auto' && isBluetoothUnavailableError(error)) {
50
+ logger(`No usable Bluetooth backend found: ${error instanceof Error ? error.message : String(error)}.`);
51
+ return [];
52
+ }
60
53
  throw error;
61
54
  }
55
+ return [...byDevice.values()].sort((left, right) => displayReading(left).localeCompare(displayReading(right)));
62
56
  }
63
- export async function connectDevice(device, options = {}) {
64
- const logger = options.logger || (() => { });
65
- const backend = backendForDevice(device);
66
- const notifyUuid = normalizeUuid(options.notifyUuid || DEFAULTS.notifyUuid);
67
- const session = await backend.connect({
68
- device,
69
- timeoutMs: options.timeoutMs || DEFAULTS.timeoutMs,
70
- connectTimeoutMs: options.connectTimeoutMs || DEFAULTS.connectTimeoutMs,
71
- notifyUuid,
72
- logger
57
+ export async function readDevice(device, options = {}) {
58
+ const readings = await readDevices({
59
+ ...options,
60
+ bluetooth: device.backend,
61
+ namePrefix: '',
62
+ deviceName: device.name || undefined
73
63
  });
74
- let disconnected = false;
75
- return {
76
- device: session.device,
77
- read: (readOptions) => readSession(session, { ...options, ...readOptions, notifyUuid, logger }),
78
- disconnect: async () => {
79
- if (disconnected)
80
- return;
81
- disconnected = true;
82
- await session.disconnect();
83
- }
84
- };
85
- }
86
- export async function readSession(session, options = {}) {
87
- const logger = options.logger || (() => { });
88
- const listenMs = options.listenMs ?? DEFAULTS.listenMs;
89
- const notifyUuid = normalizeUuid(options.notifyUuid || session.notify.uuid || DEFAULTS.notifyUuid);
90
- const messages = [];
91
- const onData = (data) => {
92
- const raw = Buffer.from(data);
93
- const message = {
94
- timestamp: new Date().toISOString(),
95
- uuid: session.notify.uuid,
96
- length: raw.length,
97
- data: raw,
98
- hex: raw.toString('hex'),
99
- base64: raw.toString('base64'),
100
- bytes: [...raw]
101
- };
102
- logger(`BLE notification ${message.hex} (${message.length} byte${message.length === 1 ? '' : 's'}).`);
103
- messages.push(message);
104
- };
105
- session.notify.onData(onData);
106
- try {
107
- logger(`Listening for ${listenMs}ms on characteristic ${notifyUuid}.`);
108
- await delay(listenMs);
109
- }
110
- finally {
111
- session.notify.removeDataListener(onData);
112
- }
113
- return {
114
- device: session.device,
64
+ const match = readings.find((reading) => sameDevice(reading.device, device));
65
+ return (match || {
66
+ device,
115
67
  timestamp: new Date().toISOString(),
116
- notifyUuid,
117
- messages
118
- };
68
+ messages: []
69
+ });
119
70
  }
120
71
  export async function shutdownBluetooth() {
121
72
  await Promise.all([nobleBackend.shutdown(), bluezBackend.shutdown()]);
@@ -129,12 +80,32 @@ async function selectBluetoothBackend(bluetooth, logger) {
129
80
  return bluezBackend;
130
81
  return nobleBackend;
131
82
  }
132
- function backendForDevice(device) {
133
- const backends = {
134
- bluez: bluezBackend,
135
- noble: nobleBackend
83
+ function readingForAdvertisement(readings, advertisement) {
84
+ const key = deviceKey(advertisement.device);
85
+ const existing = readings.get(key);
86
+ if (existing) {
87
+ existing.device = advertisement.device;
88
+ existing.timestamp = advertisement.message.timestamp;
89
+ return existing;
90
+ }
91
+ const reading = {
92
+ device: advertisement.device,
93
+ timestamp: advertisement.message.timestamp,
94
+ messages: []
136
95
  };
137
- return backends[device.backend];
96
+ readings.set(key, reading);
97
+ return reading;
98
+ }
99
+ function sameDevice(left, right) {
100
+ return (left.id === right.id ||
101
+ (!!left.address && !!right.address && left.address.toLowerCase() === right.address.toLowerCase()) ||
102
+ (!!left.name && !!right.name && left.name === right.name));
103
+ }
104
+ function deviceKey(device) {
105
+ return device.address?.toLowerCase() || device.name || `${device.backend}:${device.id}`;
106
+ }
107
+ function displayReading(reading) {
108
+ return reading.device.name || reading.device.address || reading.device.id;
138
109
  }
139
110
  function isBluetoothUnavailableError(error) {
140
111
  const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,6 @@
6
6
  bluetooth: { value: 'auto' },
7
7
  namePrefix: { value: '' },
8
8
  serviceUuid: { value: '' },
9
- notifyUuid: { value: 'fff1', required: true },
10
9
  listenMs: { value: 5000, required: true, validate: RED.validators.number() },
11
10
  targetMode: { value: 'all' },
12
11
  deviceName: { value: '' }
@@ -107,10 +106,6 @@
107
106
  <label for="node-config-input-serviceUuid"><i class="fa fa-filter"></i> Service UUID</label>
108
107
  <input type="text" id="node-config-input-serviceUuid" placeholder="optional">
109
108
  </div>
110
- <div class="form-row">
111
- <label for="node-config-input-notifyUuid"><i class="fa fa-bell"></i> Notify UUID</label>
112
- <input type="text" id="node-config-input-notifyUuid" placeholder="fff1">
113
- </div>
114
109
  <div class="form-row">
115
110
  <label for="node-config-input-listenMs"><i class="fa fa-clock-o"></i> Listen ms</label>
116
111
  <input type="number" id="node-config-input-listenMs" min="0" step="100">
@@ -131,5 +126,5 @@
131
126
  </script>
132
127
 
133
128
  <script type="text/html" data-help-name="ble-reader-device">
134
- <p>Configures BLE discovery and the notification characteristic used by the raw reader.</p>
129
+ <p>Configures BLE advertisement scanning and optional device filters used by the raw reader.</p>
135
130
  </script>
@@ -11,7 +11,6 @@ module.exports = function registerBleReaderDeviceNode(RED) {
11
11
  node.bluetooth = config.bluetooth || 'auto';
12
12
  node.namePrefix = config.namePrefix || '';
13
13
  node.serviceUuid = config.serviceUuid || '';
14
- node.notifyUuid = config.notifyUuid || 'fff1';
15
14
  node.listenMs = Number(config.listenMs || 5000);
16
15
  node.targetMode = config.targetMode || 'all';
17
16
  node.deviceName = config.deviceName || '';
@@ -11,7 +11,7 @@
11
11
  outputs: 1,
12
12
  icon: 'font-awesome/fa-bluetooth',
13
13
  label: function () {
14
- return this.name || 'BLE read';
14
+ return this.name || 'BLE advertisement read';
15
15
  }
16
16
  });
17
17
  </script>
@@ -32,7 +32,7 @@
32
32
  </script>
33
33
 
34
34
  <script type="text/html" data-help-name="ble-reader-read">
35
- <p>Collects raw BLE notifications. Output <code>msg.payload</code> is an array with one entry per matching device.</p>
36
- <p>Each message contains <code>data</code> as a Buffer plus <code>hex</code>, <code>base64</code>, <code>bytes</code>, <code>length</code>, and <code>timestamp</code>.</p>
37
- <p>Incoming <code>msg.payload</code> may contain <code>{ deviceName, listenMs, serviceUuid, notifyUuid }</code> to override the configured values.</p>
35
+ <p>Collects raw BLE advertisement manufacturer data. Output <code>msg.payload</code> is an array with one entry per matching device.</p>
36
+ <p>Each message contains <code>companyId</code>, <code>companyIdHex</code>, <code>data</code> as a Buffer plus <code>hex</code>, <code>base64</code>, <code>bytes</code>, <code>length</code>, and <code>timestamp</code>.</p>
37
+ <p>Incoming <code>msg.payload</code> may contain <code>{ deviceName, listenMs, serviceUuid }</code> to override the configured values.</p>
38
38
  </script>
@@ -16,16 +16,14 @@ module.exports = function registerBleReaderReadNode(RED) {
16
16
  const deviceName = override.deviceName || (node.device.targetMode === 'name' ? node.device.deviceName : undefined);
17
17
  const listenMs = override.listenMs ?? (node.listenMs || node.device.listenMs);
18
18
  const serviceUuid = override.serviceUuid ?? node.device.serviceUuid;
19
- const notifyUuid = override.notifyUuid ?? node.device.notifyUuid;
20
19
 
21
- node.status({ fill: 'yellow', shape: 'ring', text: 'listening' });
20
+ node.status({ fill: 'yellow', shape: 'ring', text: 'scanning' });
22
21
  const result = await node.device.enqueue((ble) =>
23
22
  ble.readDevices({
24
23
  bluetooth: node.device.bluetooth,
25
24
  namePrefix: node.device.namePrefix,
26
25
  deviceName,
27
26
  listenMs,
28
- notifyUuid,
29
27
  scanServiceUuid: serviceUuid || null,
30
28
  matchServiceUuid: serviceUuid || null
31
29
  })
@@ -50,7 +48,6 @@ function normalizePayload(payload) {
50
48
  const result = {};
51
49
  if (typeof payload.deviceName === 'string' && payload.deviceName) result.deviceName = payload.deviceName;
52
50
  if (typeof payload.serviceUuid === 'string') result.serviceUuid = payload.serviceUuid;
53
- if (typeof payload.notifyUuid === 'string' && payload.notifyUuid) result.notifyUuid = payload.notifyUuid;
54
51
  if (payload.listenMs !== undefined) {
55
52
  const listenMs = Number(payload.listenMs);
56
53
  if (Number.isFinite(listenMs) && listenMs >= 0) result.listenMs = listenMs;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "node-red-contrib-ble-scanner",
3
- "version": "0.0.1",
4
- "description": "Generic Node-RED BLE reader for raw notification messages.",
3
+ "version": "0.2.0",
4
+ "description": "Generic Node-RED BLE scanner for raw advertisement manufacturer data.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "test": "npm run build --silent && node --test"
47
47
  },
48
48
  "dependencies": {
49
- "commander": "^14.0.3",
49
+ "commander": "^15.0.0",
50
50
  "dbus-next": "^0.10.2"
51
51
  },
52
52
  "optionalDependencies": {
@@ -67,7 +67,8 @@
67
67
  "bluetooth",
68
68
  "ble",
69
69
  "scanner",
70
- "notifications"
70
+ "advertisements",
71
+ "manufacturer-data"
71
72
  ],
72
73
  "license": "MIT"
73
74
  }