@ovok/native 1.16.1-dev.2143 → 1.16.1-dev.2145
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/lib/commonjs/modules/next/bluetooth/ble-plx/ble-peripheral.js +35 -0
- package/lib/commonjs/modules/next/bluetooth/ble-plx/ble-peripheral.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/ble-plx/ble-scanner.js +3 -30
- package/lib/commonjs/modules/next/bluetooth/ble-plx/ble-scanner.js.map +1 -1
- package/lib/commonjs/modules/next/bluetooth/ble-plx/legacy-driver.js +2 -2
- package/lib/commonjs/modules/next/bluetooth/ble-plx/legacy-driver.js.map +1 -1
- package/lib/commonjs/modules/next/bluetooth/react-native/ovok-sink.js.map +1 -1
- package/lib/commonjs/modules/next/bluetooth/web/create-web-bluetooth-runtime.js +28 -0
- package/lib/commonjs/modules/next/bluetooth/web/create-web-bluetooth-runtime.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/index.js +208 -0
- package/lib/commonjs/modules/next/bluetooth/web/index.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-ble-device.js +143 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-ble-device.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-ble-shapes.js +43 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-ble-shapes.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-permissions.js +21 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-permissions.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-scanner.js +133 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-scanner.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-services.js +28 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-services.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-values.js +37 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth-values.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth.types.js +2 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-bluetooth.types.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-gatt.js +83 -0
- package/lib/commonjs/modules/next/bluetooth/web/web-gatt.js.map +1 -0
- package/lib/module/modules/next/bluetooth/ble-plx/ble-peripheral.js +30 -0
- package/lib/module/modules/next/bluetooth/ble-plx/ble-peripheral.js.map +1 -0
- package/lib/module/modules/next/bluetooth/ble-plx/ble-scanner.js +2 -27
- package/lib/module/modules/next/bluetooth/ble-plx/ble-scanner.js.map +1 -1
- package/lib/module/modules/next/bluetooth/ble-plx/legacy-driver.js +1 -1
- package/lib/module/modules/next/bluetooth/ble-plx/legacy-driver.js.map +1 -1
- package/lib/module/modules/next/bluetooth/react-native/ovok-sink.js.map +1 -1
- package/lib/module/modules/next/bluetooth/web/create-web-bluetooth-runtime.js +25 -0
- package/lib/module/modules/next/bluetooth/web/create-web-bluetooth-runtime.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/index.js +28 -0
- package/lib/module/modules/next/bluetooth/web/index.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-ble-device.js +140 -0
- package/lib/module/modules/next/bluetooth/web/web-ble-device.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-ble-shapes.js +39 -0
- package/lib/module/modules/next/bluetooth/web/web-ble-shapes.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-permissions.js +18 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-permissions.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-scanner.js +128 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-scanner.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-services.js +25 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-services.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-values.js +29 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth-values.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth.types.js +2 -0
- package/lib/module/modules/next/bluetooth/web/web-bluetooth.types.js.map +1 -0
- package/lib/module/modules/next/bluetooth/web/web-gatt.js +79 -0
- package/lib/module/modules/next/bluetooth/web/web-gatt.js.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-link.d.ts +1 -1
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-link.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-peripheral.d.ts +8 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-peripheral.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-scanner.d.ts +3 -7
- package/lib/typescript/commonjs/src/modules/next/bluetooth/ble-plx/ble-scanner.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/next/bluetooth/react-native/ovok-sink.d.ts +2 -2
- package/lib/typescript/commonjs/src/modules/next/bluetooth/react-native/ovok-sink.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts +23 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/index.d.ts +41 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-ble-device.d.ts +53 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-ble-device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-ble-shapes.d.ts +27 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-ble-shapes.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-permissions.d.ts +8 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-permissions.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-scanner.d.ts +29 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-scanner.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-services.d.ts +10 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-services.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-values.d.ts +9 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth-values.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth.types.d.ts +56 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-bluetooth.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-gatt.d.ts +27 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/web/web-gatt.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-link.d.ts +1 -1
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-link.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-peripheral.d.ts +8 -0
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-peripheral.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-scanner.d.ts +3 -7
- package/lib/typescript/module/src/modules/next/bluetooth/ble-plx/ble-scanner.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/next/bluetooth/react-native/ovok-sink.d.ts +2 -2
- package/lib/typescript/module/src/modules/next/bluetooth/react-native/ovok-sink.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts +23 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/index.d.ts +41 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/index.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-ble-device.d.ts +53 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-ble-device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-ble-shapes.d.ts +27 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-ble-shapes.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-permissions.d.ts +8 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-permissions.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-scanner.d.ts +29 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-scanner.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-services.d.ts +10 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-services.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-values.d.ts +9 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth-values.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth.types.d.ts +56 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-bluetooth.types.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-gatt.d.ts +27 -0
- package/lib/typescript/module/src/modules/next/bluetooth/web/web-gatt.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DEVICE_DISCONNECTED, toBleCharacteristic, WebBleError } from "./web-ble-shapes.js";
|
|
4
|
+
import { bytesOf, canonicalUuid, fromBase64, toBase64 } from "./web-bluetooth-values.js";
|
|
5
|
+
import { WebGatt } from "./web-gatt.js";
|
|
6
|
+
|
|
7
|
+
/** The ATT default; browsers negotiate a larger MTU themselves and expose no way to ask for one. */
|
|
8
|
+
const DEFAULT_MTU = 23;
|
|
9
|
+
const VALUE_CHANGED = "characteristicvaluechanged";
|
|
10
|
+
const DISCONNECTED = "gattserverdisconnected";
|
|
11
|
+
|
|
12
|
+
/** Advertising data a browser saw for the device, when it let the page watch advertisements. */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A Web Bluetooth device behind the part of the `react-native-ble-plx` `Device` API the SDK's device classes use, so
|
|
16
|
+
* every integrated device and `defineCustomDevice` declaration runs unchanged in a browser. Operations queue (see
|
|
17
|
+
* `WebGatt`), so a write also waits for notifications still being started.
|
|
18
|
+
*/
|
|
19
|
+
class WebBleDevice {
|
|
20
|
+
mtu = DEFAULT_MTU;
|
|
21
|
+
rssi = null;
|
|
22
|
+
monitors = new Set();
|
|
23
|
+
disconnectListeners = new Set();
|
|
24
|
+
constructor(device, advertisement) {
|
|
25
|
+
this.id = device.id;
|
|
26
|
+
this.name = device.name?.trim() || null;
|
|
27
|
+
this.localName = this.name;
|
|
28
|
+
this.manufacturerData = advertisement?.manufacturerData ?? null;
|
|
29
|
+
this.serviceUUIDs = advertisement?.serviceUUIDs ?? null;
|
|
30
|
+
this.gatt = new WebGatt(device);
|
|
31
|
+
device.addEventListener(DISCONNECTED, this.onDisconnect);
|
|
32
|
+
}
|
|
33
|
+
async connect() {
|
|
34
|
+
await this.gatt.server().connect();
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
async isConnected() {
|
|
38
|
+
return this.gatt.connected;
|
|
39
|
+
}
|
|
40
|
+
async cancelConnection() {
|
|
41
|
+
if (this.gatt.connected) {
|
|
42
|
+
this.gatt.server().disconnect();
|
|
43
|
+
}
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
async requestMTU() {
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Discovers the services, and reports them as advertised when the browser showed none. */
|
|
51
|
+
async discoverAllServicesAndCharacteristics() {
|
|
52
|
+
const uuids = await this.gatt.queued(() => {
|
|
53
|
+
this.gatt.forget();
|
|
54
|
+
return this.gatt.serviceUuids();
|
|
55
|
+
});
|
|
56
|
+
if (!this.serviceUUIDs?.length) {
|
|
57
|
+
this.serviceUUIDs = uuids;
|
|
58
|
+
}
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
services() {
|
|
62
|
+
return this.gatt.queued(async () => (await this.gatt.serviceUuids()).map(uuid => ({
|
|
63
|
+
uuid,
|
|
64
|
+
deviceID: this.id,
|
|
65
|
+
isPrimary: true
|
|
66
|
+
})));
|
|
67
|
+
}
|
|
68
|
+
characteristicsForService(serviceUuid) {
|
|
69
|
+
return this.gatt.queued(async () => (await this.gatt.characteristicsOf(serviceUuid)).map(characteristic => toBleCharacteristic(this.id, canonicalUuid(serviceUuid), characteristic, null)));
|
|
70
|
+
}
|
|
71
|
+
readCharacteristicForService(serviceUuid, characteristicUuid) {
|
|
72
|
+
return this.gatt.queued(async () => {
|
|
73
|
+
const characteristic = await this.gatt.characteristic(serviceUuid, characteristicUuid);
|
|
74
|
+
const value = await characteristic.readValue();
|
|
75
|
+
return toBleCharacteristic(this.id, canonicalUuid(serviceUuid), characteristic, toBase64(bytesOf(value)));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
writeCharacteristicWithResponseForService(serviceUuid, characteristicUuid, base64) {
|
|
79
|
+
return this.write(serviceUuid, characteristicUuid, base64, true);
|
|
80
|
+
}
|
|
81
|
+
writeCharacteristicWithoutResponseForService(serviceUuid, characteristicUuid, base64) {
|
|
82
|
+
return this.write(serviceUuid, characteristicUuid, base64, false);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Starts notifications in the GATT queue; `listener` gets each value, then `DeviceDisconnected` if the link drops. */
|
|
86
|
+
monitorCharacteristicForService(serviceUuid, characteristicUuid, listener) {
|
|
87
|
+
let characteristic;
|
|
88
|
+
let active = true;
|
|
89
|
+
const onValue = event => {
|
|
90
|
+
const value = event.target?.value;
|
|
91
|
+
if (active && characteristic && value) {
|
|
92
|
+
const base64 = toBase64(bytesOf(value));
|
|
93
|
+
listener(null, toBleCharacteristic(this.id, canonicalUuid(serviceUuid), characteristic, base64));
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const stop = () => {
|
|
97
|
+
const started = characteristic;
|
|
98
|
+
started?.removeEventListener(VALUE_CHANGED, onValue);
|
|
99
|
+
void this.gatt.queued(async () => started?.stopNotifications()).catch(() => undefined);
|
|
100
|
+
};
|
|
101
|
+
this.monitors.add(listener);
|
|
102
|
+
this.gatt.queued(async () => {
|
|
103
|
+
characteristic = await this.gatt.characteristic(serviceUuid, characteristicUuid);
|
|
104
|
+
characteristic.addEventListener(VALUE_CHANGED, onValue);
|
|
105
|
+
await characteristic.startNotifications();
|
|
106
|
+
}).then(() => !active && stop(), error => active && listener(this.gatt.errorOf(error), null));
|
|
107
|
+
return {
|
|
108
|
+
remove: () => {
|
|
109
|
+
if (active) {
|
|
110
|
+
active = false;
|
|
111
|
+
this.monitors.delete(listener);
|
|
112
|
+
stop();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
onDisconnected(listener) {
|
|
118
|
+
this.disconnectListeners.add(listener);
|
|
119
|
+
return {
|
|
120
|
+
remove: () => this.disconnectListeners.delete(listener)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
onDisconnect = () => {
|
|
124
|
+
const error = new WebBleError(DEVICE_DISCONNECTED, `Device ${this.id} was disconnected`);
|
|
125
|
+
[...this.monitors].forEach(listener => listener(error, null));
|
|
126
|
+
this.monitors.clear();
|
|
127
|
+
this.gatt.forget();
|
|
128
|
+
[...this.disconnectListeners].forEach(listener => listener(null, this));
|
|
129
|
+
};
|
|
130
|
+
write(serviceUuid, characteristicUuid, base64, withResponse) {
|
|
131
|
+
return this.gatt.queued(async () => {
|
|
132
|
+
const characteristic = await this.gatt.characteristic(serviceUuid, characteristicUuid);
|
|
133
|
+
const writeValue = withResponse ? characteristic.writeValueWithResponse : characteristic.writeValueWithoutResponse;
|
|
134
|
+
await (writeValue ?? characteristic.writeValue).call(characteristic, fromBase64(base64));
|
|
135
|
+
return toBleCharacteristic(this.id, canonicalUuid(serviceUuid), characteristic, base64);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export { WebBleDevice };
|
|
140
|
+
//# sourceMappingURL=web-ble-device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEVICE_DISCONNECTED","toBleCharacteristic","WebBleError","bytesOf","canonicalUuid","fromBase64","toBase64","WebGatt","DEFAULT_MTU","VALUE_CHANGED","DISCONNECTED","WebBleDevice","mtu","rssi","monitors","Set","disconnectListeners","constructor","device","advertisement","id","name","trim","localName","manufacturerData","serviceUUIDs","gatt","addEventListener","onDisconnect","connect","server","isConnected","connected","cancelConnection","disconnect","requestMTU","discoverAllServicesAndCharacteristics","uuids","queued","forget","serviceUuids","length","services","map","uuid","deviceID","isPrimary","characteristicsForService","serviceUuid","characteristicsOf","characteristic","readCharacteristicForService","characteristicUuid","value","readValue","writeCharacteristicWithResponseForService","base64","write","writeCharacteristicWithoutResponseForService","monitorCharacteristicForService","listener","active","onValue","event","target","stop","started","removeEventListener","stopNotifications","catch","undefined","add","startNotifications","then","error","errorOf","remove","delete","onDisconnected","forEach","clear","withResponse","writeValue","writeValueWithResponse","writeValueWithoutResponse","call"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-ble-device.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { canonicalUuid } from "./web-bluetooth-values.js";
|
|
4
|
+
/** `react-native-ble-plx`'s BleErrorCode.DeviceDisconnected, which ends a link instead of failing it. */
|
|
5
|
+
const DEVICE_DISCONNECTED = 201;
|
|
6
|
+
const UNKNOWN_ERROR = 0;
|
|
7
|
+
|
|
8
|
+
/** A failed Web Bluetooth operation in the shape `react-native-ble-plx` reports errors. */
|
|
9
|
+
class WebBleError extends Error {
|
|
10
|
+
constructor(errorCode, message, reason) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.errorCode = errorCode;
|
|
13
|
+
this.reason = reason;
|
|
14
|
+
this.name = "BleError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A characteristic in the shape `react-native-ble-plx` returns one, with its value as base64. */
|
|
19
|
+
|
|
20
|
+
const toBleCharacteristic = (deviceID, serviceUUID, characteristic, value) => {
|
|
21
|
+
const {
|
|
22
|
+
properties
|
|
23
|
+
} = characteristic;
|
|
24
|
+
const uuid = canonicalUuid(characteristic.uuid);
|
|
25
|
+
return {
|
|
26
|
+
id: `${serviceUUID}/${uuid}`,
|
|
27
|
+
uuid,
|
|
28
|
+
serviceUUID,
|
|
29
|
+
deviceID,
|
|
30
|
+
value,
|
|
31
|
+
isReadable: properties.read,
|
|
32
|
+
isWritableWithResponse: properties.write,
|
|
33
|
+
isWritableWithoutResponse: properties.writeWithoutResponse,
|
|
34
|
+
isNotifiable: properties.notify,
|
|
35
|
+
isIndicatable: properties.indicate
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export { DEVICE_DISCONNECTED, toBleCharacteristic, UNKNOWN_ERROR, WebBleError };
|
|
39
|
+
//# sourceMappingURL=web-ble-shapes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["canonicalUuid","DEVICE_DISCONNECTED","UNKNOWN_ERROR","WebBleError","Error","constructor","errorCode","message","reason","name","toBleCharacteristic","deviceID","serviceUUID","characteristic","value","properties","uuid","id","isReadable","read","isWritableWithResponse","write","isWritableWithoutResponse","writeWithoutResponse","isNotifiable","notify","isIndicatable","indicate"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-ble-shapes.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,2BAAwB;AAGtD;AACA,MAAMC,mBAAmB,GAAG,GAAG;AAC/B,MAAMC,aAAa,GAAG,CAAC;;AAEvB;AACA,MAAMC,WAAW,SAASC,KAAK,CAAC;EACvBC,WAAWA,CAAiBC,SAAiB,EAAEC,OAAe,EAAkBC,MAAgB,EAAE;IACvG,KAAK,CAACD,OAAO,CAAC;IAAC,KADkBD,SAAiB,GAAjBA,SAAiB;IAAA,KAAmCE,MAAgB,GAAhBA,MAAgB;IAErG,IAAI,CAACC,IAAI,GAAG,UAAU;EACxB;AACF;;AAEA;;AAcA,MAAMC,mBAAmB,GAAGA,CAC1BC,QAAgB,EAChBC,WAAmB,EACnBC,cAA0C,EAC1CC,KAAoB,KACE;EACtB,MAAM;IAAEC;EAAW,CAAC,GAAGF,cAAc;EACrC,MAAMG,IAAI,GAAGhB,aAAa,CAACa,cAAc,CAACG,IAAI,CAAC;EAE/C,OAAO;IACLC,EAAE,EAAE,GAAGL,WAAW,IAAII,IAAI,EAAE;IAC5BA,IAAI;IACJJ,WAAW;IACXD,QAAQ;IACRG,KAAK;IACLI,UAAU,EAAEH,UAAU,CAACI,IAAI;IAC3BC,sBAAsB,EAAEL,UAAU,CAACM,KAAK;IACxCC,yBAAyB,EAAEP,UAAU,CAACQ,oBAAoB;IAC1DC,YAAY,EAAET,UAAU,CAACU,MAAM;IAC/BC,aAAa,EAAEX,UAAU,CAACY;EAC5B,CAAC;AACH,CAAC;AAED,SAAS1B,mBAAmB,EAAES,mBAAmB,EAAER,aAAa,EAAEC,WAAW","ignoreList":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { isWebBluetoothAvailable } from "./web-bluetooth-scanner.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Browser permissions: the browser asks per device in its chooser, so there is no prompt to show first. Granted where
|
|
7
|
+
* the browser has Web Bluetooth, denied where it has none; no settings page can change that.
|
|
8
|
+
*/
|
|
9
|
+
const webBluetoothPermissions = () => {
|
|
10
|
+
const permission = async () => isWebBluetoothAvailable() ? "granted" : "denied";
|
|
11
|
+
return {
|
|
12
|
+
check: permission,
|
|
13
|
+
request: permission,
|
|
14
|
+
openSettings: async () => undefined
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export { webBluetoothPermissions };
|
|
18
|
+
//# sourceMappingURL=web-bluetooth-permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isWebBluetoothAvailable","webBluetoothPermissions","permission","check","request","openSettings","undefined"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-bluetooth-permissions.ts"],"mappings":";;AAEA,SAASA,uBAAuB,QAAQ,4BAAyB;;AAEjE;AACA;AACA;AACA;AACA,MAAMC,uBAAuB,GAAGA,CAAA,KAA4B;EAC1D,MAAMC,UAAU,GAAG,MAAAA,CAAA,KAA2CF,uBAAuB,CAAC,CAAC,GAAG,SAAS,GAAG,QAAS;EAE/G,OAAO;IAAEG,KAAK,EAAED,UAAU;IAAEE,OAAO,EAAEF,UAAU;IAAEG,YAAY,EAAE,MAAAA,CAAA,KAAYC;EAAU,CAAC;AACxF,CAAC;AAED,SAASL,uBAAuB","ignoreList":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { fromBleError } from "../ble-plx/ble-errors.js";
|
|
4
|
+
import { blePeripheral } from "../ble-plx/ble-peripheral.js";
|
|
5
|
+
import { BluetoothError } from "../errors.js";
|
|
6
|
+
import { WebBleDevice } from "./web-ble-device.js";
|
|
7
|
+
import { webBluetoothServicesFor } from "./web-bluetooth-services.js";
|
|
8
|
+
import { canonicalUuid, manufacturerDataOf } from "./web-bluetooth-values.js";
|
|
9
|
+
/** How long a device gets to advertise, where the browser lets the page watch, before it is reported without. */
|
|
10
|
+
const ADVERTISEMENT_WAIT_MS = 1500;
|
|
11
|
+
const CHOOSER_CLOSED = "NotFoundError";
|
|
12
|
+
|
|
13
|
+
/** What `webBluetoothScanner` needs. */
|
|
14
|
+
|
|
15
|
+
/** A `BluetoothScanner` for browsers, where a page only reaches the devices the user picks in the browser's chooser. */
|
|
16
|
+
|
|
17
|
+
const navigatorBluetooth = () => globalThis.navigator?.bluetooth;
|
|
18
|
+
|
|
19
|
+
/** Whether this browser has Web Bluetooth, such as Chrome and Edge on desktop and Android, or Bluefy on iOS. */
|
|
20
|
+
const isWebBluetoothAvailable = () => navigatorBluetooth() !== undefined;
|
|
21
|
+
const unsupported = () => new BluetoothError("unsupported", "This browser has no Web Bluetooth");
|
|
22
|
+
|
|
23
|
+
/** The first advertisement the browser reports, when it lets the page watch them, so names alone need not match. */
|
|
24
|
+
const advertisementOf = device => {
|
|
25
|
+
if (typeof device.watchAdvertisements !== "function") {
|
|
26
|
+
return Promise.resolve(undefined);
|
|
27
|
+
}
|
|
28
|
+
return new Promise(resolve => {
|
|
29
|
+
const watching = new AbortController();
|
|
30
|
+
const done = advertisement => {
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
device.removeEventListener("advertisementreceived", received);
|
|
33
|
+
watching.abort();
|
|
34
|
+
resolve(advertisement);
|
|
35
|
+
};
|
|
36
|
+
const received = event => {
|
|
37
|
+
const {
|
|
38
|
+
uuids,
|
|
39
|
+
manufacturerData
|
|
40
|
+
} = event;
|
|
41
|
+
done({
|
|
42
|
+
serviceUUIDs: uuids?.map(canonicalUuid) ?? null,
|
|
43
|
+
manufacturerData: manufacturerDataOf(manufacturerData)
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const timer = setTimeout(() => done(), ADVERTISEMENT_WAIT_MS);
|
|
47
|
+
device.addEventListener("advertisementreceived", received);
|
|
48
|
+
device.watchAdvertisements?.({
|
|
49
|
+
signal: watching.signal
|
|
50
|
+
}).catch(() => done());
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Finds devices through Web Bluetooth. A scan reports the devices this site may already use (`getDevices`, where the
|
|
56
|
+
* browser has it) and every device picked with `chooseDevice`; browsers can't scan in the background or without the
|
|
57
|
+
* user picking.
|
|
58
|
+
*/
|
|
59
|
+
const webBluetoothScanner = ({
|
|
60
|
+
acceptedDevices,
|
|
61
|
+
bluetooth = navigatorBluetooth()
|
|
62
|
+
} = {}) => {
|
|
63
|
+
const optionalServices = webBluetoothServicesFor(acceptedDevices);
|
|
64
|
+
const scans = new Set();
|
|
65
|
+
const devices = new Map();
|
|
66
|
+
const peripheralOf = async device => {
|
|
67
|
+
let bleDevice = devices.get(device.id);
|
|
68
|
+
if (!bleDevice) {
|
|
69
|
+
bleDevice = new WebBleDevice(device, await advertisementOf(device));
|
|
70
|
+
devices.set(device.id, bleDevice);
|
|
71
|
+
}
|
|
72
|
+
if (!bleDevice.serviceUUIDs?.length) {
|
|
73
|
+
// Devices told apart by their services alone (the SIG profiles) need them, and only a connection reveals them.
|
|
74
|
+
await bleDevice.connect().then(connected => connected.discoverAllServicesAndCharacteristics()).catch(() => undefined);
|
|
75
|
+
}
|
|
76
|
+
return blePeripheral(bleDevice);
|
|
77
|
+
};
|
|
78
|
+
const report = async device => {
|
|
79
|
+
const peripheral = await peripheralOf(device);
|
|
80
|
+
scans.forEach(onFound => onFound(peripheral));
|
|
81
|
+
return peripheral;
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
watchState: listener => {
|
|
85
|
+
if (!bluetooth) {
|
|
86
|
+
listener("unsupported");
|
|
87
|
+
return () => undefined;
|
|
88
|
+
}
|
|
89
|
+
let watching = true;
|
|
90
|
+
const changed = event => watching && listener(event.value ? "on" : "off");
|
|
91
|
+
bluetooth.addEventListener("availabilitychanged", changed);
|
|
92
|
+
bluetooth.getAvailability().then(available => watching && listener(available ? "on" : "off"), () => watching && listener("unknown"));
|
|
93
|
+
return () => {
|
|
94
|
+
watching = false;
|
|
95
|
+
bluetooth.removeEventListener("availabilitychanged", changed);
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
scan: (onFound, onError) => {
|
|
99
|
+
if (!bluetooth) {
|
|
100
|
+
onError(unsupported());
|
|
101
|
+
return () => undefined;
|
|
102
|
+
}
|
|
103
|
+
scans.add(onFound);
|
|
104
|
+
bluetooth.getDevices?.().then(allowed => allowed.forEach(device => void report(device)), error => onError(fromBleError(error)));
|
|
105
|
+
return () => {
|
|
106
|
+
scans.delete(onFound);
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
chooseDevice: async () => {
|
|
110
|
+
if (!bluetooth) {
|
|
111
|
+
throw unsupported();
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
return await report(await bluetooth.requestDevice({
|
|
115
|
+
acceptAllDevices: true,
|
|
116
|
+
optionalServices
|
|
117
|
+
}));
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (error?.name === CHOOSER_CLOSED) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
throw fromBleError(error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
export { isWebBluetoothAvailable, webBluetoothScanner };
|
|
128
|
+
//# sourceMappingURL=web-bluetooth-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fromBleError","blePeripheral","BluetoothError","WebBleDevice","webBluetoothServicesFor","canonicalUuid","manufacturerDataOf","ADVERTISEMENT_WAIT_MS","CHOOSER_CLOSED","navigatorBluetooth","globalThis","navigator","bluetooth","isWebBluetoothAvailable","undefined","unsupported","advertisementOf","device","watchAdvertisements","Promise","resolve","watching","AbortController","done","advertisement","clearTimeout","timer","removeEventListener","received","abort","event","uuids","manufacturerData","serviceUUIDs","map","setTimeout","addEventListener","signal","catch","webBluetoothScanner","acceptedDevices","optionalServices","scans","Set","devices","Map","peripheralOf","bleDevice","get","id","set","length","connect","then","connected","discoverAllServicesAndCharacteristics","report","peripheral","forEach","onFound","watchState","listener","changed","value","getAvailability","available","scan","onError","add","getDevices","allowed","error","delete","chooseDevice","requestDevice","acceptAllDevices","name"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-bluetooth-scanner.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { getBackgroundServiceUUIDs } from "../../../bt-management/services/background-sync/background-service-uuids.js";
|
|
4
|
+
import { IntegratedDevices } from "../../../bt-management/types/integrated-devices.js";
|
|
5
|
+
import { canonicalUuid } from "./web-bluetooth-values.js";
|
|
6
|
+
|
|
7
|
+
/** Services read on every connection, whatever the device. */
|
|
8
|
+
const SHARED_SERVICES = ["1800", "180a", "180f", "1805", "1804"];
|
|
9
|
+
|
|
10
|
+
/** Bluetooth SIG profiles: glucose, thermometer, heart rate, blood pressure, weight scale, pulse oximeter. */
|
|
11
|
+
const SIG_SERVICES = ["1808", "1809", "180d", "1810", "181d", "1822"];
|
|
12
|
+
|
|
13
|
+
/** Services the integrated devices' protocols use beyond their background-scan services. */
|
|
14
|
+
const PROTOCOL_SERVICES = ["1000", "18f0", "7801", "7802", "7809", "7889", "7892", "a000", "a500", "a602", "a610", "ae30", "f018", "fe60", "fee0", "ff00", "ff12", "ffb0", "ffe0", "ffe5", "fff0", "ffff", "14839ac4-7d7e-415c-9a42-167340cf2339", "e8fb0001-a14b-98f9-831b-4e2941d01248", "00002760-08c2-11e1-9073-0e8ac72e5450", "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "cdeacb80-5235-4c07-8846-93a37ee6b86d", "cdeacd80-5235-4c07-8846-93a37ee6b86d", "49535343-fe7d-4ae5-8fa9-9fafd205e455", "81eea003-e735-49ec-8a11-7e32cae1e14e", "5d4b8aa6-a26a-4a1b-99f5-cd4473c786e3", "2610fc00-494d-494c-4544-55544954414c", "233bf000-5a34-1b6d-975c-000d5690abe4", "23434100-1fe4-1eff-80cb-00ff78297d8b", "00001523-1212-efde-1523-785feabcd123", "0003cdd0-0000-1000-8000-00805f9b0131", "00010203-0405-0607-0809-0a0b0c0d1910", "fb349b5f-8000-0080-0010-0000f0180000"];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Every GATT service an integrated device uses, as a browser must be told when the user picks a device: a page can
|
|
18
|
+
* only reach the services it named in `navigator.bluetooth.requestDevice`'s `optionalServices`.
|
|
19
|
+
*/
|
|
20
|
+
const WEB_BLUETOOTH_SERVICES = [...new Set([...SHARED_SERVICES, ...SIG_SERVICES, ...PROTOCOL_SERVICES, ...getBackgroundServiceUUIDs(Object.values(IntegratedDevices))].map(canonicalUuid))];
|
|
21
|
+
|
|
22
|
+
/** `WEB_BLUETOOTH_SERVICES` and the services of the `defineCustomDevice` declarations among `acceptedDevices`. */
|
|
23
|
+
const webBluetoothServicesFor = (acceptedDevices = []) => [...new Set([...WEB_BLUETOOTH_SERVICES, ...getBackgroundServiceUUIDs(acceptedDevices).map(canonicalUuid)])];
|
|
24
|
+
export { WEB_BLUETOOTH_SERVICES, webBluetoothServicesFor };
|
|
25
|
+
//# sourceMappingURL=web-bluetooth-services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["getBackgroundServiceUUIDs","IntegratedDevices","canonicalUuid","SHARED_SERVICES","SIG_SERVICES","PROTOCOL_SERVICES","WEB_BLUETOOTH_SERVICES","Set","Object","values","map","webBluetoothServicesFor","acceptedDevices"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-bluetooth-services.ts"],"mappings":";;AAAA,SAASA,yBAAyB,QAAQ,6EAA0E;AAEpH,SAASC,iBAAiB,QAAQ,oDAAiD;AAEnF,SAASC,aAAa,QAAQ,2BAAwB;;AAEtD;AACA,MAAMC,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;;AAEhE;AACA,MAAMC,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;;AAErE;AACA,MAAMC,iBAAiB,GAAG,CACxB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9D,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,EACtC,sCAAsC,CACvC;;AAED;AACA;AACA;AACA;AACA,MAAMC,sBAAyC,GAAG,CAChD,GAAG,IAAIC,GAAG,CACR,CACE,GAAGJ,eAAe,EAClB,GAAGC,YAAY,EACf,GAAGC,iBAAiB,EACpB,GAAGL,yBAAyB,CAACQ,MAAM,CAACC,MAAM,CAACR,iBAAiB,CAAC,CAAC,CAC/D,CAACS,GAAG,CAACR,aAAa,CACrB,CAAC,CACF;;AAED;AACA,MAAMS,uBAAuB,GAAGA,CAACC,eAA0C,GAAG,EAAE,KAAe,CAC7F,GAAG,IAAIL,GAAG,CAAC,CAAC,GAAGD,sBAAsB,EAAE,GAAGN,yBAAyB,CAACY,eAAe,CAAC,CAACF,GAAG,CAACR,aAAa,CAAC,CAAC,CAAC,CAC1G;AAED,SAASI,sBAAsB,EAAEK,uBAAuB","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const BASE_UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb";
|
|
4
|
+
const SHORT_UUID = /^[0-9a-f]{4}$/;
|
|
5
|
+
const MEDIUM_UUID = /^[0-9a-f]{8}$/;
|
|
6
|
+
|
|
7
|
+
/** A UUID as Web Bluetooth accepts it: lower case, with a 16- or 32-bit alias expanded on the Bluetooth base UUID. */
|
|
8
|
+
const canonicalUuid = uuid => {
|
|
9
|
+
const lower = uuid.trim().toLowerCase();
|
|
10
|
+
if (SHORT_UUID.test(lower)) {
|
|
11
|
+
return `0000${lower}${BASE_UUID_SUFFIX}`;
|
|
12
|
+
}
|
|
13
|
+
return MEDIUM_UUID.test(lower) ? `${lower}${BASE_UUID_SUFFIX}` : lower;
|
|
14
|
+
};
|
|
15
|
+
const bytesOf = view => new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
16
|
+
const toBase64 = bytes => btoa(Array.from(bytes, byte => String.fromCharCode(byte)).join(""));
|
|
17
|
+
const fromBase64 = base64 => Uint8Array.from(atob(base64), char => char.charCodeAt(0));
|
|
18
|
+
|
|
19
|
+
/** Manufacturer data the way `react-native-ble-plx` reports it: the company ID, little endian, then the payload. */
|
|
20
|
+
const manufacturerDataOf = data => {
|
|
21
|
+
const [entry] = data ?? [];
|
|
22
|
+
if (!entry) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const [companyId, payload] = entry;
|
|
26
|
+
return toBase64(Uint8Array.from([companyId & 0xff, companyId >> 8, ...bytesOf(payload)]));
|
|
27
|
+
};
|
|
28
|
+
export { bytesOf, canonicalUuid, fromBase64, manufacturerDataOf, toBase64 };
|
|
29
|
+
//# sourceMappingURL=web-bluetooth-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["BASE_UUID_SUFFIX","SHORT_UUID","MEDIUM_UUID","canonicalUuid","uuid","lower","trim","toLowerCase","test","bytesOf","view","Uint8Array","buffer","byteOffset","byteLength","toBase64","bytes","btoa","Array","from","byte","String","fromCharCode","join","fromBase64","base64","atob","char","charCodeAt","manufacturerDataOf","data","entry","companyId","payload"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-bluetooth-values.ts"],"mappings":";;AAAA,MAAMA,gBAAgB,GAAG,8BAA8B;AACvD,MAAMC,UAAU,GAAG,eAAe;AAClC,MAAMC,WAAW,GAAG,eAAe;;AAEnC;AACA,MAAMC,aAAa,GAAIC,IAAY,IAAa;EAC9C,MAAMC,KAAK,GAAGD,IAAI,CAACE,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;EAEvC,IAAIN,UAAU,CAACO,IAAI,CAACH,KAAK,CAAC,EAAE;IAC1B,OAAO,OAAOA,KAAK,GAAGL,gBAAgB,EAAE;EAC1C;EAEA,OAAOE,WAAW,CAACM,IAAI,CAACH,KAAK,CAAC,GAAG,GAAGA,KAAK,GAAGL,gBAAgB,EAAE,GAAGK,KAAK;AACxE,CAAC;AAED,MAAMI,OAAO,GAAIC,IAAc,IAAiB,IAAIC,UAAU,CAACD,IAAI,CAACE,MAAM,EAAEF,IAAI,CAACG,UAAU,EAAEH,IAAI,CAACI,UAAU,CAAC;AAE7G,MAAMC,QAAQ,GAAIC,KAAiB,IAAaC,IAAI,CAACC,KAAK,CAACC,IAAI,CAACH,KAAK,EAAGI,IAAI,IAAKC,MAAM,CAACC,YAAY,CAACF,IAAI,CAAC,CAAC,CAACG,IAAI,CAAC,EAAE,CAAC,CAAC;AAErH,MAAMC,UAAU,GAAIC,MAAc,IAAiBd,UAAU,CAACQ,IAAI,CAACO,IAAI,CAACD,MAAM,CAAC,EAAGE,IAAI,IAAKA,IAAI,CAACC,UAAU,CAAC,CAAC,CAAC,CAAC;;AAE9G;AACA,MAAMC,kBAAkB,GAAIC,IAA+C,IAAoB;EAC7F,MAAM,CAACC,KAAK,CAAC,GAAGD,IAAI,IAAI,EAAE;EAE1B,IAAI,CAACC,KAAK,EAAE;IACV,OAAO,IAAI;EACb;EAEA,MAAM,CAACC,SAAS,EAAEC,OAAO,CAAC,GAAGF,KAAK;EAElC,OAAOhB,QAAQ,CAACJ,UAAU,CAACQ,IAAI,CAAC,CAACa,SAAS,GAAG,IAAI,EAAEA,SAAS,IAAI,CAAC,EAAE,GAAGvB,OAAO,CAACwB,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,SAASxB,OAAO,EAAEN,aAAa,EAAEqB,UAAU,EAAEK,kBAAkB,EAAEd,QAAQ","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-bluetooth.types.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DEVICE_DISCONNECTED, UNKNOWN_ERROR, WebBleError } from "./web-ble-shapes.js";
|
|
4
|
+
import { canonicalUuid } from "./web-bluetooth-values.js";
|
|
5
|
+
const messageOf = error => error instanceof Error ? error.message : String(error);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A device's GATT server as one queue: browsers allow one GATT operation at a time, so each runs after the previous one
|
|
9
|
+
* settles, and its services are discovered once per connection.
|
|
10
|
+
*/
|
|
11
|
+
class WebGatt {
|
|
12
|
+
characteristics = new Map();
|
|
13
|
+
operations = Promise.resolve();
|
|
14
|
+
constructor(device) {
|
|
15
|
+
this.device = device;
|
|
16
|
+
}
|
|
17
|
+
get connected() {
|
|
18
|
+
return this.device.gatt?.connected ?? false;
|
|
19
|
+
}
|
|
20
|
+
server() {
|
|
21
|
+
if (!this.device.gatt) {
|
|
22
|
+
throw new WebBleError(UNKNOWN_ERROR, `Device ${this.device.id} is unsupported: it has no GATT server`);
|
|
23
|
+
}
|
|
24
|
+
return this.device.gatt;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Runs `operation` after the previous one settles; a failure comes back as a `react-native-ble-plx` error. */
|
|
28
|
+
queued(operation) {
|
|
29
|
+
const result = this.operations.then(operation, operation).catch(error => {
|
|
30
|
+
throw this.errorOf(error);
|
|
31
|
+
});
|
|
32
|
+
this.operations = result.catch(() => undefined);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The discovered services' UUIDs; call it inside a queued operation, so discovery never queues behind itself. */
|
|
37
|
+
async serviceUuids() {
|
|
38
|
+
await this.discover();
|
|
39
|
+
return [...this.characteristics.keys()];
|
|
40
|
+
}
|
|
41
|
+
async characteristicsOf(serviceUuid) {
|
|
42
|
+
await this.discover();
|
|
43
|
+
return [...(this.characteristics.get(canonicalUuid(serviceUuid))?.values() ?? [])];
|
|
44
|
+
}
|
|
45
|
+
async characteristic(serviceUuid, characteristicUuid) {
|
|
46
|
+
await this.discover();
|
|
47
|
+
const characteristic = this.characteristics.get(canonicalUuid(serviceUuid))?.get(canonicalUuid(characteristicUuid));
|
|
48
|
+
if (!characteristic) {
|
|
49
|
+
throw new WebBleError(UNKNOWN_ERROR, `Characteristic ${characteristicUuid} of service ${serviceUuid} was not found on device ${this.device.id}`);
|
|
50
|
+
}
|
|
51
|
+
return characteristic;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Forgets the discovered services, as a new connection must discover them again. */
|
|
55
|
+
forget() {
|
|
56
|
+
this.discovered = undefined;
|
|
57
|
+
}
|
|
58
|
+
errorOf(error) {
|
|
59
|
+
if (error instanceof WebBleError) {
|
|
60
|
+
return error;
|
|
61
|
+
}
|
|
62
|
+
return new WebBleError(this.connected ? UNKNOWN_ERROR : DEVICE_DISCONNECTED, messageOf(error), error);
|
|
63
|
+
}
|
|
64
|
+
discover() {
|
|
65
|
+
this.discovered ??= (async () => {
|
|
66
|
+
this.characteristics.clear();
|
|
67
|
+
for (const service of await this.server().getPrimaryServices()) {
|
|
68
|
+
const characteristics = await service.getCharacteristics().catch(() => []);
|
|
69
|
+
this.characteristics.set(canonicalUuid(service.uuid), new Map(characteristics.map(characteristic => [canonicalUuid(characteristic.uuid), characteristic])));
|
|
70
|
+
}
|
|
71
|
+
})().catch(error => {
|
|
72
|
+
this.discovered = undefined;
|
|
73
|
+
throw error;
|
|
74
|
+
});
|
|
75
|
+
return this.discovered;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export { WebGatt };
|
|
79
|
+
//# sourceMappingURL=web-gatt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEVICE_DISCONNECTED","UNKNOWN_ERROR","WebBleError","canonicalUuid","messageOf","error","Error","message","String","WebGatt","characteristics","Map","operations","Promise","resolve","constructor","device","connected","gatt","server","id","queued","operation","result","then","catch","errorOf","undefined","serviceUuids","discover","keys","characteristicsOf","serviceUuid","get","values","characteristic","characteristicUuid","forget","discovered","clear","service","getPrimaryServices","getCharacteristics","set","uuid","map"],"sourceRoot":"../../../../../../src","sources":["modules/next/bluetooth/web/web-gatt.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Device } from "react-native-ble-plx";
|
|
1
|
+
import type { Device } from "react-native-ble-plx";
|
|
2
2
|
import { Link } from "../link";
|
|
3
3
|
/** Connects (retrying with backoff), discovers services and reads Device Information; aborting `signal` closes the link. */
|
|
4
4
|
declare function openBleLink(device: Device, signal: AbortSignal): Promise<Link>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ble-link.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/ble-plx/ble-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAgB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ble-link.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/ble-plx/ble-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,MAAM,EAAgB,MAAM,sBAAsB,CAAC;AAO3E,OAAO,EAAqB,IAAI,EAAE,MAAM,SAAS,CAAC;AAyJlD,4HAA4H;AAC5H,iBAAe,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB7E;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Device } from "react-native-ble-plx";
|
|
2
|
+
import { Peripheral } from "../transport";
|
|
3
|
+
/** The `react-native-ble-plx` device behind a peripheral that `blePeripheral` made. */
|
|
4
|
+
declare const bleDeviceOf: (peripheral: Peripheral) => Device;
|
|
5
|
+
/** A `react-native-ble-plx` device, or a device with the same API such as a Web Bluetooth one, as a peripheral. */
|
|
6
|
+
declare const blePeripheral: (device: Device) => Peripheral;
|
|
7
|
+
export { bleDeviceOf, blePeripheral };
|
|
8
|
+
//# sourceMappingURL=ble-peripheral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ble-peripheral.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/ble-plx/ble-peripheral.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,uFAAuF;AACvF,QAAA,MAAM,WAAW,GAAI,YAAY,UAAU,KAAG,MAQ7C,CAAC;AAEF,mHAAmH;AACnH,QAAA,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,UAcvC,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { BleManager
|
|
2
|
-
import { BluetoothScanner
|
|
3
|
-
/** The `react-native-ble-plx` device behind a peripheral this adapter reported. */
|
|
4
|
-
declare const bleDeviceOf: (peripheral: Peripheral) => Device;
|
|
5
|
-
/** A `react-native-ble-plx` device as a peripheral. */
|
|
6
|
-
declare const blePeripheral: (device: Device) => Peripheral;
|
|
1
|
+
import { BleManager } from "react-native-ble-plx";
|
|
2
|
+
import { BluetoothScanner } from "../transport";
|
|
7
3
|
/** A scanner over a `react-native-ble-plx` `BleManager`. */
|
|
8
4
|
declare const bleManagerScanner: (bleManager: BleManager) => BluetoothScanner;
|
|
9
|
-
export {
|
|
5
|
+
export { bleManagerScanner };
|
|
10
6
|
//# sourceMappingURL=ble-scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ble-scanner.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/ble-plx/ble-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"ble-scanner.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/ble-plx/ble-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAgB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAY9D,4DAA4D;AAC5D,QAAA,MAAM,iBAAiB,GAAI,YAAY,UAAU,KAAG,gBA6BlD,CAAC;AAEH,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Ovok } from "
|
|
1
|
+
import type { Ovok } from "@ovok/core/next";
|
|
2
2
|
import { ReadingSink } from "../sink";
|
|
3
3
|
/** Saves readings for the signed-in account through the `Ovok` measurements API. */
|
|
4
|
-
declare const ovokReadingSink: (client: Ovok) => ReadingSink;
|
|
4
|
+
declare const ovokReadingSink: (client: Pick<Ovok, "measurements">) => ReadingSink;
|
|
5
5
|
export { ovokReadingSink };
|
|
6
6
|
//# sourceMappingURL=ovok-sink.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ovok-sink.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/react-native/ovok-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ovok-sink.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/react-native/ovok-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAStC,oFAAoF;AACpF,QAAA,MAAM,eAAe,GAAI,QAAQ,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,KAAG,WAoB5D,CAAC;AAEH,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/lib/typescript/commonjs/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Ovok, OvokStorage } from "@ovok/core/next";
|
|
2
|
+
import { DeviceSupport } from "../devices";
|
|
3
|
+
import { ResultPolicy } from "../result-policy";
|
|
4
|
+
import { BluetoothRuntime } from "../runtime";
|
|
5
|
+
import { WebBluetoothScanner } from "./web-bluetooth-scanner";
|
|
6
|
+
/** What `createWebBluetoothRuntime` needs. */
|
|
7
|
+
type CreateWebBluetoothRuntimeOptions = {
|
|
8
|
+
/** Saves the readings. */
|
|
9
|
+
client: Pick<Ovok, "measurements">;
|
|
10
|
+
/** The browser's devices, from `webBluetoothScanner`; the app calls its `chooseDevice` from a tap. */
|
|
11
|
+
scanner: WebBluetoothScanner;
|
|
12
|
+
/** The devices to look for. */
|
|
13
|
+
devices: readonly DeviceSupport[];
|
|
14
|
+
/** Which readings of a connection to keep; defaults to every reading. */
|
|
15
|
+
resultPolicy?: ResultPolicy;
|
|
16
|
+
/** Where the paired device IDs persist; without it pairing lasts until the runtime is disposed. */
|
|
17
|
+
pairedStorage?: OvokStorage;
|
|
18
|
+
};
|
|
19
|
+
/** A `BluetoothRuntime` wired for browsers: Web Bluetooth through `scanner`, saving through `client`. */
|
|
20
|
+
declare const createWebBluetoothRuntime: ({ client, scanner, devices, resultPolicy, pairedStorage, }: CreateWebBluetoothRuntimeOptions) => BluetoothRuntime;
|
|
21
|
+
export { createWebBluetoothRuntime };
|
|
22
|
+
export type { CreateWebBluetoothRuntimeOptions };
|
|
23
|
+
//# sourceMappingURL=create-web-bluetooth-runtime.d.ts.map
|
package/lib/typescript/commonjs/src/modules/next/bluetooth/web/create-web-bluetooth-runtime.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-web-bluetooth-runtime.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/next/bluetooth/web/create-web-bluetooth-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,8CAA8C;AAC9C,KAAK,gCAAgC,GAAG;IAEtC,0BAA0B;IAC1B,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAEnC,sGAAsG;IACtG,OAAO,EAAE,mBAAmB,CAAC;IAE7B,+BAA+B;IAC/B,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAElC,yEAAyE;IACzE,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B,mGAAmG;IACnG,aAAa,CAAC,EAAE,WAAW,CAAC;CAC7B,CAAC;AAEF,yGAAyG;AACzG,QAAA,MAAM,yBAAyB,GAAI,4DAMhC,gCAAgC,KAAG,gBAQlC,CAAC;AAEL,OAAO,EAAE,yBAAyB,EAAE,CAAC;AACrC,YAAY,EAAE,gCAAgC,EAAE,CAAC"}
|