@alexgyver/ble 1.0.8 → 1.0.10
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/.github/workflows/pio-publish.yml +32 -0
- package/.github/workflows/tg-send.yml +35 -0
- package/README.md +76 -8
- package/README_EN.md +81 -0
- package/ble.js +74 -16
- package/ble.min.js +1 -1
- package/package.json +6 -6
- package/test/script.js +2 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
name: Publish to PlatformIO Registry
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout release tag
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
ref: ${{ github.event.release.tag_name }}
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.x"
|
|
22
|
+
|
|
23
|
+
- name: Install PlatformIO
|
|
24
|
+
run: pip install -U platformio
|
|
25
|
+
|
|
26
|
+
- name: Check package
|
|
27
|
+
run: pio pkg pack
|
|
28
|
+
|
|
29
|
+
- name: Publish to PlatformIO Registry
|
|
30
|
+
env:
|
|
31
|
+
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
|
|
32
|
+
run: pio pkg publish --owner gyverlibs --non-interactive
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
name: Telegram Message
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
name: Send Message
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Check if major or minor release
|
|
12
|
+
id: semver
|
|
13
|
+
shell: bash
|
|
14
|
+
run: |
|
|
15
|
+
TAG="${{ github.event.release.tag_name }}"
|
|
16
|
+
VERSION="${TAG#v}"
|
|
17
|
+
PATCH="$(echo "$VERSION" | cut -d. -f3)"
|
|
18
|
+
|
|
19
|
+
if [[ "$PATCH" == "0" ]]; then
|
|
20
|
+
echo "should_send=true" >> "$GITHUB_OUTPUT"
|
|
21
|
+
else
|
|
22
|
+
echo "should_send=false" >> "$GITHUB_OUTPUT"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
- name: send telegram message on release
|
|
26
|
+
if: steps.semver.outputs.should_send == 'true'
|
|
27
|
+
uses: appleboy/telegram-action@master
|
|
28
|
+
with:
|
|
29
|
+
to: ${{ secrets.TELEGRAM_TO }}
|
|
30
|
+
token: ${{ secrets.TELEGRAM_TOKEN }}
|
|
31
|
+
disable_web_page_preview: true
|
|
32
|
+
message: |
|
|
33
|
+
${{ github.event.repository.name }} ${{ github.event.release.tag_name }}
|
|
34
|
+
${{ github.event.release.body }}
|
|
35
|
+
https://github.com/${{ github.repository }}
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# BLE.js
|
|
2
2
|
Обёртка на Web Bluetooth API
|
|
3
3
|
- Автоматическое переподключение
|
|
4
|
-
-
|
|
5
|
-
-
|
|
4
|
+
- Последовательная отправка без пересечения записей
|
|
5
|
+
- Настраиваемое дробление больших отправок
|
|
6
|
+
- Отдельная атомарная отправка одного BLE frame
|
|
6
7
|
|
|
7
8
|
[demo](https://gyverlibs.github.io/BLE.js/test/)
|
|
8
9
|
|
|
@@ -14,12 +15,14 @@
|
|
|
14
15
|
```js
|
|
15
16
|
constructor(params = {});
|
|
16
17
|
config(params = {});
|
|
17
|
-
// eol: /\r?\n/
|
|
18
18
|
// serviceUUID: '0000ffe0-0000-1000-8000-00805f9b34fb'
|
|
19
|
-
//
|
|
19
|
+
// rxUUID: '0000ffe1-0000-1000-8000-00805f9b34fb'
|
|
20
|
+
// txUUID: '0000ffe2-0000-1000-8000-00805f9b34fb'
|
|
20
21
|
// auto_open: false
|
|
21
|
-
// max_tx: 20
|
|
22
22
|
// reconnect: 1000
|
|
23
|
+
// chunkSize: 500
|
|
24
|
+
// chunkDelay: 0
|
|
25
|
+
// withResponse: false
|
|
23
26
|
|
|
24
27
|
onbin(b);
|
|
25
28
|
ontext(t);
|
|
@@ -34,11 +37,76 @@ static supported();
|
|
|
34
37
|
opened();
|
|
35
38
|
selected();
|
|
36
39
|
getName();
|
|
40
|
+
getRxProperties();
|
|
41
|
+
getTxProperties();
|
|
42
|
+
canWriteWithResponse();
|
|
43
|
+
canWriteWithoutResponse();
|
|
44
|
+
canIndicate();
|
|
37
45
|
|
|
38
46
|
select();
|
|
39
47
|
open();
|
|
40
48
|
close();
|
|
41
49
|
|
|
42
|
-
sendBin(data);
|
|
43
|
-
sendText(text);
|
|
44
|
-
```
|
|
50
|
+
sendBin(data, options = {});
|
|
51
|
+
sendText(text, options = {});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Все методы отправки возвращают `Promise<boolean>`.
|
|
55
|
+
|
|
56
|
+
## Дробление отправки
|
|
57
|
+
|
|
58
|
+
`sendBin()` делит данные на несколько BLE characteristic writes по `chunkSize`. Задержка между записями задаётся через `chunkDelay`:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
const ble = new BLEJS({
|
|
62
|
+
chunkSize: 100,
|
|
63
|
+
chunkDelay: 5,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await ble.sendBin(data);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`chunkSize <= 0` отключает дробление и выполняет одну characteristic write:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
await ble.sendBin(data, { chunkSize: 0 });
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Для протоколов, где одна BLE write является одним транспортным frame, отключите дробление для конкретной отправки:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const ok = await ble.sendBin(frame, { chunkSize: 0 });
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Опция `withResponse` едина для всех методов отправки:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
await ble.sendBin(data, { withResponse: true });
|
|
85
|
+
await ble.sendText('hello', { withResponse: true });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Для атомарного фрейма с GATT response обе опции можно совместить:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
await ble.sendBin(frame, { withResponse: true, chunkSize: 0 });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
При `withResponse: true` используется `writeValueWithResponse()`. Promise отправки завершается после ответа GATT-сервера, поэтому режим подходит для последовательной передачи с транспортным backpressure. Значение по умолчанию задаётся одноимённой настройкой конструктора.
|
|
95
|
+
|
|
96
|
+
Для обратной совместимости второй boolean-аргумент продолжает трактоваться как старый `fast`: `true` выбирает Write without Response, `false` — Write with Response. Третий аргумент старой формы задаёт `chunkSize`:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
await ble.sendBin(data, false, 100);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Перед использованием можно проверить свойства найденных характеристик:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
if (!ble.canWriteWithResponse()) throw new Error('Write with Response is unavailable');
|
|
106
|
+
if (!ble.canWriteWithoutResponse()) throw new Error('Write without Response is unavailable');
|
|
107
|
+
if (!ble.canIndicate()) throw new Error('Indications are unavailable');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`getRxProperties()` и `getTxProperties()` возвращают объект `BluetoothCharacteristicProperties` либо `null`, пока соединение не открыто. `startNotifications()` включает доступный режим, но не позволяет JavaScript принудительно выбрать Indication вместо Notification. Если протоколу нужны именно Indication, TX characteristic на устройстве следует объявлять как indicate-only.
|
|
111
|
+
|
|
112
|
+
Проверка поддержки выбранного способа записи выполняется внутри `sendBin()`. При несовместимой RX characteristic метод вызывает `onerror` и возвращает `false`.
|
package/README_EN.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
This is an automatic translation and may be incorrect in some places. See the source README and examples for authoritative information.
|
|
2
|
+
|
|
3
|
+
# BLE.js
|
|
4
|
+
Wrapper on Web Bluetooth API
|
|
5
|
+
- Automatic reconnection
|
|
6
|
+
- Sequential writes without overlapping operations
|
|
7
|
+
- Configurable splitting of large writes
|
|
8
|
+
- Atomic sending of a single BLE frame
|
|
9
|
+
|
|
10
|
+
[demo](https://gyverlibs.github.io/BLE.js/test/)
|
|
11
|
+
|
|
12
|
+
> **Browser**: https://gyverlibs.github.io/BLE.js/BLE.min.js
|
|
13
|
+
|
|
14
|
+
> **Node**: npm i @alexgyver/ble
|
|
15
|
+
|
|
16
|
+
## Doc.
|
|
17
|
+
```js
|
|
18
|
+
constructor(params = {});
|
|
19
|
+
config(params = {});
|
|
20
|
+
// serviceUUID: '0000ffe0-0000-1000-8000-00805f9b34fb'
|
|
21
|
+
// rxUUID: '0000ffe1-0000-1000-8000-00805f9b34fb'
|
|
22
|
+
// txUUID: '0000ffe2-0000-1000-8000-00805f9b34fb'
|
|
23
|
+
// auto_open: false
|
|
24
|
+
// reconnect: 1000
|
|
25
|
+
// chunkSize: 500
|
|
26
|
+
// chunkDelay: 0
|
|
27
|
+
// withResponse: false
|
|
28
|
+
|
|
29
|
+
onbin(b);
|
|
30
|
+
ontext(t);
|
|
31
|
+
|
|
32
|
+
onopen():
|
|
33
|
+
onclose():
|
|
34
|
+
onchange(s):
|
|
35
|
+
onselect(name);
|
|
36
|
+
onerror(e);
|
|
37
|
+
|
|
38
|
+
static supported();
|
|
39
|
+
opened();
|
|
40
|
+
selected();
|
|
41
|
+
getName();
|
|
42
|
+
getRxProperties();
|
|
43
|
+
getTxProperties();
|
|
44
|
+
canWriteWithResponse();
|
|
45
|
+
canWriteWithoutResponse();
|
|
46
|
+
canIndicate();
|
|
47
|
+
|
|
48
|
+
select();
|
|
49
|
+
open();
|
|
50
|
+
close();
|
|
51
|
+
|
|
52
|
+
sendBin(data, options = {});
|
|
53
|
+
sendText(text, options = {});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
All send methods return `Promise<boolean>`.
|
|
57
|
+
|
|
58
|
+
The `withResponse` option is shared by all send methods:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
await ble.sendBin(data, { withResponse: true });
|
|
62
|
+
await ble.sendText('hello', { withResponse: true });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Set `chunkSize: 0` when one protocol frame must map to exactly one characteristic write:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
await ble.sendBin(frame, { withResponse: true, chunkSize: 0 });
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
With `withResponse: true`, the library uses `writeValueWithResponse()` and validates that the connected RX characteristic supports it. The send Promise resolves after the GATT response, providing transport-level backpressure. The constructor option with the same name selects the default mode.
|
|
72
|
+
|
|
73
|
+
The legacy boolean argument remains supported: `true` means Write without Response and `false` means Write with Response. The legacy third argument still sets `chunkSize`:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
await ble.sendBin(data, false, 100);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`canWriteWithResponse()`, `canWriteWithoutResponse()`, and `canIndicate()` expose the capabilities of the connected RX and TX characteristics. `getRxProperties()` and `getTxProperties()` return their complete `BluetoothCharacteristicProperties`, or `null` while disconnected. Every send validates the selected write mode and returns `false` through the usual error path when it is unsupported.
|
|
80
|
+
|
|
81
|
+
Web Bluetooth does not let JavaScript explicitly select Indication instead of Notification. A protocol that requires Indication should expose an indicate-only TX characteristic on the peripheral.
|
package/ble.js
CHANGED
|
@@ -25,6 +25,7 @@ export default class BLEJS {
|
|
|
25
25
|
reconnect: 1000,
|
|
26
26
|
chunkSize: 500,
|
|
27
27
|
chunkDelay: 0,
|
|
28
|
+
withResponse: false,
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
this.cfg = { ...def, ...params };
|
|
@@ -50,6 +51,26 @@ export default class BLEJS {
|
|
|
50
51
|
return this._device ? this._device.name : 'None';
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
getRxProperties() {
|
|
55
|
+
return this._rx?.properties ?? null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getTxProperties() {
|
|
59
|
+
return this._tx?.properties ?? null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
canWriteWithResponse() {
|
|
63
|
+
return !!this._rx?.properties?.write;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
canWriteWithoutResponse() {
|
|
67
|
+
return !!this._rx?.properties?.writeWithoutResponse;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
canIndicate() {
|
|
71
|
+
return !!this._tx?.properties?.indicate;
|
|
72
|
+
}
|
|
73
|
+
|
|
53
74
|
async select() {
|
|
54
75
|
try {
|
|
55
76
|
await this.close();
|
|
@@ -162,37 +183,74 @@ export default class BLEJS {
|
|
|
162
183
|
}
|
|
163
184
|
}
|
|
164
185
|
|
|
165
|
-
async sendText(text,
|
|
166
|
-
|
|
186
|
+
async sendText(text, options) {
|
|
187
|
+
return this.sendBin((new TextEncoder()).encode(text), options);
|
|
167
188
|
}
|
|
168
189
|
|
|
169
|
-
async sendBin(data,
|
|
190
|
+
async sendBin(data, options, legacyChunkSize) {
|
|
170
191
|
if (!this.opened() || !this._rx) return false;
|
|
171
192
|
|
|
172
|
-
|
|
193
|
+
options = this._sendOptions(options, legacyChunkSize);
|
|
194
|
+
|
|
195
|
+
const result = await this._sender.runNothrow(async () => {
|
|
173
196
|
if (!this.opened() || !this._rx) return false;
|
|
174
197
|
|
|
175
|
-
const chunkSize = this.cfg.chunkSize;
|
|
176
198
|
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
199
|
+
if (!bytes.length) return true;
|
|
177
200
|
|
|
178
|
-
|
|
179
|
-
if (!this.
|
|
201
|
+
if (options.withResponse) {
|
|
202
|
+
if (!this.canWriteWithResponse()) {
|
|
203
|
+
this._error('RX characteristic does not support Write with Response');
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
} else if (!this.canWriteWithoutResponse()) {
|
|
207
|
+
this._error('RX characteristic does not support Write without Response');
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
180
210
|
|
|
181
|
-
|
|
211
|
+
let size = Number(options.chunkSize);
|
|
212
|
+
if (!Number.isFinite(size) || size <= 0) size = bytes.length;
|
|
213
|
+
else size = Math.max(1, Math.floor(size));
|
|
182
214
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
await this._rx.writeValueWithResponse(chunk);
|
|
187
|
-
}
|
|
215
|
+
try {
|
|
216
|
+
for (let i = 0; i < bytes.length; i += size) {
|
|
217
|
+
if (!this.opened() || !this._rx) return false;
|
|
188
218
|
|
|
189
|
-
|
|
190
|
-
|
|
219
|
+
const chunk = bytes.subarray(i, i + size);
|
|
220
|
+
|
|
221
|
+
if (options.withResponse) {
|
|
222
|
+
await this._rx.writeValueWithResponse(chunk);
|
|
223
|
+
} else {
|
|
224
|
+
await this._rx.writeValueWithoutResponse(chunk);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (i + size < bytes.length && this.cfg.chunkDelay > 0) {
|
|
228
|
+
await sleep(this.cfg.chunkDelay);
|
|
229
|
+
}
|
|
191
230
|
}
|
|
231
|
+
} catch (e) {
|
|
232
|
+
this._error(e);
|
|
233
|
+
return false;
|
|
192
234
|
}
|
|
193
235
|
|
|
194
236
|
return true;
|
|
195
237
|
});
|
|
238
|
+
|
|
239
|
+
return result === true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
_sendOptions(options, legacyChunkSize) {
|
|
243
|
+
if (typeof options === 'boolean') {
|
|
244
|
+
return {
|
|
245
|
+
withResponse: !options,
|
|
246
|
+
chunkSize: legacyChunkSize ?? this.cfg.chunkSize,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
withResponse: options?.withResponse ?? this.cfg.withResponse,
|
|
252
|
+
chunkSize: options?.chunkSize ?? this.cfg.chunkSize,
|
|
253
|
+
};
|
|
196
254
|
}
|
|
197
255
|
|
|
198
256
|
_state = BLEJS.State.Closed;
|
|
@@ -271,4 +329,4 @@ export default class BLEJS {
|
|
|
271
329
|
break;
|
|
272
330
|
}
|
|
273
331
|
}
|
|
274
|
-
}
|
|
332
|
+
}
|
package/ble.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const e=e=>new Promise(t=>setTimeout(t,e));class t{constructor(){this._session=0,this.reset()}run(e){const t=this._session,s=this._queue.then(()=>{if(t!==this._session)throw new Error("Queue empty");return e()});return this._queue=s.catch(()=>{}),s}runNothrow(e){return this.run(e).catch(()=>null)}reset(){this._session++,this._queue=Promise.resolve()}}class s{static State={Closed:"closed",Opening:"opening",Open:"open",Closing:"closing"};ontext=null;onbin(e){}onopen(){}onclose(){}onchange(e){}onselect(e){}onerror(e){}constructor(e={}){this.cfg={serviceUUID:"0000ffe0-0000-1000-8000-00805f9b34fb",rxUUID:"0000ffe1-0000-1000-8000-00805f9b34fb",txUUID:"0000ffe2-0000-1000-8000-00805f9b34fb",auto_open:!1,reconnect:1e3,chunkSize:500,chunkDelay:0,withResponse:!1,...e}}config(e={}){this.cfg={...this.cfg,...e}}static supported(){return"bluetooth"in navigator}opened(){return this._state===s.State.Open}selected(){return!!this._device}getName(){return this._device?this._device.name:"None"}getRxProperties(){return this._rx?.properties??null}getTxProperties(){return this._tx?.properties??null}canWriteWithResponse(){return!!this._rx?.properties?.write}canWriteWithoutResponse(){return!!this._rx?.properties?.writeWithoutResponse}canIndicate(){return!!this._tx?.properties?.indicate}async select(){try{await this.close(),this._device&&this._device.removeEventListener("gattserverdisconnected",this._disconnect_h),this._device=await navigator.bluetooth.requestDevice({filters:[{services:[this.cfg.serviceUUID]}],optionalServices:[this.cfg.serviceUUID]}),this._device.addEventListener("gattserverdisconnected",this._disconnect_h)}catch(e){this._error(e),this._device=null}return this.onselect(this.getName()),this.cfg.auto_open&&this.open(),this.selected()}async open(){return this._lifecycle.runNothrow(async()=>this._device?!!this.opened()||(this.cfg.reconnect&&(this.retry=!0),await this._open(),this.opened()):(this._error("No device"),!1))}async _open(){if(this._state===s.State.Closed){this._change(s.State.Opening);try{const e=await this._device.gatt.connect(),t=await e.getPrimaryService(this.cfg.serviceUUID);this._rx=await t.getCharacteristic(this.cfg.rxUUID),this._tx=await t.getCharacteristic(this.cfg.txUUID),await this._tx.startNotifications(),this._tx.addEventListener("characteristicvaluechanged",this._data_h),this._sender.reset(),this._change(s.State.Open)}catch(t){this._error(t),this._sender.reset(),this._change(s.State.Closed),this.retry&&e(this.cfg.reconnect).then(()=>{this._lifecycle.runNothrow(()=>this._open())})}}}async close(){return this._lifecycle.runNothrow(async()=>(this.retry=!1,this._sender.reset(),this._state!==s.State.Closed&&await this._close(),!0))}async _close(){if(this._state!==s.State.Closed){this._change(s.State.Closing);try{this._device?.gatt?.connected?this._device.gatt.disconnect():await this._disconnect()}catch(e){this._error(e),await this._disconnect()}}}async sendText(e,t){return this.sendBin((new TextEncoder).encode(e),t)}async sendBin(t,s,i){return!(!this.opened()||!this._rx)&&(s=this._sendOptions(s,i),!0===await this._sender.runNothrow(async()=>{if(!this.opened()||!this._rx)return!1;const i=t instanceof Uint8Array?t:new Uint8Array(t);if(!i.length)return!0;if(s.withResponse){if(!this.canWriteWithResponse())return this._error("RX characteristic does not support Write with Response"),!1}else if(!this.canWriteWithoutResponse())return this._error("RX characteristic does not support Write without Response"),!1;let n=Number(s.chunkSize);n=!Number.isFinite(n)||n<=0?i.length:Math.max(1,Math.floor(n));try{for(let t=0;t<i.length;t+=n){if(!this.opened()||!this._rx)return!1;const r=i.subarray(t,t+n);s.withResponse?await this._rx.writeValueWithResponse(r):await this._rx.writeValueWithoutResponse(r),t+n<i.length&&this.cfg.chunkDelay>0&&await e(this.cfg.chunkDelay)}}catch(e){return this._error(e),!1}return!0}))}_sendOptions(e,t){return"boolean"==typeof e?{withResponse:!e,chunkSize:t??this.cfg.chunkSize}:{withResponse:e?.withResponse??this.cfg.withResponse,chunkSize:e?.chunkSize??this.cfg.chunkSize}}_state=s.State.Closed;_device=null;_rx=null;_tx=null;retry=!1;_sender=new t;_lifecycle=new t;async _disconnect(t){if(this._sender.reset(),this._tx)try{this._tx.removeEventListener("characteristicvaluechanged",this._data_h)}catch(t){}this._rx=null,this._tx=null,this._change(s.State.Closed),this.retry&&e(this.cfg.reconnect).then(()=>{this._lifecycle.runNothrow(()=>this._open())}),await e(50)}_disconnect_h=this._disconnect.bind(this);_data(e){try{const t=e.target.value,s=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);this.onbin(s),this.ontext&&this.ontext((new TextDecoder).decode(s))}catch(e){this._error(e)}}_data_h=this._data.bind(this);_error(e){this.onerror("[BLE] "+e)}_change(e){if(this._state!==e)switch(this._state=e,this.onchange(e),e){case s.State.Open:this.onopen();break;case s.State.Closed:this.onclose()}}}export{s as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexgyver/ble",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Web BLE Serial",
|
|
5
5
|
"main": "./ble.js",
|
|
6
6
|
"module": "./ble.js",
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
"url": "git+https://github.com/GyverLibs/ble.js.git"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"css-loader": "^7.1.
|
|
17
|
+
"css-loader": "^7.1.5",
|
|
18
18
|
"style-loader": "^4.0.0",
|
|
19
|
-
"webpack": "^5.
|
|
20
|
-
"webpack-cli": "^7.
|
|
21
|
-
"webpack-dev-server": "^
|
|
19
|
+
"webpack": "^5.110.3",
|
|
20
|
+
"webpack-cli": "^7.2.3",
|
|
21
|
+
"webpack-dev-server": "^6.0.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@alexgyver/utils": "^1.2.
|
|
24
|
+
"@alexgyver/utils": "^1.2.18"
|
|
25
25
|
},
|
|
26
26
|
"author": "AlexGyver <alex@alexgyver.ru>",
|
|
27
27
|
"license": "MIT"
|
package/test/script.js
CHANGED