@onekeyfe/hd-transport-web-device 1.2.2-alpha.114 → 1.2.2-alpha.115
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.
|
@@ -205,12 +205,52 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
205
205
|
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
206
206
|
});
|
|
207
207
|
|
|
208
|
-
test('
|
|
208
|
+
test('cancels a pending native connect acquire has not registered yet', async () => {
|
|
209
209
|
const device = { id: 'pending-connect-id', name: 'OneKey Pro 2' };
|
|
210
210
|
const nobleBle = createNobleBle(device);
|
|
211
|
+
// Never calls back: the field case the Core acquire deadline has to break.
|
|
212
|
+
nobleBle.connect.mockImplementation(
|
|
213
|
+
() =>
|
|
214
|
+
new Promise<void>(() => {
|
|
215
|
+
// intentionally never settles
|
|
216
|
+
})
|
|
217
|
+
);
|
|
218
|
+
const bleTransport = configureTransport(nobleBle) as any;
|
|
219
|
+
|
|
220
|
+
const pendingAcquire = bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V2' });
|
|
221
|
+
pendingAcquire.catch(() => undefined);
|
|
222
|
+
await new Promise(resolve => {
|
|
223
|
+
setTimeout(resolve, 10);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// What the deadline / user abort calls. connectedDevices is still empty
|
|
227
|
+
// here, so this only works because the acquire is tracked as in flight.
|
|
228
|
+
await bleTransport.disconnect(device.id);
|
|
229
|
+
|
|
230
|
+
expect(nobleBle.unsubscribe).not.toHaveBeenCalled();
|
|
231
|
+
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('leaves a kept-alive link up when a released device is disconnected', async () => {
|
|
235
|
+
const device = { id: 'kept-alive-id', name: 'OneKey Pro 2' };
|
|
236
|
+
const nobleBle = createNobleBle(device);
|
|
237
|
+
const bleTransport = configureTransport(nobleBle) as any;
|
|
238
|
+
|
|
239
|
+
// No acquire in flight and nothing in connectedDevices: the link was
|
|
240
|
+
// released logically and belongs to the main-process keep-alive timer.
|
|
241
|
+
// The routine post-call cancel must not cost the next call a cold connect.
|
|
242
|
+
await bleTransport.disconnect(device.id);
|
|
243
|
+
|
|
244
|
+
expect(nobleBle.disconnect).not.toHaveBeenCalled();
|
|
245
|
+
expect(nobleBle.unsubscribe).not.toHaveBeenCalled();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test('forceNative disconnects a device the renderer no longer tracks', async () => {
|
|
249
|
+
const device = { id: 'presumed-dead-id', name: 'OneKey Pro 2' };
|
|
250
|
+
const nobleBle = createNobleBle(device);
|
|
211
251
|
const bleTransport = configureTransport(nobleBle) as any;
|
|
212
252
|
|
|
213
|
-
await bleTransport.releaseNative(device.id);
|
|
253
|
+
await bleTransport.releaseNative(device.id, { forceNative: true });
|
|
214
254
|
|
|
215
255
|
expect(nobleBle.unsubscribe).not.toHaveBeenCalled();
|
|
216
256
|
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,iCAAiC,CAAC;AAC5F,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EAEZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAIvC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAiDF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,SAAS,CAA0D;IAE3E,OAAO,CAAC,WAAW,CAA0D;IAE7E,OAAO,CAAC,6BAA6B,CAAqB;IAE1D,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,CAAQ;IAExD,OAAO,CAAC,kBAAkB,CAAuB;IAEjD,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,OAAO,CAAC,gBAAgB,CAA0B;IAElD,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,UAAU,CAAkC;IAEpD,OAAO,CAAC,sBAAsB,CAAkC;IAEhE,OAAO,CAAC,SAAS,CAAsE;IAEvF,OAAO,CAAC,YAAY,CAAoD;IAExE,OAAO,CAAC,aAAa,CAAwC;IAE7D,OAAO,CAAC,eAAe,CAAgD;IAEvE,OAAO,CAAC,eAAe,CAmBpB;IAGH,OAAO,CAAC,oBAAoB,CAAS;IAErC,OAAO,CAAC,oBAAoB,CAAsC;IAElE,OAAO,CAAC,WAAW,CAAsC;IAUzD,OAAO,CAAC,qBAAqB,CAAC,CAAa;IAE3C,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,uBAAuB;IAsC/B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,kBAAkB;IAiC1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAqBxC,OAAO,CAAC,wBAAwB;IAgChC,SAAS,CAAC,UAAU,EAAE,GAAG;IAKzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAgB7B,MAAM;IAIN,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAiBxC,OAAO,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -216,6 +216,14 @@ declare class ElectronBleTransport {
|
|
|
216
216
|
Log?: any;
|
|
217
217
|
emitter?: EventEmitter;
|
|
218
218
|
private connectedDevices;
|
|
219
|
+
/**
|
|
220
|
+
* Devices whose acquire() is still in flight.
|
|
221
|
+
*
|
|
222
|
+
* A native connect that never calls back has not reached `connectedDevices`
|
|
223
|
+
* yet, so this is the only record that the renderer is still trying to own
|
|
224
|
+
* the link; `releaseNative()` needs it to cancel that pending connect.
|
|
225
|
+
*/
|
|
226
|
+
private acquiringDevices;
|
|
219
227
|
private deviceProtocol;
|
|
220
228
|
private deviceProtocolHints;
|
|
221
229
|
private deviceMtus;
|
package/dist/index.js
CHANGED
|
@@ -850,6 +850,7 @@ class ElectronBleTransport {
|
|
|
850
850
|
this.runPromise = null;
|
|
851
851
|
this.runPromiseDeviceId = null;
|
|
852
852
|
this.connectedDevices = new Set();
|
|
853
|
+
this.acquiringDevices = new Set();
|
|
853
854
|
this.deviceProtocol = new Map();
|
|
854
855
|
this.deviceProtocolHints = new Map();
|
|
855
856
|
this.deviceMtus = new Map();
|
|
@@ -875,7 +876,7 @@ class ElectronBleTransport {
|
|
|
875
876
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
876
877
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug('[Electron BLE] Protocol V2 link invalidated:', uuid, reason);
|
|
877
878
|
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
878
|
-
yield this.releaseNative(uuid);
|
|
879
|
+
yield this.releaseNative(uuid, { forceNative: true });
|
|
879
880
|
}
|
|
880
881
|
}),
|
|
881
882
|
});
|
|
@@ -1034,6 +1035,7 @@ class ElectronBleTransport {
|
|
|
1034
1035
|
this.runPromise = null;
|
|
1035
1036
|
this.runPromiseDeviceId = null;
|
|
1036
1037
|
}
|
|
1038
|
+
this.acquiringDevices.add(uuid);
|
|
1037
1039
|
try {
|
|
1038
1040
|
if (!((_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle)) {
|
|
1039
1041
|
throw new Error('Noble BLE API not available');
|
|
@@ -1100,6 +1102,9 @@ class ElectronBleTransport {
|
|
|
1100
1102
|
this.cleanupDeviceState(uuid);
|
|
1101
1103
|
this.handleBluetoothError(error);
|
|
1102
1104
|
}
|
|
1105
|
+
finally {
|
|
1106
|
+
this.acquiringDevices.delete(uuid);
|
|
1107
|
+
}
|
|
1103
1108
|
});
|
|
1104
1109
|
}
|
|
1105
1110
|
release(id, _onclose, keepSession) {
|
|
@@ -1120,12 +1125,14 @@ class ElectronBleTransport {
|
|
|
1120
1125
|
return this.releaseNative(id);
|
|
1121
1126
|
});
|
|
1122
1127
|
}
|
|
1123
|
-
releaseNative(id) {
|
|
1128
|
+
releaseNative(id, options) {
|
|
1124
1129
|
var _a, _b;
|
|
1125
1130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1131
|
+
const rendererOwnsLink = this.connectedDevices.has(id) || this.acquiringDevices.has(id);
|
|
1132
|
+
const shouldDisconnect = (options === null || options === void 0 ? void 0 : options.forceNative) === true || rendererOwnsLink;
|
|
1126
1133
|
try {
|
|
1127
1134
|
const nobleBle = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle;
|
|
1128
|
-
if (nobleBle) {
|
|
1135
|
+
if (nobleBle && shouldDisconnect) {
|
|
1129
1136
|
if (this.connectedDevices.has(id)) {
|
|
1130
1137
|
yield invokeNobleBle(nobleBle.unsubscribe(id)).catch(error => {
|
|
1131
1138
|
var _a;
|
|
@@ -1564,7 +1571,7 @@ class ElectronBleTransport {
|
|
|
1564
1571
|
this.notificationCleanups.delete(uuid);
|
|
1565
1572
|
this.notificationTokens.delete(uuid);
|
|
1566
1573
|
if (!isProbeTimeout) {
|
|
1567
|
-
yield this.releaseNative(uuid);
|
|
1574
|
+
yield this.releaseNative(uuid, { forceNative: true });
|
|
1568
1575
|
}
|
|
1569
1576
|
}
|
|
1570
1577
|
throw this.normalizeBluetoothError(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.115",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.2-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.115",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.115"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.115",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "a115ca6998586c05c22996f278091778fd5471f1"
|
|
33
33
|
}
|
|
@@ -117,6 +117,15 @@ export default class ElectronBleTransport {
|
|
|
117
117
|
|
|
118
118
|
private connectedDevices: Set<string> = new Set();
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Devices whose acquire() is still in flight.
|
|
122
|
+
*
|
|
123
|
+
* A native connect that never calls back has not reached `connectedDevices`
|
|
124
|
+
* yet, so this is the only record that the renderer is still trying to own
|
|
125
|
+
* the link; `releaseNative()` needs it to cancel that pending connect.
|
|
126
|
+
*/
|
|
127
|
+
private acquiringDevices: Set<string> = new Set();
|
|
128
|
+
|
|
120
129
|
private deviceProtocol: Map<string, ProtocolType> = new Map();
|
|
121
130
|
|
|
122
131
|
private deviceProtocolHints: Map<string, ProtocolType> = new Map();
|
|
@@ -149,7 +158,7 @@ export default class ElectronBleTransport {
|
|
|
149
158
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
150
159
|
this.Log?.debug('[Electron BLE] Protocol V2 link invalidated:', uuid, reason);
|
|
151
160
|
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
152
|
-
await this.releaseNative(uuid);
|
|
161
|
+
await this.releaseNative(uuid, { forceNative: true });
|
|
153
162
|
}
|
|
154
163
|
},
|
|
155
164
|
});
|
|
@@ -363,6 +372,7 @@ export default class ElectronBleTransport {
|
|
|
363
372
|
this.runPromiseDeviceId = null;
|
|
364
373
|
}
|
|
365
374
|
|
|
375
|
+
this.acquiringDevices.add(uuid);
|
|
366
376
|
try {
|
|
367
377
|
if (!window.desktopApi?.nobleBle) {
|
|
368
378
|
throw new Error('Noble BLE API not available');
|
|
@@ -434,6 +444,8 @@ export default class ElectronBleTransport {
|
|
|
434
444
|
}
|
|
435
445
|
this.cleanupDeviceState(uuid);
|
|
436
446
|
this.handleBluetoothError(error);
|
|
447
|
+
} finally {
|
|
448
|
+
this.acquiringDevices.delete(uuid);
|
|
437
449
|
}
|
|
438
450
|
}
|
|
439
451
|
|
|
@@ -454,10 +466,23 @@ export default class ElectronBleTransport {
|
|
|
454
466
|
}
|
|
455
467
|
|
|
456
468
|
// Hard teardown, error paths only: a link presumed dead must not be reused.
|
|
457
|
-
|
|
469
|
+
//
|
|
470
|
+
// The native disconnect is sent while the renderer still owns the link, or is
|
|
471
|
+
// still trying to get it: a stuck acquire has not reached `connectedDevices`
|
|
472
|
+
// yet, and its pending native connect can only be cancelled from here, so the
|
|
473
|
+
// Core acquire deadline would otherwise be unable to terminate it.
|
|
474
|
+
//
|
|
475
|
+
// It is NOT sent for a device the renderer has already released logically.
|
|
476
|
+
// That link belongs to the main-process keep-alive timer, and dropping it on
|
|
477
|
+
// the routine post-call `cancel()` (Device.interruptionFromUser, no acquire
|
|
478
|
+
// held, empty request queue) costs a full cold reconnect on the very next
|
|
479
|
+
// operation — measured 2.93s on Pro and 17-26s on Pro 2.
|
|
480
|
+
private async releaseNative(id: string, options?: { forceNative?: boolean }) {
|
|
481
|
+
const rendererOwnsLink = this.connectedDevices.has(id) || this.acquiringDevices.has(id);
|
|
482
|
+
const shouldDisconnect = options?.forceNative === true || rendererOwnsLink;
|
|
458
483
|
try {
|
|
459
484
|
const nobleBle = window.desktopApi?.nobleBle;
|
|
460
|
-
if (nobleBle) {
|
|
485
|
+
if (nobleBle && shouldDisconnect) {
|
|
461
486
|
if (this.connectedDevices.has(id)) {
|
|
462
487
|
await invokeNobleBle(nobleBle.unsubscribe(id)).catch(error => {
|
|
463
488
|
this.Log?.debug('[Electron BLE] release unsubscribe failed:', error);
|
|
@@ -970,7 +995,7 @@ export default class ElectronBleTransport {
|
|
|
970
995
|
this.notificationCleanups.delete(uuid);
|
|
971
996
|
this.notificationTokens.delete(uuid);
|
|
972
997
|
if (!isProbeTimeout) {
|
|
973
|
-
await this.releaseNative(uuid);
|
|
998
|
+
await this.releaseNative(uuid, { forceNative: true });
|
|
974
999
|
}
|
|
975
1000
|
}
|
|
976
1001
|
throw this.normalizeBluetoothError(e);
|