From 1e20dd40fd8df709bd0385c0a3b0344a6a3ff71e Mon Sep 17 00:00:00 2001 From: Michael Roberts Date: Mon, 28 Feb 2022 12:50:56 +0000 Subject: [PATCH 1/8] feat(useBluetooth): new function --- packages/core/index.ts | 1 + packages/core/useBluetooth/demo.vue | 44 ++++++++ packages/core/useBluetooth/index.md | 108 +++++++++++++++++++ packages/core/useBluetooth/index.test.ts | 7 ++ packages/core/useBluetooth/index.ts | 132 +++++++++++++++++++++++ pnpm-lock.yaml | 66 ++++++------ 6 files changed, 325 insertions(+), 33 deletions(-) create mode 100644 packages/core/useBluetooth/demo.vue create mode 100644 packages/core/useBluetooth/index.md create mode 100644 packages/core/useBluetooth/index.test.ts create mode 100644 packages/core/useBluetooth/index.ts diff --git a/packages/core/index.ts b/packages/core/index.ts index 5707de41c3b..6ec4c63c362 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -12,6 +12,7 @@ export * from './useAsyncQueue' export * from './useAsyncState' export * from './useBase64' export * from './useBattery' +export * from './useBluetooth' export * from './useBreakpoints' export * from './useBroadcastChannel' export * from './useBrowserLocation' diff --git a/packages/core/useBluetooth/demo.vue b/packages/core/useBluetooth/demo.vue new file mode 100644 index 00000000000..f1869a33e81 --- /dev/null +++ b/packages/core/useBluetooth/demo.vue @@ -0,0 +1,44 @@ + + + diff --git a/packages/core/useBluetooth/index.md b/packages/core/useBluetooth/index.md new file mode 100644 index 00000000000..a2c850b695a --- /dev/null +++ b/packages/core/useBluetooth/index.md @@ -0,0 +1,108 @@ +--- +category: Browser +--- + +# useBluetooth + +A reactive for working with the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) which provides the ability to connect and interact with Bluetooth Low Energy peripherals. + +The Web Bluetooth API lets websites discover and communicate with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). + +N.B. It is currently partially implemented in Android M, Chrome OS, Mac, and Windows 10. For a full overview of browser compatabiltiy please see [Web Bluetooth API Browser Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API#browser_compatibility) + +N.B. There are a numebr of caveats to be aware of with the web bluetooth API speficiation. Please refer to the [Web Bluetooth W3C Draft Report](https://webbluetoothcg.github.io/web-bluetooth/) for numerous caveats around device detection and connection. + +N.B. This API is not available in Web Workers (not exposed via WorkerNavigator). + +## Usage Default + +```ts +import { useBluetooth } from '@vueuse/core' + +const { + isSupported, + isConnected, + device, + requestDevice, + server +} = useBluetooth({ + acceptAllDevices: true +}) +``` + +```vue + +``` + +When the device has paired and is connected, you can then work with the server object as you wish. + +## Usage Battery Level Example + +This sample illustrates the use of the Web Bluetooth API to read battery level and be notified of changes from a nearby Bluetooth Device advertising Battery information with Bluetooth Low Energy. + +Here, we use the characteristicvaluechanged event listener to handle reading battery level characteristic value. This event listener will optionally handle upcoming notifications as well. + +```ts +import { pausableWatch, useBluetooth } from '@vueuse/core' + +const { + isSupported, + isConnected, + device, + requestDevice, + server +} = useBluetooth({ + acceptAllDevices: true, + optionalServices: [ + "battery_service" + ] +}) + +const batteryPercent = ref() + +const isGettingBatteryLevels = ref(false) + +const getBatteryLevels = async () => { + isGettingBatteryLevels.value = true + + // Get the battery service: + const batteryService = await server.getPrimaryService("battery_service") + + // Get the current battery level + const batteryLevelCharacteristic = await batteryService.getCharacteristic( + "battery_level" + ) + + // Listen to when characteristic value changes on `characteristicvaluechanged` event: + batteryLevelCharacteristic.addEventListener('characteristicvaluechanged', (event) => { + batteryPercent.value = event.target.value.getUint8(0) + }) + + // Convert received buffer to number: + const batteryLevel = await batteryLevelCharacteristic.readValue() + + batteryPercent.value = await batteryLevel.getUint8(0) +} + +const { stop } = pausableWatch(isConnected, (newIsConnected) => { + if (!newIsConnected || !server.value || isGettingBatteryLevels.value) return + // Attempt to get the battery levels of the device: + getBatteryLevels() + // We only want to run this on the initial connection, as we will use a event listener to handle updates: + stop() +}) +``` + +```vue + +``` + +More samples can be found on [Google Chrome's Web Bluetooth Samples](https://googlechrome.github.io/samples/web-bluetooth/). diff --git a/packages/core/useBluetooth/index.test.ts b/packages/core/useBluetooth/index.test.ts new file mode 100644 index 00000000000..27d44f00c61 --- /dev/null +++ b/packages/core/useBluetooth/index.test.ts @@ -0,0 +1,7 @@ +import { useBluetooth } from '.' + +describe('useBluetooth', () => { + it('should be defined', () => { + expect(useBluetooth).toBeDefined() + }) +}) diff --git a/packages/core/useBluetooth/index.ts b/packages/core/useBluetooth/index.ts new file mode 100644 index 00000000000..91f5f221b61 --- /dev/null +++ b/packages/core/useBluetooth/index.ts @@ -0,0 +1,132 @@ +import { computed, ref, watch } from 'vue-demi' +import { tryOnMounted, tryOnScopeDispose } from '@vueuse/shared' +import type { ConfigurableNavigator } from '../_configurable' + +import { defaultNavigator } from '../_configurable' + +export interface UseBluetoothRequestDeviceOptions { + /** + * + * An array of BluetoothScanFilters. This filter consists of an array + * of BluetoothServiceUUIDs, a name parameter, and a namePrefix parameter. + * + */ + filters?: BluetoothLEScanFilter[] | undefined + /** + * + * An array of BluetoothServiceUUIDs. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/BluetoothRemoteGATTService/uuid + * + */ + optionalServices?: BluetoothServiceUUID[] | undefined +} + +export interface UseBluetoothOptions extends UseBluetoothRequestDeviceOptions, ConfigurableNavigator { + /** + * + * A boolean value indicating that the requesting script can accept all Bluetooth + * devices. The default is false. + * + * !! This may result in a bunch of unrelated devices being shown + * in the chooser and energy being wasted as there are no filters. + * + * + * Use it with caution. + * + * @default false + * + */ + acceptAllDevices?: boolean +} + +export function useBluetooth(options?: UseBluetoothOptions) { + let { + acceptAllDevices = false, + } = options || {} + + const { + filters = undefined, + optionalServices = undefined, + navigator = defaultNavigator, + } = options || {} + + const isSupported = navigator && 'bluetooth' in navigator + + const device = ref(undefined) + + const error = ref(null) + + watch(device, () => { + connectToBluetoothGATTServer() + }) + + async function requestDevice(): Promise { + // This is the function can only be called if Bluetooth API is supported: + if (!isSupported) return + + // Reset any errors we currently have: + error.value = null + + // If filters specified, we need to ensure we don't accept all devices: + if (filters && filters.length > 0) + acceptAllDevices = false + + try { + device.value = await navigator?.bluetooth.requestDevice({ + acceptAllDevices, + filters, + optionalServices, + }) + } + catch (err) { + error.value = err + } + } + + const server = ref() + + const isConnected = computed((): boolean => { + return server.value?.connected || false + }) + + async function connectToBluetoothGATTServer() { + // Reset any errors we currently have: + error.value = null + + if (device.value && device.value.gatt) { + // Add callback to gattserverdisconnected event: + device.value.addEventListener('gattserverdisconnected', () => {}) + + try { + // Connect to the device: + server.value = await device.value.gatt.connect() + } + catch (err) { + error.value = err + } + } + } + + tryOnMounted(() => { + if (device.value) + device.value.gatt?.disconnect() + }) + + tryOnScopeDispose(() => { + if (device.value) + device.value.gatt?.disconnect() + }) + + return { + isSupported, + isConnected, + // Device: + device, + requestDevice, + // Server: + server, + // Errors: + error, + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7690849fbb..66d9c0cc018 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.4 +lockfileVersion: 5.3 neverBuiltDependencies: - electron @@ -1840,7 +1840,7 @@ packages: resolution: {integrity: sha512-kbMawY0WRPyL/lbknBkme4CNLl+Gw+E9G4OpNeXAauqoQiNkBgpIvZYy7BRT4sNGhZbxdxXxXbruqUwDzLmvTw==} dev: true - /@firebase/analytics/0.6.18_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/analytics/0.6.18_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-FXNtYDxbs9ynPbzUVuG94BjFPOPpgJ7156660uvCBuKgoBCIVcNqKkJQQ7TH8384fqvGjbjdcgARY9jgAHbtog==} peerDependencies: '@firebase/app': 0.x @@ -1850,7 +1850,7 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/installations': 0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/installations': 0.4.32_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/logger': 0.2.6 '@firebase/util': 1.3.0 tslib: 2.3.1 @@ -1864,7 +1864,7 @@ packages: resolution: {integrity: sha512-KJ+BqJbdNsx4QT/JIT1yDj5p6D+QN97iJs3GuHnORrqL+DU3RWc9nSYQsrY6Tv9jVWcOkMENXAgDT484vzsm2w==} dev: true - /@firebase/app-check/0.3.2_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/app-check/0.3.2_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-YjpsnV1xVTO1B836IKijRcDeceLgHQNJ/DWa+Vky9UHkm1Mi4qosddX8LZzldaWRTWKX7BN1MbZOLY8r7M/MZQ==} peerDependencies: '@firebase/app': 0.x @@ -1896,7 +1896,7 @@ packages: xmlhttprequest: 1.8.0 dev: true - /@firebase/auth-interop-types/0.1.6_btkbmd3h5b2xery5rhjafs7ybe: + /@firebase/auth-interop-types/0.1.6_0cd4160f67e87572471d89d202cbf809: resolution: {integrity: sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==} peerDependencies: '@firebase/app-types': 0.x @@ -1906,7 +1906,7 @@ packages: '@firebase/util': 1.3.0 dev: true - /@firebase/auth-types/0.10.3_btkbmd3h5b2xery5rhjafs7ybe: + /@firebase/auth-types/0.10.3_0cd4160f67e87572471d89d202cbf809: resolution: {integrity: sha512-zExrThRqyqGUbXOFrH/sowuh2rRtfKHp9SBVY2vOqKWdCX1Ztn682n9WLtlUDsiYVIbBcwautYWk2HyCGFv0OA==} peerDependencies: '@firebase/app-types': 0.x @@ -1916,13 +1916,13 @@ packages: '@firebase/util': 1.3.0 dev: true - /@firebase/auth/0.16.8_aozjwb6f4ndokleblc2fqhe7cu: + /@firebase/auth/0.16.8_03b29b07c5e346e52c8158b4581c9f15: resolution: {integrity: sha512-mR0UXG4LirWIfOiCWxVmvz1o23BuKGxeItQ2cCUgXLTjNtWJXdcky/356iTUsd7ZV5A78s2NHeN5tIDDG6H4rg==} peerDependencies: '@firebase/app': 0.x dependencies: '@firebase/app': 0.6.30 - '@firebase/auth-types': 0.10.3_btkbmd3h5b2xery5rhjafs7ybe + '@firebase/auth-types': 0.10.3_0cd4160f67e87572471d89d202cbf809 transitivePeerDependencies: - '@firebase/app-types' - '@firebase/util' @@ -1945,7 +1945,7 @@ packages: /@firebase/database/0.11.0_@firebase+app-types@0.6.3: resolution: {integrity: sha512-b/kwvCubr6G9coPlo48PbieBDln7ViFBHOGeVt/bt82yuv5jYZBEYAac/mtOVSxpf14aMo/tAN+Edl6SWqXApw==} dependencies: - '@firebase/auth-interop-types': 0.1.6_btkbmd3h5b2xery5rhjafs7ybe + '@firebase/auth-interop-types': 0.1.6_0cd4160f67e87572471d89d202cbf809 '@firebase/component': 0.5.6 '@firebase/database-types': 0.8.0 '@firebase/logger': 0.2.6 @@ -1956,7 +1956,7 @@ packages: - '@firebase/app-types' dev: true - /@firebase/firestore-types/2.4.0_btkbmd3h5b2xery5rhjafs7ybe: + /@firebase/firestore-types/2.4.0_0cd4160f67e87572471d89d202cbf809: resolution: {integrity: sha512-0dgwfuNP7EN6/OlK2HSNSQiQNGLGaRBH0gvgr1ngtKKJuJFuq0Z48RBMeJX9CGjV4TP9h2KaB+KrUKJ5kh1hMg==} peerDependencies: '@firebase/app-types': 0.x @@ -1966,7 +1966,7 @@ packages: '@firebase/util': 1.3.0 dev: true - /@firebase/firestore/2.4.0_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/firestore/2.4.0_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-PQ6+lWNrvh74GvFTHT4gCutFipDmtu8D1tNNawKe+/SyL6XFgeuMYgZIpKQgkTSezVDogC7EGQTJBFnewF9pOg==} engines: {node: ^8.13.0 || >=10.10.0} peerDependencies: @@ -1976,7 +1976,7 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/firestore-types': 2.4.0_btkbmd3h5b2xery5rhjafs7ybe + '@firebase/firestore-types': 2.4.0_0cd4160f67e87572471d89d202cbf809 '@firebase/logger': 0.2.6 '@firebase/util': 1.3.0 '@firebase/webchannel-wrapper': 0.5.1 @@ -1990,7 +1990,7 @@ packages: resolution: {integrity: sha512-3KElyO3887HNxtxNF1ytGFrNmqD+hheqjwmT3sI09FaDCuaxGbOnsXAXH2eQ049XRXw9YQpHMgYws/aUNgXVyQ==} dev: true - /@firebase/functions/0.6.15_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/functions/0.6.15_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-b7RpLwFXi0N+HgkfK8cmkarSOoBeSrc1jNdadkCacQt+vIePkKM3E9EJXF4roWSa8GwTruodpBsvH+lK9iCAKQ==} peerDependencies: '@firebase/app': 0.x @@ -2013,7 +2013,7 @@ packages: '@firebase/app-types': 0.6.3 dev: true - /@firebase/installations/0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/installations/0.4.32_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-K4UlED1Vrhd2rFQQJih+OgEj8OTtrtH4+Izkx7ip2bhXSc+unk8ZhnF69D0kmh7zjXAqEDJrmHs9O5fI3rV6Tw==} peerDependencies: '@firebase/app': 0.x @@ -2040,7 +2040,7 @@ packages: '@firebase/app-types': 0.6.3 dev: true - /@firebase/messaging/0.8.0_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/messaging/0.8.0_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-hkFHDyVe1kMcY9KEG+prjCbvS6MtLUgVFUbbQqq7JQfiv58E07YCzRUcMrJolbNi/1QHH6Jv16DxNWjJB9+/qA==} peerDependencies: '@firebase/app': 0.x @@ -2049,7 +2049,7 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/installations': 0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/installations': 0.4.32_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/messaging-types': 0.5.0_@firebase+app-types@0.6.3 '@firebase/util': 1.3.0 idb: 3.0.2 @@ -2060,7 +2060,7 @@ packages: resolution: {integrity: sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==} dev: true - /@firebase/performance/0.4.18_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/performance/0.4.18_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-lvZW/TVDne2TyOpWbv++zjRn277HZpbjxbIPfwtnmKjVY1gJ+H77Qi1c2avVIc9hg80uGX/5tNf4pOApNDJLVg==} peerDependencies: '@firebase/app': 0.x @@ -2069,7 +2069,7 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/installations': 0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/installations': 0.4.32_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/logger': 0.2.6 '@firebase/performance-types': 0.0.13 '@firebase/util': 1.3.0 @@ -2088,7 +2088,7 @@ packages: resolution: {integrity: sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==} dev: true - /@firebase/remote-config/0.1.43_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/remote-config/0.1.43_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-laNM4MN0CfeSp7XCVNjYOC4DdV6mj0l2rzUh42x4v2wLTweCoJ/kc1i4oWMX9TI7Jw8Am5Wl71Awn1J2pVe5xA==} peerDependencies: '@firebase/app': 0.x @@ -2097,14 +2097,14 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/installations': 0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/installations': 0.4.32_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/logger': 0.2.6 '@firebase/remote-config-types': 0.1.9 '@firebase/util': 1.3.0 tslib: 2.3.1 dev: true - /@firebase/storage-types/0.5.0_btkbmd3h5b2xery5rhjafs7ybe: + /@firebase/storage-types/0.5.0_0cd4160f67e87572471d89d202cbf809: resolution: {integrity: sha512-6Wv3Lu7s18hsgW7HG4BFwycTquZ3m/C8bjBoOsmPu0TD6M1GKwCzOC7qBdN7L6tRYPh8ipTj5+rPFrmhGfUVKA==} peerDependencies: '@firebase/app-types': 0.x @@ -2114,7 +2114,7 @@ packages: '@firebase/util': 1.3.0 dev: true - /@firebase/storage/0.7.0_z3hxu6tufpxc3mjsqzr74ipb4a: + /@firebase/storage/0.7.0_cecf7a7a742bee2db1328663fe21e1e0: resolution: {integrity: sha512-ebDFKJbM5HOxVtZV+RhVEBVtlWHK+Z5L3kA5uDBA2jMYcn+8NV/crozJnEE+iRsGEco6dLK5JS+Er4qtKLpH5A==} peerDependencies: '@firebase/app': 0.x @@ -2123,7 +2123,7 @@ packages: '@firebase/app': 0.6.30 '@firebase/app-types': 0.6.3 '@firebase/component': 0.5.6 - '@firebase/storage-types': 0.5.0_btkbmd3h5b2xery5rhjafs7ybe + '@firebase/storage-types': 0.5.0_0cd4160f67e87572471d89d202cbf809 '@firebase/util': 1.3.0 node-fetch: 2.6.1 tslib: 2.3.1 @@ -5548,20 +5548,20 @@ packages: resolution: {integrity: sha512-GCABTbJdo88QgzX5OH/vsfKBWvTRbLUylGlYXtO7uYo1VErfGd2BWW9ATlJP5Gxx+ClDfyvVTvcs2rcNWn3uUA==} engines: {node: ^8.13.0 || >=10.10.0} dependencies: - '@firebase/analytics': 0.6.18_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/analytics': 0.6.18_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/app': 0.6.30 - '@firebase/app-check': 0.3.2_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/app-check': 0.3.2_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/app-types': 0.6.3 - '@firebase/auth': 0.16.8_aozjwb6f4ndokleblc2fqhe7cu + '@firebase/auth': 0.16.8_03b29b07c5e346e52c8158b4581c9f15 '@firebase/database': 0.11.0_@firebase+app-types@0.6.3 - '@firebase/firestore': 2.4.0_z3hxu6tufpxc3mjsqzr74ipb4a - '@firebase/functions': 0.6.15_z3hxu6tufpxc3mjsqzr74ipb4a - '@firebase/installations': 0.4.32_z3hxu6tufpxc3mjsqzr74ipb4a - '@firebase/messaging': 0.8.0_z3hxu6tufpxc3mjsqzr74ipb4a - '@firebase/performance': 0.4.18_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/firestore': 2.4.0_cecf7a7a742bee2db1328663fe21e1e0 + '@firebase/functions': 0.6.15_cecf7a7a742bee2db1328663fe21e1e0 + '@firebase/installations': 0.4.32_cecf7a7a742bee2db1328663fe21e1e0 + '@firebase/messaging': 0.8.0_cecf7a7a742bee2db1328663fe21e1e0 + '@firebase/performance': 0.4.18_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/polyfill': 0.3.36 - '@firebase/remote-config': 0.1.43_z3hxu6tufpxc3mjsqzr74ipb4a - '@firebase/storage': 0.7.0_z3hxu6tufpxc3mjsqzr74ipb4a + '@firebase/remote-config': 0.1.43_cecf7a7a742bee2db1328663fe21e1e0 + '@firebase/storage': 0.7.0_cecf7a7a742bee2db1328663fe21e1e0 '@firebase/util': 1.3.0 dev: true From 5f7f566fc9abbbd0ca626222f3daf5e7dbe3b32d Mon Sep 17 00:00:00 2001 From: Michael Roberts Date: Mon, 28 Feb 2022 12:54:29 +0000 Subject: [PATCH 2/8] chore(docs): Updated index.md --- packages/core/useBluetooth/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/useBluetooth/index.md b/packages/core/useBluetooth/index.md index a2c850b695a..861b514e905 100644 --- a/packages/core/useBluetooth/index.md +++ b/packages/core/useBluetooth/index.md @@ -8,9 +8,9 @@ A reactive for working with the [Web Bluetooth API](https://developer.mozilla.or The Web Bluetooth API lets websites discover and communicate with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). -N.B. It is currently partially implemented in Android M, Chrome OS, Mac, and Windows 10. For a full overview of browser compatabiltiy please see [Web Bluetooth API Browser Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API#browser_compatibility) +N.B. It is currently partially implemented in Android M, Chrome OS, Mac, and Windows 10. For a full overview of browser compatibility please see [Web Bluetooth API Browser Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API#browser_compatibility) -N.B. There are a numebr of caveats to be aware of with the web bluetooth API speficiation. Please refer to the [Web Bluetooth W3C Draft Report](https://webbluetoothcg.github.io/web-bluetooth/) for numerous caveats around device detection and connection. +N.B. There are a number of caveats to be aware of with the web bluetooth API specification. Please refer to the [Web Bluetooth W3C Draft Report](https://webbluetoothcg.github.io/web-bluetooth/) for numerous caveats around device detection and connection. N.B. This API is not available in Web Workers (not exposed via WorkerNavigator). From 43bffe14a3ddb721623ada4658bc89ff2ebc01af Mon Sep 17 00:00:00 2001 From: Michael Roberts Date: Mon, 28 Feb 2022 12:56:31 +0000 Subject: [PATCH 3/8] chore(tsconfig): Added @types/web-bluetooth to global types. --- tsconfig.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 7bb50fe71cf..2a55638cf0b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,11 @@ "compilerOptions": { "target": "es2017", "module": "esnext", - "lib": ["ESNext", "DOM", "DOM.Iterable"], + "lib": [ + "ESNext", + "DOM", + "DOM.Iterable" + ], "moduleResolution": "node", "esModuleInterop": true, "strict": true, @@ -28,7 +32,8 @@ }, "types": [ "vitest", - "vitest/globals" + "vitest/globals", + "@types/web-bluetooth" ] }, "include": [ @@ -46,4 +51,4 @@ "packages/.test", "packages/_docs" ] -} +} \ No newline at end of file From 08fc11b9bd28b2be9995bcba3886e9eaa21a931b Mon Sep 17 00:00:00 2001 From: Michael Roberts Date: Mon, 28 Feb 2022 13:02:10 +0000 Subject: [PATCH 4/8] chore(lint): run pnpm run lint -- --fix --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 2a55638cf0b..a835ee2fdac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -51,4 +51,4 @@ "packages/.test", "packages/_docs" ] -} \ No newline at end of file +} From 2983c8992161e0dc9fb0e29f3def154a6018a4be Mon Sep 17 00:00:00 2001 From: "Michael J. Roberts" Date: Fri, 25 Mar 2022 17:04:58 +0100 Subject: [PATCH 5/8] fix: tryOnMounted will now connect() to gatt server. --- packages/core/useBluetooth/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/useBluetooth/index.ts b/packages/core/useBluetooth/index.ts index 91f5f221b61..ef6df3f0a40 100644 --- a/packages/core/useBluetooth/index.ts +++ b/packages/core/useBluetooth/index.ts @@ -110,7 +110,7 @@ export function useBluetooth(options?: UseBluetoothOptions) { tryOnMounted(() => { if (device.value) - device.value.gatt?.disconnect() + device.value.gatt?.connect() }) tryOnScopeDispose(() => { From c0e0f3a194c21cec612e323c18e7593d5d06523b Mon Sep 17 00:00:00 2001 From: "Michael J. Roberts" Date: Sun, 24 Apr 2022 20:39:42 +0100 Subject: [PATCH 6/8] chore(useBluetoothAPI): applied suggested lint fixes --- packages/core/useBluetooth/index.md | 23 ++++++++++++----------- packages/core/useBluetooth/index.ts | 3 ++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/core/useBluetooth/index.md b/packages/core/useBluetooth/index.md index 861b514e905..8721e12f974 100644 --- a/packages/core/useBluetooth/index.md +++ b/packages/core/useBluetooth/index.md @@ -19,14 +19,14 @@ N.B. This API is not available in Web Workers (not exposed via WorkerNavigator). ```ts import { useBluetooth } from '@vueuse/core' -const { +const { isSupported, isConnected, device, requestDevice, - server + server, } = useBluetooth({ - acceptAllDevices: true + acceptAllDevices: true, }) ``` @@ -49,32 +49,32 @@ Here, we use the characteristicvaluechanged event listener to handle reading bat ```ts import { pausableWatch, useBluetooth } from '@vueuse/core' -const { +const { isSupported, isConnected, device, requestDevice, - server + server, } = useBluetooth({ acceptAllDevices: true, optionalServices: [ - "battery_service" - ] + 'battery_service', + ], }) const batteryPercent = ref() const isGettingBatteryLevels = ref(false) -const getBatteryLevels = async () => { +const getBatteryLevels = async() => { isGettingBatteryLevels.value = true // Get the battery service: - const batteryService = await server.getPrimaryService("battery_service") + const batteryService = await server.getPrimaryService('battery_service') // Get the current battery level const batteryLevelCharacteristic = await batteryService.getCharacteristic( - "battery_level" + 'battery_level', ) // Listen to when characteristic value changes on `characteristicvaluechanged` event: @@ -89,7 +89,8 @@ const getBatteryLevels = async () => { } const { stop } = pausableWatch(isConnected, (newIsConnected) => { - if (!newIsConnected || !server.value || isGettingBatteryLevels.value) return + if (!newIsConnected || !server.value || isGettingBatteryLevels.value) + return // Attempt to get the battery levels of the device: getBatteryLevels() // We only want to run this on the initial connection, as we will use a event listener to handle updates: diff --git a/packages/core/useBluetooth/index.ts b/packages/core/useBluetooth/index.ts index ef6df3f0a40..b85e678e29d 100644 --- a/packages/core/useBluetooth/index.ts +++ b/packages/core/useBluetooth/index.ts @@ -63,7 +63,8 @@ export function useBluetooth(options?: UseBluetoothOptions) { async function requestDevice(): Promise { // This is the function can only be called if Bluetooth API is supported: - if (!isSupported) return + if (!isSupported) + return // Reset any errors we currently have: error.value = null From 29777eb58ecf09a1093cbe2b79f6582d77be5d20 Mon Sep 17 00:00:00 2001 From: "Michael J. Roberts" Date: Sun, 5 Jun 2022 12:05:32 +0100 Subject: [PATCH 7/8] fix: added @types/web-bluetooth --- package.json | 1 + pnpm-lock.yaml | 163 +++++++++++++++++++------------------------------ 2 files changed, 64 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index 2a9508b86ae..17caf0d23b9 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@types/prettier": "^2.6.1", "@types/semver": "^7.3.9", "@types/sharp": "^0.30.2", + "@types/web-bluetooth": "^0.0.14", "@vitest/ui": "^0.12.9", "@vue/compiler-sfc": "^3.2.36", "@vue/composition-api": "^1.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66d9c0cc018..12fb558efc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,7 @@ importers: '@types/prettier': ^2.6.1 '@types/semver': ^7.3.9 '@types/sharp': ^0.30.2 + '@types/web-bluetooth': ^0.0.14 '@vitest/ui': ^0.12.9 '@vue/compiler-sfc': ^3.2.36 '@vue/composition-api': ^1.6.2 @@ -74,7 +75,7 @@ importers: vue: ^3.2.36 vue2: npm:vue@^2.6.14 devDependencies: - '@antfu/eslint-config': 0.24.2_xztl6dhthcahlo6akmb2bmjmle + '@antfu/eslint-config': 0.24.2_eslint@8.16.0+typescript@4.7.2 '@antfu/ni': 0.16.2 '@iconify/json': 2.1.48 '@rollup/plugin-json': 4.1.0_rollup@2.74.1 @@ -86,11 +87,12 @@ importers: '@types/prettier': 2.6.1 '@types/semver': 7.3.9 '@types/sharp': 0.30.2 + '@types/web-bluetooth': 0.0.14 '@vitest/ui': 0.12.9 '@vue/compiler-sfc': 3.2.36 '@vue/composition-api': 1.6.2_vue@3.2.36 '@vue/test-utils': 2.0.0_vue@3.2.36 - '@vue/theme': 1.0.2_fxyydyqjavkblcmg2ywsuz264y + '@vue/theme': 1.0.2_2df181e2090554158986d62d2a675ee6 axios: 0.27.2 bumpp: 7.1.1 consola: 2.15.3 @@ -121,20 +123,20 @@ importers: remove-markdown: 0.5.0 rimraf: 3.0.2 rollup: 2.74.1 - rollup-plugin-dts: 4.2.1_durm56y4qsrp7annnznb67puce + rollup-plugin-dts: 4.2.1_rollup@2.74.1+typescript@4.7.2 rollup-plugin-esbuild: 4.9.1_rollup@2.74.1 sharp: 0.30.5 simple-git: 3.7.1 simple-git-hooks: 2.7.0 typescript: 4.7.2 unocss: 0.34.1_vite@2.9.9 - unplugin-icons: 0.14.3_5ldljao7w6lsiq5e2abv2ioccy - unplugin-vue-components: 0.19.5_spcnh6tolfhh3jo26jzl6kgg4m + unplugin-icons: 0.14.3_eac6b481dfb7972443a4d0035d21c216 + unplugin-vue-components: 0.19.5_93c4d3fa6e594e7da5daf272bf28c6e3 vite: 2.9.9 vite-plugin-inspect: 0.5.0_vite@2.9.9 vite-plugin-pwa: 0.12.0_vite@2.9.9 vitepress: 0.22.4 - vitest: 0.12.9_vrw6rgtr7itp6ghyrtnu3o3lrq + vitest: 0.12.9_@vitest+ui@0.12.9+jsdom@19.0.0 vue: 3.2.36 vue2: /vue/2.6.14 @@ -388,16 +390,16 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.4 - /@antfu/eslint-config-basic/0.24.2_hzuh7e2up357pvq3mkokjvu2lq: + /@antfu/eslint-config-basic/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-JQOJP5zM6pVg0wNUMJCcseNTbOSjIOK6kqhAzzkE1Xz5oUtaHgL9zjGyazPpJU6tkYzpXsUpCn3Nd2rFY02b4g==} peerDependencies: eslint: '>=7.4.0' dependencies: eslint: 8.16.0 - eslint-plugin-antfu: 0.24.2_xztl6dhthcahlo6akmb2bmjmle + eslint-plugin-antfu: 0.24.2_eslint@8.16.0+typescript@4.7.2 eslint-plugin-eslint-comments: 3.2.0_eslint@8.16.0 eslint-plugin-html: 6.2.0 - eslint-plugin-import: 2.26.0_grfei5yostfimvqdpf73rlhy3e + eslint-plugin-import: 2.26.0_eslint@8.16.0 eslint-plugin-jsonc: 2.2.1_eslint@8.16.0 eslint-plugin-markdown: 2.2.1_eslint@8.16.0 eslint-plugin-n: 15.2.0_eslint@8.16.0 @@ -407,73 +409,64 @@ packages: jsonc-eslint-parser: 2.1.0 yaml-eslint-parser: 1.0.1 transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color - typescript dev: true - /@antfu/eslint-config-react/0.24.2_xztl6dhthcahlo6akmb2bmjmle: + /@antfu/eslint-config-react/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-rovMrWq4ZGNrPMTOrnLNcXNzztgaTGNT15e7fhOXvP1Zq2UMmj1BCvZjJnLFeHE+ptl7HGd9OADf+WdEfWEfKw==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-ts': 0.24.2_xztl6dhthcahlo6akmb2bmjmle + '@antfu/eslint-config-ts': 0.24.2_eslint@8.16.0+typescript@4.7.2 eslint: 8.16.0 eslint-plugin-react: 7.30.0_eslint@8.16.0 transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color - typescript dev: true - /@antfu/eslint-config-ts/0.24.2_xztl6dhthcahlo6akmb2bmjmle: + /@antfu/eslint-config-ts/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-SLuePt5doZxiYPc4UpNpXHGufgK14/1PXb7qJlDOPYx9jWuPyCkpxesxWXBZ4S+ZHNOw4rvR2iJG0HFVPuNZxg==} peerDependencies: eslint: '>=7.4.0' typescript: '>=3.9' dependencies: - '@antfu/eslint-config-basic': 0.24.2_hzuh7e2up357pvq3mkokjvu2lq - '@typescript-eslint/eslint-plugin': 5.26.0_hzuh7e2up357pvq3mkokjvu2lq - '@typescript-eslint/parser': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@antfu/eslint-config-basic': 0.24.2_eslint@8.16.0+typescript@4.7.2 + '@typescript-eslint/eslint-plugin': 5.26.0_3e687f93547efbf7d61b629ca4d69a5c + '@typescript-eslint/parser': 5.26.0_eslint@8.16.0+typescript@4.7.2 eslint: 8.16.0 typescript: 4.7.2 transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color dev: true - /@antfu/eslint-config-vue/0.24.2_xztl6dhthcahlo6akmb2bmjmle: + /@antfu/eslint-config-vue/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-lENl6u3GHnzoP75nEx2J+BNZ5S8ORx3XBPD+izxvxoyarVeda4JZf66YJ3nfMI1g/7/5KoM2ebf3g3ceOEBi3w==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-ts': 0.24.2_xztl6dhthcahlo6akmb2bmjmle + '@antfu/eslint-config-ts': 0.24.2_eslint@8.16.0+typescript@4.7.2 eslint: 8.16.0 eslint-plugin-vue: 9.0.1_eslint@8.16.0 transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color - typescript dev: true - /@antfu/eslint-config/0.24.2_xztl6dhthcahlo6akmb2bmjmle: + /@antfu/eslint-config/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-hDqwNg8e2xud31467KQRmIaYknoF6ijZIUSVY4LI6rlOZPWHQp7J/rMW6NnIF5RHcGJnI/O0Pf1A0GJl3/pjJw==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-react': 0.24.2_xztl6dhthcahlo6akmb2bmjmle - '@antfu/eslint-config-vue': 0.24.2_xztl6dhthcahlo6akmb2bmjmle - '@typescript-eslint/eslint-plugin': 5.26.0_hzuh7e2up357pvq3mkokjvu2lq - '@typescript-eslint/parser': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@antfu/eslint-config-react': 0.24.2_eslint@8.16.0+typescript@4.7.2 + '@antfu/eslint-config-vue': 0.24.2_eslint@8.16.0+typescript@4.7.2 + '@typescript-eslint/eslint-plugin': 5.26.0_3e687f93547efbf7d61b629ca4d69a5c + '@typescript-eslint/parser': 5.26.0_eslint@8.16.0+typescript@4.7.2 eslint: 8.16.0 eslint-plugin-eslint-comments: 3.2.0_eslint@8.16.0 eslint-plugin-html: 6.2.0 - eslint-plugin-import: 2.26.0_grfei5yostfimvqdpf73rlhy3e + eslint-plugin-import: 2.26.0_eslint@8.16.0 eslint-plugin-jsonc: 2.2.1_eslint@8.16.0 eslint-plugin-n: 15.2.0_eslint@8.16.0 eslint-plugin-promise: 6.0.0_eslint@8.16.0 @@ -483,8 +476,6 @@ packages: jsonc-eslint-parser: 2.1.0 yaml-eslint-parser: 1.0.1 transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color - typescript dev: true @@ -2374,7 +2365,7 @@ packages: resolution: {integrity: sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=} dev: true - /@rollup/plugin-babel/5.3.0_x2aor467pf57uz6h672f6uaxfe: + /@rollup/plugin-babel/5.3.0_@babel+core@7.17.7+rollup@2.74.1: resolution: {integrity: sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==} engines: {node: '>= 10.0.0'} peerDependencies: @@ -2633,7 +2624,11 @@ packages: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: true - /@typescript-eslint/eslint-plugin/5.26.0_hzuh7e2up357pvq3mkokjvu2lq: + /@types/web-bluetooth/0.0.14: + resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==} + dev: true + + /@typescript-eslint/eslint-plugin/5.26.0_3e687f93547efbf7d61b629ca4d69a5c: resolution: {integrity: sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2644,10 +2639,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@typescript-eslint/parser': 5.26.0_eslint@8.16.0+typescript@4.7.2 '@typescript-eslint/scope-manager': 5.26.0 - '@typescript-eslint/type-utils': 5.26.0_xztl6dhthcahlo6akmb2bmjmle - '@typescript-eslint/utils': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@typescript-eslint/type-utils': 5.26.0_eslint@8.16.0+typescript@4.7.2 + '@typescript-eslint/utils': 5.26.0_eslint@8.16.0+typescript@4.7.2 debug: 4.3.4 eslint: 8.16.0 functional-red-black-tree: 1.0.1 @@ -2660,7 +2655,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.26.0_xztl6dhthcahlo6akmb2bmjmle: + /@typescript-eslint/parser/5.26.0_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2688,7 +2683,7 @@ packages: '@typescript-eslint/visitor-keys': 5.26.0 dev: true - /@typescript-eslint/type-utils/5.26.0_xztl6dhthcahlo6akmb2bmjmle: + /@typescript-eslint/type-utils/5.26.0_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2698,7 +2693,7 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@typescript-eslint/utils': 5.26.0_eslint@8.16.0+typescript@4.7.2 debug: 4.3.4 eslint: 8.16.0 tsutils: 3.21.0_typescript@4.7.2 @@ -2733,7 +2728,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.26.0_xztl6dhthcahlo6akmb2bmjmle: + /@typescript-eslint/utils/5.26.0_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3007,12 +3002,12 @@ packages: vue: 3.2.36 dev: true - /@vue/theme/1.0.2_fxyydyqjavkblcmg2ywsuz264y: + /@vue/theme/1.0.2_2df181e2090554158986d62d2a675ee6: resolution: {integrity: sha512-jBALidvFMLgcR76UQ2foi4yD5gHn1YrigXJglZe3Rb0rm4KRVLxPeCe/CAfD42Wsm9xAfSNDUxRneQfbQpA1eg==} dependencies: '@docsearch/css': 3.0.0-alpha.42 '@docsearch/js': 3.0.0-alpha.42 - '@vueuse/core': 7.4.1_fxyydyqjavkblcmg2ywsuz264y + '@vueuse/core': 7.4.1_2df181e2090554158986d62d2a675ee6 body-scroll-lock: 3.1.5 normalize.css: 8.0.1 shiki: 0.9.15 @@ -3025,7 +3020,7 @@ packages: - vue dev: true - /@vueuse/core/7.4.1_fxyydyqjavkblcmg2ywsuz264y: + /@vueuse/core/7.4.1_2df181e2090554158986d62d2a675ee6: resolution: {integrity: sha512-8UeLPCAieeQLXFHF1/28SIEK6ILLPb/4hp03hR+xkXF00gB/YUp0CEVcRAL9uQ8HTZa3S2T/jTISMc1ZjilM0A==} peerDependencies: '@vue/composition-api': ^1.1.0 @@ -3037,12 +3032,12 @@ packages: optional: true dependencies: '@vue/composition-api': 1.6.2_vue@3.2.36 - '@vueuse/shared': 7.4.1_fxyydyqjavkblcmg2ywsuz264y + '@vueuse/shared': 7.4.1_2df181e2090554158986d62d2a675ee6 vue: 3.2.36 - vue-demi: 0.13.0_fxyydyqjavkblcmg2ywsuz264y + vue-demi: 0.13.0_2df181e2090554158986d62d2a675ee6 dev: true - /@vueuse/shared/7.4.1_fxyydyqjavkblcmg2ywsuz264y: + /@vueuse/shared/7.4.1_2df181e2090554158986d62d2a675ee6: resolution: {integrity: sha512-Pzb7XoHIcgPwwBJ5Ow9lZb0HTDyaLDV3pgxKauPGTMN9qvEylG06kUG+VTjJXkPsRtiGu46di8XyFeMw2dongA==} peerDependencies: '@vue/composition-api': ^1.1.0 @@ -3055,7 +3050,7 @@ packages: dependencies: '@vue/composition-api': 1.6.2_vue@3.2.36 vue: 3.2.36 - vue-demi: 0.13.0_fxyydyqjavkblcmg2ywsuz264y + vue-demi: 0.13.0_2df181e2090554158986d62d2a675ee6 dev: true /@xmldom/xmldom/0.7.5: @@ -3960,22 +3955,12 @@ packages: /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true dependencies: ms: 2.0.0 dev: true /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true dependencies: ms: 2.1.3 dev: true @@ -4978,40 +4963,20 @@ packages: dependencies: debug: 3.2.7 resolve: 1.22.0 - transitivePeerDependencies: - - supports-color dev: true - /eslint-module-utils/2.7.3_zhgf6mw2wzy6dnrak3ta47vb3m: + /eslint-module-utils/2.7.3: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true dependencies: - '@typescript-eslint/parser': 5.26.0_xztl6dhthcahlo6akmb2bmjmle debug: 3.2.7 - eslint-import-resolver-node: 0.3.6 find-up: 2.1.0 - transitivePeerDependencies: - - supports-color dev: true - /eslint-plugin-antfu/0.24.2_xztl6dhthcahlo6akmb2bmjmle: + /eslint-plugin-antfu/0.24.2_eslint@8.16.0+typescript@4.7.2: resolution: {integrity: sha512-WMvTNmI8h9eRTRUcTYgbECEXD8AwF+fjsTXiKNouD4a2pOps8WW9yjRnMOENk0/9vV5p52cu6PbJbfbM0/B/TA==} dependencies: - '@typescript-eslint/utils': 5.26.0_xztl6dhthcahlo6akmb2bmjmle + '@typescript-eslint/utils': 5.26.0_eslint@8.16.0+typescript@4.7.2 transitivePeerDependencies: - eslint - supports-color @@ -5046,24 +5011,19 @@ packages: htmlparser2: 7.2.0 dev: true - /eslint-plugin-import/2.26.0_grfei5yostfimvqdpf73rlhy3e: + /eslint-plugin-import/2.26.0_eslint@8.16.0: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: - '@typescript-eslint/parser': '*' eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true dependencies: - '@typescript-eslint/parser': 5.26.0_xztl6dhthcahlo6akmb2bmjmle array-includes: 3.1.4 array.prototype.flat: 1.2.5 debug: 2.6.9 doctrine: 2.1.0 eslint: 8.16.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3_zhgf6mw2wzy6dnrak3ta47vb3m + eslint-module-utils: 2.7.3 has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 @@ -5071,10 +5031,6 @@ packages: object.values: 1.1.5 resolve: 1.22.0 tsconfig-paths: 3.14.1 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color dev: true /eslint-plugin-jsonc/2.2.1_eslint@8.16.0: @@ -5401,6 +5357,7 @@ packages: terser: 5.10.0 yargs: 17.3.1 transitivePeerDependencies: + - acorn - supports-color dev: true @@ -7923,7 +7880,7 @@ packages: dev: true optional: true - /rollup-plugin-dts/4.2.1_durm56y4qsrp7annnznb67puce: + /rollup-plugin-dts/4.2.1_rollup@2.74.1+typescript@4.7.2: resolution: {integrity: sha512-eaxQZNUJ5iQcxNGlpJ1CUgG4OSVqWjDZ3nNSWBIoGrpcote2aNphSe1RJOaSYkb8dwn3o+rYm1vvld/5z3EGSQ==} engines: {node: '>=v12.22.11'} peerDependencies: @@ -7964,6 +7921,8 @@ packages: rollup: 2.74.1 serialize-javascript: 4.0.0 terser: 5.10.0 + transitivePeerDependencies: + - acorn dev: true /rollup/2.74.1: @@ -8591,6 +8550,8 @@ packages: resolution: {integrity: sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==} engines: {node: '>=10'} hasBin: true + peerDependencies: + acorn: ^8.5.0 peerDependenciesMeta: acorn: optional: true @@ -8938,7 +8899,7 @@ packages: - vite dev: true - /unplugin-icons/0.14.3_5ldljao7w6lsiq5e2abv2ioccy: + /unplugin-icons/0.14.3_eac6b481dfb7972443a4d0035d21c216: resolution: {integrity: sha512-PyyNMACpZ/EAiG3B6K1wPGZ151VGdlHIEx8/utgP546yVmPpV/xC1k1V2eEebf71fGm3WD6gzPrERNsbMgIVgg==} peerDependencies: '@svgr/core': '>=5.5.0' @@ -8971,7 +8932,7 @@ packages: - webpack dev: true - /unplugin-vue-components/0.19.5_spcnh6tolfhh3jo26jzl6kgg4m: + /unplugin-vue-components/0.19.5_93c4d3fa6e594e7da5daf272bf28c6e3: resolution: {integrity: sha512-cIC+PdQEXmG+B1gmZGk4hws2xP+00C6pg3FD6ixEgRyW+WF+QXQW/60pc+hUhtDYs1PFE+23K3NY7yvYTnDDTA==} engines: {node: '>=14'} peerDependencies: @@ -9167,6 +9128,7 @@ packages: workbox-window: 6.5.3 transitivePeerDependencies: - '@types/babel__core' + - acorn - supports-color dev: true @@ -9214,7 +9176,7 @@ packages: - stylus dev: true - /vitest/0.12.9_vrw6rgtr7itp6ghyrtnu3o3lrq: + /vitest/0.12.9_@vitest+ui@0.12.9+jsdom@19.0.0: resolution: {integrity: sha512-1NtyUANS72Qw5PwYvoztk067NX4fSiis2xQxhByOWS33eL2er/yupHyLxlBCOkF2ANe0dLFRvT1GVb+nczL5aw==} engines: {node: '>=v14.16.0'} hasBin: true @@ -9271,7 +9233,7 @@ packages: optional: true dev: false - /vue-demi/0.13.0_fxyydyqjavkblcmg2ywsuz264y: + /vue-demi/0.13.0_2df181e2090554158986d62d2a675ee6: resolution: {integrity: sha512-pu9R4Nydj+LMcKkIL1cnP1L2anJBTmVZzVWSdy5P1rkSRs9fxGCFrZmXdPTEsN37m5JtBVBSYKPk6xnORfjUsQ==} engines: {node: '>=12'} hasBin: true @@ -9478,7 +9440,7 @@ packages: '@babel/core': 7.17.7 '@babel/preset-env': 7.16.5_@babel+core@7.17.7 '@babel/runtime': 7.16.5 - '@rollup/plugin-babel': 5.3.0_x2aor467pf57uz6h672f6uaxfe + '@rollup/plugin-babel': 5.3.0_@babel+core@7.17.7+rollup@2.74.1 '@rollup/plugin-node-resolve': 11.2.1_rollup@2.74.1 '@rollup/plugin-replace': 2.4.2_rollup@2.74.1 '@surma/rollup-plugin-off-main-thread': 2.2.3 @@ -9513,6 +9475,7 @@ packages: workbox-window: 6.5.3 transitivePeerDependencies: - '@types/babel__core' + - acorn - supports-color dev: true From e8d848a828dd6710f14c999165492057c857d44c Mon Sep 17 00:00:00 2001 From: "Michael J. Roberts" Date: Sun, 5 Jun 2022 12:08:50 +0100 Subject: [PATCH 8/8] fix: missing space before function parentheses --- packages/core/useBluetooth/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/useBluetooth/index.md b/packages/core/useBluetooth/index.md index 8721e12f974..6bf2d62a921 100644 --- a/packages/core/useBluetooth/index.md +++ b/packages/core/useBluetooth/index.md @@ -66,7 +66,7 @@ const batteryPercent = ref() const isGettingBatteryLevels = ref(false) -const getBatteryLevels = async() => { +const getBatteryLevels = async () => { isGettingBatteryLevels.value = true // Get the battery service: