@capacitor-community/bluetooth-le
Advanced tools
Comparing version 0.1.2 to 0.2.0
@@ -5,2 +5,17 @@ # Changelog | ||
## [0.2.0](https://github.com/capacitor-community/bluetooth-le/compare/v0.1.2...v0.2.0) (2021-02-13) | ||
### Features | ||
* add optional onDisconnect callback to connect method ([1eefe64](https://github.com/capacitor-community/bluetooth-le/commit/1eefe64512020ce133e3bda927a5c0249c9cd001)) | ||
* implement getEnabled and enabled notifications ([319098f](https://github.com/capacitor-community/bluetooth-le/commit/319098fc17afc047485f075b705c4946ed5c5052)) | ||
* `initialize` will no longer reject when BLE is disabled, use `getEnabled` to check whether BLE is enabled or not | ||
### Bug Fixes | ||
* **ios:** fix allowDuplicates in requestLEScan ([b17b69a](https://github.com/capacitor-community/bluetooth-le/commit/b17b69a9913ec921707ad1d1a4a55b0f87c443fd)) | ||
* **web:** avoid duplicate events ([9a0edbf](https://github.com/capacitor-community/bluetooth-le/commit/9a0edbfac39892b4075596d22398533eebf70b39)) | ||
### [0.1.2](https://github.com/capacitor-community/bluetooth-le/compare/v0.1.1...v0.1.2) (2021-01-23) | ||
@@ -7,0 +22,0 @@ |
@@ -14,3 +14,3 @@ { | ||
"tags": [], | ||
"docs": "Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable or disabled on this device.\nOn Android it will ask for the location permission. On iOS it will ask for the Bluetooth permission.\nFor an example, see [usage](#usage).", | ||
"docs": "Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable on this device.\r\nOn Android it will ask for the location permission. On iOS it will ask for the Bluetooth permission.\r\nFor an example, see [usage](#usage).", | ||
"complexTypes": [], | ||
@@ -20,2 +20,43 @@ "slug": "initialize" | ||
{ | ||
"name": "getEnabled", | ||
"signature": "() => Promise<boolean>", | ||
"parameters": [], | ||
"returns": "Promise<boolean>", | ||
"tags": [], | ||
"docs": "Reports whether BLE is enabled on this device.\r\nAlways returns `true` on web.", | ||
"complexTypes": [], | ||
"slug": "getenabled" | ||
}, | ||
{ | ||
"name": "startEnabledNotifications", | ||
"signature": "(callback: (value: boolean) => void) => Promise<void>", | ||
"parameters": [ | ||
{ | ||
"name": "callback", | ||
"docs": "Callback function to use when the BLE state changes.", | ||
"type": "(value: boolean) => void" | ||
} | ||
], | ||
"returns": "Promise<void>", | ||
"tags": [ | ||
{ | ||
"name": "param", | ||
"text": "callback Callback function to use when the BLE state changes." | ||
} | ||
], | ||
"docs": "Register a callback function that will be invoked when BLE is enabled (true) or disabled (false) on this device.\r\nNot available on web (the callback will never be invoked).", | ||
"complexTypes": [], | ||
"slug": "startenablednotifications" | ||
}, | ||
{ | ||
"name": "stopEnabledNotifications", | ||
"signature": "() => Promise<void>", | ||
"parameters": [], | ||
"returns": "Promise<void>", | ||
"tags": [], | ||
"docs": "Stop the enabled notifications registered with `startEnabledNotifications`.", | ||
"complexTypes": [], | ||
"slug": "stopenablednotifications" | ||
}, | ||
{ | ||
"name": "requestDevice", | ||
@@ -37,3 +78,3 @@ "signature": "(options?: RequestBleDeviceOptions | undefined) => Promise<BleDevice>", | ||
], | ||
"docs": "Request a peripheral BLE device to interact with. This will scan for available devices according to the filters in the options and show a dialog to pick a device.\nFor an example, see [usage](#usage).", | ||
"docs": "Request a peripheral BLE device to interact with. This will scan for available devices according to the filters in the options and show a dialog to pick a device.\r\nFor an example, see [usage](#usage).", | ||
"complexTypes": [ | ||
@@ -71,3 +112,3 @@ "BleDevice", | ||
], | ||
"docs": "Start scanning for BLE devices to interact with according to the filters in the options. The callback will be invoked on each device that is found.\nScanning will continue until `stopLEScan` is called. For an example, see [usage](#usage).\n**NOTE**: Use with care on web platform, the required API is still behind a flag in most browsers.", | ||
"docs": "Start scanning for BLE devices to interact with according to the filters in the options. The callback will be invoked on each device that is found.\r\nScanning will continue until `stopLEScan` is called. For an example, see [usage](#usage).\r\n**NOTE**: Use with care on web platform, the required API is still behind a flag in most browsers.", | ||
"complexTypes": [ | ||
@@ -91,3 +132,3 @@ "RequestBleDeviceOptions", | ||
"name": "connect", | ||
"signature": "(deviceId: string) => Promise<void>", | ||
"signature": "(deviceId: string, onDisconnect?: ((deviceId: string) => void) | undefined) => Promise<void>", | ||
"parameters": [ | ||
@@ -98,2 +139,7 @@ { | ||
"type": "string" | ||
}, | ||
{ | ||
"name": "onDisconnect", | ||
"docs": "Optional disconnect callback function that will be used when the device disconnects", | ||
"type": "((deviceId: string) => void) | undefined" | ||
} | ||
@@ -106,2 +152,6 @@ ], | ||
"text": "deviceId The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan))" | ||
}, | ||
{ | ||
"name": "param", | ||
"text": "onDisconnect Optional disconnect callback function that will be used when the device disconnects" | ||
} | ||
@@ -328,3 +378,3 @@ ], | ||
"tags": [], | ||
"docs": "ID of the device, which will be needed for further calls.\nOn Android this is the BLE MAC address.\nOn iOS and web it is an identifier.", | ||
"docs": "ID of the device, which will be needed for further calls.\r\nOn Android this is the BLE MAC address.\r\nOn iOS and web it is an identifier.", | ||
"complexTypes": [], | ||
@@ -359,3 +409,3 @@ "type": "string" | ||
"tags": [], | ||
"docs": "Filter devices by service UUIDs.\nUUIDs have to be specified as 128 bit UUID strings in lowercase,\ne.g. ['0000180d-0000-1000-8000-00805f9b34fb']\nThere is a helper function to convert numbers to UUIDs.\ne.g. [numberToUUID(0x180f)]. (see [UUID format](#uuid-format))", | ||
"docs": "Filter devices by service UUIDs.\r\nUUIDs have to be specified as 128 bit UUID strings in lowercase,\r\ne.g. ['0000180d-0000-1000-8000-00805f9b34fb']\r\nThere is a helper function to convert numbers to UUIDs.\r\ne.g. [numberToUUID(0x180f)]. (see [UUID format](#uuid-format))", | ||
"complexTypes": [], | ||
@@ -381,3 +431,3 @@ "type": "string[] | undefined" | ||
"tags": [], | ||
"docs": "For web, all services that will be used have to be listed under services or optionalServices,\ne.g. [numberToUUID(0x180f)] (see [UUID format](#uuid-format))", | ||
"docs": "For web, all services that will be used have to be listed under services or optionalServices,\r\ne.g. [numberToUUID(0x180f)] (see [UUID format](#uuid-format))", | ||
"complexTypes": [], | ||
@@ -389,3 +439,3 @@ "type": "string[] | undefined" | ||
"tags": [], | ||
"docs": "Normally scans will discard the second and subsequent advertisements from a single device.\nIf you need to receive them, set allowDuplicates to true (only applicable in `requestLEScan`).\n(default: false)", | ||
"docs": "Normally scans will discard the second and subsequent advertisements from a single device.\r\nIf you need to receive them, set allowDuplicates to true (only applicable in `requestLEScan`).\r\n(default: false)", | ||
"complexTypes": [], | ||
@@ -401,3 +451,3 @@ "type": "boolean | undefined" | ||
], | ||
"type": "ScanMode | undefined" | ||
"type": "ScanMode" | ||
} | ||
@@ -468,3 +518,3 @@ ] | ||
], | ||
"type": "DataView | undefined" | ||
"type": "DataView" | ||
} | ||
@@ -1048,3 +1098,3 @@ ] | ||
"tags": [], | ||
"docs": "Perform Bluetooth LE scan in low power mode. This mode is enforced if the scanning application is not in foreground.\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_POWER" | ||
"docs": "Perform Bluetooth LE scan in low power mode. This mode is enforced if the scanning application is not in foreground.\r\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_POWER" | ||
}, | ||
@@ -1055,3 +1105,3 @@ { | ||
"tags": [], | ||
"docs": "Perform Bluetooth LE scan in balanced power mode. (default) Scan results are returned at a rate that provides a good trade-off between scan frequency and power consumption.\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_BALANCED" | ||
"docs": "Perform Bluetooth LE scan in balanced power mode. (default) Scan results are returned at a rate that provides a good trade-off between scan frequency and power consumption.\r\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_BALANCED" | ||
}, | ||
@@ -1062,7 +1112,8 @@ { | ||
"tags": [], | ||
"docs": "Scan using highest duty cycle. It's recommended to only use this mode when the application is running in the foreground.\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_LATENCY" | ||
"docs": "Scan using highest duty cycle. It's recommended to only use this mode when the application is running in the foreground.\r\nhttps://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_LATENCY" | ||
} | ||
] | ||
} | ||
] | ||
], | ||
"typeAliases": [] | ||
} |
@@ -5,3 +5,3 @@ import type { PluginListenerHandle } from '@capacitor/core'; | ||
/** | ||
* Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable or disabled on this device. | ||
* Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable on this device. | ||
* On Android it will ask for the location permission. On iOS it will ask for the Bluetooth permission. | ||
@@ -12,2 +12,17 @@ * For an example, see [usage](#usage). | ||
/** | ||
* Reports whether BLE is enabled on this device. | ||
* Always returns `true` on web. | ||
*/ | ||
getEnabled(): Promise<boolean>; | ||
/** | ||
* Register a callback function that will be invoked when BLE is enabled (true) or disabled (false) on this device. | ||
* Not available on web (the callback will never be invoked). | ||
* @param callback Callback function to use when the BLE state changes. | ||
*/ | ||
startEnabledNotifications(callback: (value: boolean) => void): Promise<void>; | ||
/** | ||
* Stop the enabled notifications registered with `startEnabledNotifications`. | ||
*/ | ||
stopEnabledNotifications(): Promise<void>; | ||
/** | ||
* Request a peripheral BLE device to interact with. This will scan for available devices according to the filters in the options and show a dialog to pick a device. | ||
@@ -33,4 +48,5 @@ * For an example, see [usage](#usage). | ||
* @param deviceId The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) | ||
* @param onDisconnect Optional disconnect callback function that will be used when the device disconnects | ||
*/ | ||
connect(deviceId: string): Promise<void>; | ||
connect(deviceId: string, onDisconnect?: (deviceId: string) => void): Promise<void>; | ||
/** | ||
@@ -74,8 +90,11 @@ * Disconnect from a peripheral BLE device. For an example, see [usage](#usage). | ||
scanListener: PluginListenerHandle | null; | ||
notifyListeners: Map<string, PluginListenerHandle>; | ||
eventListeners: Map<string, PluginListenerHandle>; | ||
initialize(): Promise<void>; | ||
getEnabled(): Promise<boolean>; | ||
startEnabledNotifications(callback: (value: boolean) => void): Promise<void>; | ||
stopEnabledNotifications(): Promise<void>; | ||
requestDevice(options?: RequestBleDeviceOptions): Promise<BleDevice>; | ||
requestLEScan(options: RequestBleDeviceOptions, callback: (result: ScanResult) => void): Promise<void>; | ||
stopLEScan(): Promise<void>; | ||
connect(deviceId: string): Promise<void>; | ||
connect(deviceId: string, onDisconnect?: (deviceId: string) => void): Promise<void>; | ||
disconnect(deviceId: string): Promise<void>; | ||
@@ -82,0 +101,0 @@ read(deviceId: string, service: string, characteristic: string): Promise<DataView>; |
@@ -16,3 +16,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
this.scanListener = null; | ||
this.notifyListeners = new Map(); | ||
this.eventListeners = new Map(); | ||
} | ||
@@ -24,2 +24,28 @@ initialize() { | ||
} | ||
getEnabled() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const result = yield BluetoothLe.getEnabled(); | ||
return result.value; | ||
}); | ||
} | ||
startEnabledNotifications(callback) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe.addListener(key, result => { | ||
callback(result.value); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe.startEnabledNotifications(); | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
yield BluetoothLe.stopEnabledNotifications(); | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -54,4 +80,13 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
connect(deviceId) { | ||
connect(deviceId, onDisconnect) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (onDisconnect) { | ||
const key = `disconnected|${deviceId}`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe.addListener(key, () => { | ||
onDisconnect(deviceId); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
} | ||
yield BluetoothLe.connect({ deviceId }); | ||
@@ -94,7 +129,7 @@ }); | ||
const key = `notification|${deviceId}|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe.addListener(key, (event) => { | ||
callback(this.convertValue(event === null || event === void 0 ? void 0 : event.value)); | ||
}); | ||
this.notifyListeners.set(key, listener); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe.startNotifications({ | ||
@@ -111,4 +146,4 @@ deviceId, | ||
const key = `notification|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.notifyListeners.delete(key); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.eventListeners.delete(key); | ||
yield BluetoothLe.stopNotifications({ | ||
@@ -115,0 +150,0 @@ deviceId, |
@@ -148,7 +148,15 @@ import type { PluginListenerHandle } from '@capacitor/core'; | ||
initialize(): Promise<void>; | ||
getEnabled(): Promise<{ | ||
value: boolean; | ||
}>; | ||
startEnabledNotifications(): Promise<void>; | ||
stopEnabledNotifications(): Promise<void>; | ||
requestDevice(options?: RequestBleDeviceOptions): Promise<BleDevice>; | ||
requestLEScan(options?: RequestBleDeviceOptions): Promise<void>; | ||
stopLEScan(): Promise<void>; | ||
addListener(eventName: 'onEnabledChanged', listenerFunc: (result: { | ||
value: boolean; | ||
}) => void): PluginListenerHandle; | ||
addListener(eventName: string, listenerFunc: (event: ReadResult) => void): PluginListenerHandle; | ||
addListener(eventName: string, listenerFunc: (result: ScanResultInternal) => void): PluginListenerHandle; | ||
addListener(eventName: 'onScanResult', listenerFunc: (result: ScanResultInternal) => void): PluginListenerHandle; | ||
connect(options: ConnectOptions): Promise<void>; | ||
@@ -155,0 +163,0 @@ disconnect(options: ConnectOptions): Promise<void>; |
@@ -6,9 +6,18 @@ /// <reference types="web-bluetooth" /> | ||
private deviceMap; | ||
private discoverdDevices; | ||
private scan; | ||
private requestBleDeviceOptions; | ||
constructor(); | ||
initialize(): Promise<void>; | ||
getEnabled(): Promise<{ | ||
value: true; | ||
}>; | ||
startEnabledNotifications(): Promise<void>; | ||
stopEnabledNotifications(): Promise<void>; | ||
requestDevice(options?: RequestBleDeviceOptions): Promise<BleDevice>; | ||
requestLEScan(options?: RequestBleDeviceOptions): Promise<void>; | ||
private onAdvertisemendReceived; | ||
stopLEScan(): Promise<void>; | ||
connect(options: ConnectOptions): Promise<void>; | ||
private onDisconnected; | ||
disconnect(options: ConnectOptions): Promise<void>; | ||
@@ -19,2 +28,3 @@ getCharacteristic(options: ReadOptions | WriteOptions): Promise<BluetoothRemoteGATTCharacteristic | undefined>; | ||
startNotifications(options: ReadOptions): Promise<void>; | ||
private onCharacteristicValueChanged; | ||
stopNotifications(options: ReadOptions): Promise<void>; | ||
@@ -21,0 +31,0 @@ private getFilters; |
@@ -19,2 +19,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
this.deviceMap = new Map(); | ||
this.discoverdDevices = new Map(); | ||
this.scan = null; | ||
@@ -32,2 +33,18 @@ } | ||
} | ||
getEnabled() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
return { value: true }; | ||
}); | ||
} | ||
startEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -48,24 +65,8 @@ return __awaiter(this, void 0, void 0, function* () { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.requestBleDeviceOptions = options; | ||
const filters = this.getFilters(options); | ||
yield this.stopLEScan(); | ||
navigator.bluetooth.addEventListener('advertisementreceived', (event) => { | ||
var _a; | ||
const isNew = !this.deviceMap.has(event.device.id); | ||
this.deviceMap.set(event.device.id, event.device); | ||
if (isNew || (options === null || options === void 0 ? void 0 : options.allowDuplicates)) { | ||
const device = { | ||
deviceId: event.device.id, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_a = event.uuids) === null || _a === void 0 ? void 0 : _a.map(webUUIDToString), | ||
}; | ||
this.notifyListeners('onScanResult', result); | ||
} | ||
}); | ||
this.discoverdDevices = new Map(); | ||
navigator.bluetooth.removeEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
navigator.bluetooth.addEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
this.scan = yield navigator.bluetooth.requestLEScan({ | ||
@@ -78,2 +79,25 @@ filters: filters.length ? filters : undefined, | ||
} | ||
onAdvertisemendReceived(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const deviceId = event.device.id; | ||
BluetoothLe.deviceMap.set(deviceId, event.device); | ||
const isNew = !BluetoothLe.discoverdDevices.has(deviceId); | ||
if (isNew || ((_a = BluetoothLe.requestBleDeviceOptions) === null || _a === void 0 ? void 0 : _a.allowDuplicates)) { | ||
BluetoothLe.discoverdDevices.set(deviceId, true); | ||
const device = { | ||
deviceId: deviceId, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_b = event.uuids) === null || _b === void 0 ? void 0 : _b.map(webUUIDToString), | ||
}; | ||
BluetoothLe.notifyListeners('onScanResult', result); | ||
} | ||
} | ||
stopLEScan() { | ||
@@ -91,5 +115,14 @@ var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield ((_a = this.getDevice(options.deviceId).gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
const device = yield this.getDevice(options.deviceId); | ||
device.removeEventListener('gattserverdisconnected', this.onDisconnected); | ||
device.addEventListener('gattserverdisconnected', this.onDisconnected); | ||
yield ((_a = device.gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
}); | ||
} | ||
onDisconnected(event) { | ||
// do not use `this` in event listener | ||
const deviceId = event.target.id; | ||
const key = `disconnected|${deviceId}`; | ||
BluetoothLe.notifyListeners(key, null); | ||
} | ||
disconnect(options) { | ||
@@ -131,11 +164,16 @@ var _a; | ||
const characteristic = yield this.getCharacteristic(options); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', (event) => { | ||
const key = `notification|${options.deviceId}|${options.service}|${options.characteristic}`; | ||
this.notifyListeners(key, { | ||
value: event.target.value, | ||
}); | ||
}); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.removeEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
yield (characteristic === null || characteristic === void 0 ? void 0 : characteristic.startNotifications()); | ||
}); | ||
} | ||
onCharacteristicValueChanged(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const characteristic = event.target; | ||
const key = `notification|${(_a = characteristic.service) === null || _a === void 0 ? void 0 : _a.device.id}|${(_b = characteristic.service) === null || _b === void 0 ? void 0 : _b.uuid}|${characteristic.uuid}`; | ||
BluetoothLe.notifyListeners(key, { | ||
value: characteristic.value, | ||
}); | ||
} | ||
stopNotifications(options) { | ||
@@ -142,0 +180,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -104,2 +104,3 @@ 'use strict'; | ||
this.deviceMap = new Map(); | ||
this.discoverdDevices = new Map(); | ||
this.scan = null; | ||
@@ -117,2 +118,18 @@ } | ||
} | ||
getEnabled() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
return { value: true }; | ||
}); | ||
} | ||
startEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -133,24 +150,8 @@ return __awaiter(this, void 0, void 0, function* () { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.requestBleDeviceOptions = options; | ||
const filters = this.getFilters(options); | ||
yield this.stopLEScan(); | ||
navigator.bluetooth.addEventListener('advertisementreceived', (event) => { | ||
var _a; | ||
const isNew = !this.deviceMap.has(event.device.id); | ||
this.deviceMap.set(event.device.id, event.device); | ||
if (isNew || (options === null || options === void 0 ? void 0 : options.allowDuplicates)) { | ||
const device = { | ||
deviceId: event.device.id, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_a = event.uuids) === null || _a === void 0 ? void 0 : _a.map(webUUIDToString), | ||
}; | ||
this.notifyListeners('onScanResult', result); | ||
} | ||
}); | ||
this.discoverdDevices = new Map(); | ||
navigator.bluetooth.removeEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
navigator.bluetooth.addEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
this.scan = yield navigator.bluetooth.requestLEScan({ | ||
@@ -163,2 +164,25 @@ filters: filters.length ? filters : undefined, | ||
} | ||
onAdvertisemendReceived(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const deviceId = event.device.id; | ||
BluetoothLe.deviceMap.set(deviceId, event.device); | ||
const isNew = !BluetoothLe.discoverdDevices.has(deviceId); | ||
if (isNew || ((_a = BluetoothLe.requestBleDeviceOptions) === null || _a === void 0 ? void 0 : _a.allowDuplicates)) { | ||
BluetoothLe.discoverdDevices.set(deviceId, true); | ||
const device = { | ||
deviceId: deviceId, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_b = event.uuids) === null || _b === void 0 ? void 0 : _b.map(webUUIDToString), | ||
}; | ||
BluetoothLe.notifyListeners('onScanResult', result); | ||
} | ||
} | ||
stopLEScan() { | ||
@@ -176,5 +200,14 @@ var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield ((_a = this.getDevice(options.deviceId).gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
const device = yield this.getDevice(options.deviceId); | ||
device.removeEventListener('gattserverdisconnected', this.onDisconnected); | ||
device.addEventListener('gattserverdisconnected', this.onDisconnected); | ||
yield ((_a = device.gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
}); | ||
} | ||
onDisconnected(event) { | ||
// do not use `this` in event listener | ||
const deviceId = event.target.id; | ||
const key = `disconnected|${deviceId}`; | ||
BluetoothLe.notifyListeners(key, null); | ||
} | ||
disconnect(options) { | ||
@@ -216,11 +249,16 @@ var _a; | ||
const characteristic = yield this.getCharacteristic(options); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', (event) => { | ||
const key = `notification|${options.deviceId}|${options.service}|${options.characteristic}`; | ||
this.notifyListeners(key, { | ||
value: event.target.value, | ||
}); | ||
}); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.removeEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
yield (characteristic === null || characteristic === void 0 ? void 0 : characteristic.startNotifications()); | ||
}); | ||
} | ||
onCharacteristicValueChanged(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const characteristic = event.target; | ||
const key = `notification|${(_a = characteristic.service) === null || _a === void 0 ? void 0 : _a.device.id}|${(_b = characteristic.service) === null || _b === void 0 ? void 0 : _b.uuid}|${characteristic.uuid}`; | ||
BluetoothLe.notifyListeners(key, { | ||
value: characteristic.value, | ||
}); | ||
} | ||
stopNotifications(options) { | ||
@@ -274,3 +312,3 @@ return __awaiter(this, void 0, void 0, function* () { | ||
this.scanListener = null; | ||
this.notifyListeners = new Map(); | ||
this.eventListeners = new Map(); | ||
} | ||
@@ -282,2 +320,28 @@ initialize() { | ||
} | ||
getEnabled() { | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const result = yield BluetoothLe$1.getEnabled(); | ||
return result.value; | ||
}); | ||
} | ||
startEnabledNotifications(callback) { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, result => { | ||
callback(result.value); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe$1.startEnabledNotifications(); | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
yield BluetoothLe$1.stopEnabledNotifications(); | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -312,4 +376,13 @@ return __awaiter$1(this, void 0, void 0, function* () { | ||
} | ||
connect(deviceId) { | ||
connect(deviceId, onDisconnect) { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
if (onDisconnect) { | ||
const key = `disconnected|${deviceId}`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, () => { | ||
onDisconnect(deviceId); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
} | ||
yield BluetoothLe$1.connect({ deviceId }); | ||
@@ -352,7 +425,7 @@ }); | ||
const key = `notification|${deviceId}|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, (event) => { | ||
callback(this.convertValue(event === null || event === void 0 ? void 0 : event.value)); | ||
}); | ||
this.notifyListeners.set(key, listener); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe$1.startNotifications({ | ||
@@ -369,4 +442,4 @@ deviceId, | ||
const key = `notification|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.notifyListeners.delete(key); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.eventListeners.delete(key); | ||
yield BluetoothLe$1.stopNotifications({ | ||
@@ -373,0 +446,0 @@ deviceId, |
@@ -101,2 +101,3 @@ var capacitorCommunityBluetoothLe = (function (exports, core) { | ||
this.deviceMap = new Map(); | ||
this.discoverdDevices = new Map(); | ||
this.scan = null; | ||
@@ -114,2 +115,18 @@ } | ||
} | ||
getEnabled() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
return { value: true }; | ||
}); | ||
} | ||
startEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// not available on web | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -130,24 +147,8 @@ return __awaiter(this, void 0, void 0, function* () { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.requestBleDeviceOptions = options; | ||
const filters = this.getFilters(options); | ||
yield this.stopLEScan(); | ||
navigator.bluetooth.addEventListener('advertisementreceived', (event) => { | ||
var _a; | ||
const isNew = !this.deviceMap.has(event.device.id); | ||
this.deviceMap.set(event.device.id, event.device); | ||
if (isNew || (options === null || options === void 0 ? void 0 : options.allowDuplicates)) { | ||
const device = { | ||
deviceId: event.device.id, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_a = event.uuids) === null || _a === void 0 ? void 0 : _a.map(webUUIDToString), | ||
}; | ||
this.notifyListeners('onScanResult', result); | ||
} | ||
}); | ||
this.discoverdDevices = new Map(); | ||
navigator.bluetooth.removeEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
navigator.bluetooth.addEventListener('advertisementreceived', this.onAdvertisemendReceived); | ||
this.scan = yield navigator.bluetooth.requestLEScan({ | ||
@@ -160,2 +161,25 @@ filters: filters.length ? filters : undefined, | ||
} | ||
onAdvertisemendReceived(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const deviceId = event.device.id; | ||
BluetoothLe.deviceMap.set(deviceId, event.device); | ||
const isNew = !BluetoothLe.discoverdDevices.has(deviceId); | ||
if (isNew || ((_a = BluetoothLe.requestBleDeviceOptions) === null || _a === void 0 ? void 0 : _a.allowDuplicates)) { | ||
BluetoothLe.discoverdDevices.set(deviceId, true); | ||
const device = { | ||
deviceId: deviceId, | ||
name: event.device.name, | ||
}; | ||
const result = { | ||
device, | ||
rssi: event.rssi, | ||
txPower: event.txPower, | ||
manufacturerData: mapToObject(event.manufacturerData), | ||
serviceData: mapToObject(event.serviceData), | ||
uuids: (_b = event.uuids) === null || _b === void 0 ? void 0 : _b.map(webUUIDToString), | ||
}; | ||
BluetoothLe.notifyListeners('onScanResult', result); | ||
} | ||
} | ||
stopLEScan() { | ||
@@ -173,5 +197,14 @@ var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield ((_a = this.getDevice(options.deviceId).gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
const device = yield this.getDevice(options.deviceId); | ||
device.removeEventListener('gattserverdisconnected', this.onDisconnected); | ||
device.addEventListener('gattserverdisconnected', this.onDisconnected); | ||
yield ((_a = device.gatt) === null || _a === void 0 ? void 0 : _a.connect()); | ||
}); | ||
} | ||
onDisconnected(event) { | ||
// do not use `this` in event listener | ||
const deviceId = event.target.id; | ||
const key = `disconnected|${deviceId}`; | ||
BluetoothLe.notifyListeners(key, null); | ||
} | ||
disconnect(options) { | ||
@@ -213,11 +246,16 @@ var _a; | ||
const characteristic = yield this.getCharacteristic(options); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', (event) => { | ||
const key = `notification|${options.deviceId}|${options.service}|${options.characteristic}`; | ||
this.notifyListeners(key, { | ||
value: event.target.value, | ||
}); | ||
}); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.removeEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
characteristic === null || characteristic === void 0 ? void 0 : characteristic.addEventListener('characteristicvaluechanged', this.onCharacteristicValueChanged); | ||
yield (characteristic === null || characteristic === void 0 ? void 0 : characteristic.startNotifications()); | ||
}); | ||
} | ||
onCharacteristicValueChanged(event) { | ||
var _a, _b; | ||
// do not use `this` in event listener | ||
const characteristic = event.target; | ||
const key = `notification|${(_a = characteristic.service) === null || _a === void 0 ? void 0 : _a.device.id}|${(_b = characteristic.service) === null || _b === void 0 ? void 0 : _b.uuid}|${characteristic.uuid}`; | ||
BluetoothLe.notifyListeners(key, { | ||
value: characteristic.value, | ||
}); | ||
} | ||
stopNotifications(options) { | ||
@@ -271,3 +309,3 @@ return __awaiter(this, void 0, void 0, function* () { | ||
this.scanListener = null; | ||
this.notifyListeners = new Map(); | ||
this.eventListeners = new Map(); | ||
} | ||
@@ -279,2 +317,28 @@ initialize() { | ||
} | ||
getEnabled() { | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const result = yield BluetoothLe$1.getEnabled(); | ||
return result.value; | ||
}); | ||
} | ||
startEnabledNotifications(callback) { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, result => { | ||
callback(result.value); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe$1.startEnabledNotifications(); | ||
}); | ||
} | ||
stopEnabledNotifications() { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
const key = `onEnabledChanged`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
yield BluetoothLe$1.stopEnabledNotifications(); | ||
}); | ||
} | ||
requestDevice(options) { | ||
@@ -309,4 +373,13 @@ return __awaiter$1(this, void 0, void 0, function* () { | ||
} | ||
connect(deviceId) { | ||
connect(deviceId, onDisconnect) { | ||
var _a; | ||
return __awaiter$1(this, void 0, void 0, function* () { | ||
if (onDisconnect) { | ||
const key = `disconnected|${deviceId}`; | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, () => { | ||
onDisconnect(deviceId); | ||
}); | ||
this.eventListeners.set(key, listener); | ||
} | ||
yield BluetoothLe$1.connect({ deviceId }); | ||
@@ -349,7 +422,7 @@ }); | ||
const key = `notification|${deviceId}|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
const listener = BluetoothLe$1.addListener(key, (event) => { | ||
callback(this.convertValue(event === null || event === void 0 ? void 0 : event.value)); | ||
}); | ||
this.notifyListeners.set(key, listener); | ||
this.eventListeners.set(key, listener); | ||
yield BluetoothLe$1.startNotifications({ | ||
@@ -366,4 +439,4 @@ deviceId, | ||
const key = `notification|${service}|${characteristic}`; | ||
(_a = this.notifyListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.notifyListeners.delete(key); | ||
(_a = this.eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
this.eventListeners.delete(key); | ||
yield BluetoothLe$1.stopNotifications({ | ||
@@ -370,0 +443,0 @@ deviceId, |
{ | ||
"name": "@capacitor-community/bluetooth-le", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "Capacitor Bluetooth Low Energy Plugin", | ||
@@ -11,3 +11,3 @@ "main": "dist/plugin.cjs.js", | ||
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web", | ||
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..", | ||
"verify:ios": "cd ios && pod install && xcodebuild clean build test -workspace Plugin.xcworkspace -scheme Plugin -destination \"platform=iOS Simulator,name=iPhone 12\" && cd ..", | ||
"verify:android": "cd android && ./gradlew clean build test && cd ..", | ||
@@ -37,12 +37,12 @@ "verify:web": "npm run build", | ||
"devDependencies": { | ||
"@capacitor/android": "^2.4.5", | ||
"@capacitor/core": "^2.4.5", | ||
"@capacitor/docgen": "^0.0.14", | ||
"@capacitor/ios": "^2.4.5", | ||
"@capacitor/android": "^2.4.6", | ||
"@capacitor/core": "^2.4.6", | ||
"@capacitor/docgen": "^0.0.15", | ||
"@capacitor/ios": "^2.4.6", | ||
"@ionic/eslint-config": "^0.3.0", | ||
"@ionic/prettier-config": "^1.0.1", | ||
"@ionic/swiftlint-config": "^1.1.2", | ||
"@rollup/plugin-node-resolve": "^11.0.1", | ||
"@rollup/plugin-node-resolve": "^11.1.1", | ||
"@types/jest": "^26.0.20", | ||
"eslint": "^7.17.0", | ||
"eslint": "^7.18.0", | ||
"jest": "^26.6.3", | ||
@@ -52,10 +52,10 @@ "prettier": "^2.2.1", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.36.1", | ||
"rollup": "^2.38.1", | ||
"standard-version": "^9.1.0", | ||
"swiftlint": "^1.0.1", | ||
"ts-jest": "^26.4.4", | ||
"ts-jest": "^26.5.0", | ||
"typescript": "~4.1.3" | ||
}, | ||
"peerDependencies": { | ||
"@capacitor/core": "^2.4.5" | ||
"@capacitor/core": "^2.4.6" | ||
}, | ||
@@ -82,2 +82,3 @@ "files": [ | ||
"prettier": "@ionic/prettier-config", | ||
"swiftlint": "@ionic/swiftlint-config", | ||
"eslintConfig": { | ||
@@ -84,0 +85,0 @@ "extends": "@ionic/eslint-config/recommended" |
@@ -37,2 +37,5 @@ <p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p> | ||
- [`initialize()`](#initialize) | ||
- [`getEnabled()`](#getenabled) | ||
- [`startEnabledNotifications(...)`](#startenablednotifications) | ||
- [`stopEnabledNotifications()`](#stopenablednotifications) | ||
- [`requestDevice(...)`](#requestdevice) | ||
@@ -299,3 +302,3 @@ - [`requestLEScan(...)`](#requestlescan) | ||
Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable or disabled on this device. | ||
Initialize Bluetooth Low Energy (BLE). If it fails, BLE might be unavailable on this device. | ||
On Android it will ask for the location permission. On iOS it will ask for the Bluetooth permission. | ||
@@ -306,2 +309,40 @@ For an example, see [usage](#usage). | ||
### getEnabled() | ||
```typescript | ||
getEnabled() => Promise<boolean> | ||
``` | ||
Reports whether BLE is enabled on this device. | ||
Always returns `true` on web. | ||
**Returns:** <code>Promise<boolean></code> | ||
--- | ||
### startEnabledNotifications(...) | ||
```typescript | ||
startEnabledNotifications(callback: (value: boolean) => void) => Promise<void> | ||
``` | ||
Register a callback function that will be invoked when BLE is enabled (true) or disabled (false) on this device. | ||
Not available on web (the callback will never be invoked). | ||
| Param | Type | Description | | ||
| -------------- | ---------------------------------------- | ---------------------------------------------------- | | ||
| **`callback`** | <code>(value: boolean) => void</code> | Callback function to use when the BLE state changes. | | ||
--- | ||
### stopEnabledNotifications() | ||
```typescript | ||
stopEnabledNotifications() => Promise<void> | ||
``` | ||
Stop the enabled notifications registered with `startEnabledNotifications`. | ||
--- | ||
### requestDevice(...) | ||
@@ -354,3 +395,3 @@ | ||
```typescript | ||
connect(deviceId: string) => Promise<void> | ||
connect(deviceId: string, onDisconnect?: ((deviceId: string) => void) | undefined) => Promise<void> | ||
``` | ||
@@ -360,5 +401,6 @@ | ||
| Param | Type | Description | | ||
| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------- | | ||
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) | | ||
| Param | Type | Description | | ||
| ------------------ | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | ||
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) | | ||
| **`onDisconnect`** | <code>((deviceId: string) => void)</code> | Optional disconnect callback function that will be used when the device disconnects | | ||
@@ -365,0 +407,0 @@ --- |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 12 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16386410
92
2828
603
4275
25