@onekeyfe/hd-transport-web-device 1.2.0-alpha.134 → 1.2.0-alpha.136
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/__tests__/webusb-protocol-cache.test.ts +25 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +18 -6
- package/dist/webusb.d.ts +1 -0
- package/dist/webusb.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/webusb.ts +27 -7
|
@@ -16,12 +16,17 @@ const schema = {
|
|
|
16
16
|
},
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
function buildAcquirableTransport() {
|
|
19
|
+
function buildAcquirableTransport(path = 'pro-webusb') {
|
|
20
20
|
const webusb = new WebUsbTransport() as any;
|
|
21
21
|
webusb.Log = { debug: jest.fn() };
|
|
22
22
|
webusb.rotateProtocolV2UsbGeneration = jest.fn().mockResolvedValue(undefined);
|
|
23
23
|
webusb.closeOpenDevice = jest.fn().mockResolvedValue(undefined);
|
|
24
24
|
webusb.connect = jest.fn().mockResolvedValue(undefined);
|
|
25
|
+
// Simulate a device that stayed connected since the probe: same USBDevice
|
|
26
|
+
// object present in the device list and recorded as the probed object.
|
|
27
|
+
const deviceObject = { serialNumber: path } as unknown as USBDevice;
|
|
28
|
+
webusb.deviceList = [{ path, device: deviceObject, commType: 'webusb' }];
|
|
29
|
+
webusb.probedDeviceObjects.set(path, deviceObject);
|
|
25
30
|
return webusb;
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -64,6 +69,25 @@ describe('WebUsbTransport protocol probe cache', () => {
|
|
|
64
69
|
expect(webusb.detectProtocol).toHaveBeenCalledWith(path, 'V1', undefined);
|
|
65
70
|
});
|
|
66
71
|
|
|
72
|
+
test('acquire re-probes when the USBDevice object identity changed since the probe', async () => {
|
|
73
|
+
const webusb = buildAcquirableTransport();
|
|
74
|
+
const path = 'pro-webusb';
|
|
75
|
+
webusb.deviceProtocol.set(path, 'V1');
|
|
76
|
+
// Simulate a replug the transport never saw a disconnect event for: the OS
|
|
77
|
+
// re-enumerated the device, so the list now holds a NEW USBDevice object.
|
|
78
|
+
webusb.deviceList = [
|
|
79
|
+
{ path, device: { serialNumber: path } as unknown as USBDevice, commType: 'webusb' },
|
|
80
|
+
];
|
|
81
|
+
webusb.detectProtocol = jest.fn().mockImplementation((p: string) => {
|
|
82
|
+
webusb.deviceProtocol.set(p, 'V1');
|
|
83
|
+
return Promise.resolve('V1');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await expect(webusb.acquire({ path, expectedProtocol: 'V1' })).resolves.toBe(path);
|
|
87
|
+
|
|
88
|
+
expect(webusb.detectProtocol).toHaveBeenCalledTimes(1);
|
|
89
|
+
});
|
|
90
|
+
|
|
67
91
|
test('acquire re-probes a stale-marked path even when a protocol is cached', async () => {
|
|
68
92
|
const webusb = buildAcquirableTransport();
|
|
69
93
|
const path = 'pro-webusb';
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,14 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
|
|
|
27
27
|
private staleProtocolPaths;
|
|
28
28
|
/** Paths currently acquired (between a successful acquire() and its release()). */
|
|
29
29
|
private acquiredPaths;
|
|
30
|
+
/**
|
|
31
|
+
* The exact USBDevice object each cached protocol was probed against. The
|
|
32
|
+
* browser returns the same object identity for a device as long as it stays
|
|
33
|
+
* connected, and a replug/reboot always yields a new object — so an identity
|
|
34
|
+
* mismatch proves the device was re-enumerated since the probe, even when the
|
|
35
|
+
* disconnect event itself was delayed or missed.
|
|
36
|
+
*/
|
|
37
|
+
private probedDeviceObjects;
|
|
30
38
|
/** Per-path USB endpoint / interface numbers (discovered from USB descriptors) */
|
|
31
39
|
private deviceEndpoints;
|
|
32
40
|
name: string;
|
package/dist/index.js
CHANGED
|
@@ -59,7 +59,8 @@ function inferProtocolHintFromDeviceName$1(name) {
|
|
|
59
59
|
}
|
|
60
60
|
let activeWebUsbTransport;
|
|
61
61
|
let usbDisconnectListenerAttached = false;
|
|
62
|
-
function
|
|
62
|
+
function registerActiveWebUsbTransport(instance, usb) {
|
|
63
|
+
activeWebUsbTransport = instance;
|
|
63
64
|
if (usbDisconnectListenerAttached)
|
|
64
65
|
return;
|
|
65
66
|
usbDisconnectListenerAttached = true;
|
|
@@ -82,6 +83,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
82
83
|
this.deviceProtocolHints = new Map();
|
|
83
84
|
this.staleProtocolPaths = new Set();
|
|
84
85
|
this.acquiredPaths = new Set();
|
|
86
|
+
this.probedDeviceObjects = new Map();
|
|
85
87
|
this.deviceEndpoints = new Map();
|
|
86
88
|
this.name = 'WebUsbTransport';
|
|
87
89
|
this.stopped = false;
|
|
@@ -98,11 +100,11 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
98
100
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'WebUSB is not supported by current browsers');
|
|
99
101
|
}
|
|
100
102
|
this.usb = usb;
|
|
101
|
-
|
|
102
|
-
attachUsbDisconnectListener(usb);
|
|
103
|
+
registerActiveWebUsbTransport(this, usb);
|
|
103
104
|
}
|
|
104
105
|
markProtocolStale(path) {
|
|
105
106
|
this.staleProtocolPaths.add(path);
|
|
107
|
+
this.probedDeviceObjects.delete(path);
|
|
106
108
|
}
|
|
107
109
|
configure(signedData) {
|
|
108
110
|
const messages = parseConfigure$1(signedData);
|
|
@@ -169,7 +171,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
169
171
|
});
|
|
170
172
|
}
|
|
171
173
|
acquire(input) {
|
|
172
|
-
var _a, _b, _c, _d;
|
|
174
|
+
var _a, _b, _c, _d, _e, _f;
|
|
173
175
|
return __awaiter(this, void 0, void 0, function* () {
|
|
174
176
|
if (!input.path)
|
|
175
177
|
return;
|
|
@@ -181,19 +183,29 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
181
183
|
this.staleProtocolPaths.delete(input.path);
|
|
182
184
|
this.deviceProtocol.delete(input.path);
|
|
183
185
|
}
|
|
186
|
+
if (this.deviceProtocol.has(input.path)) {
|
|
187
|
+
const currentDevice = (_b = this.deviceList.find(d => d.path === input.path)) === null || _b === void 0 ? void 0 : _b.device;
|
|
188
|
+
if (!currentDevice || currentDevice !== this.probedDeviceObjects.get(input.path)) {
|
|
189
|
+
this.deviceProtocol.delete(input.path);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
184
192
|
const cachedProtocol = this.deviceProtocol.get(input.path);
|
|
185
193
|
if (cachedProtocol && input.expectedProtocol && cachedProtocol !== input.expectedProtocol) {
|
|
186
194
|
this.deviceProtocol.delete(input.path);
|
|
187
195
|
}
|
|
188
196
|
if (!this.deviceProtocol.has(input.path)) {
|
|
189
|
-
const deviceName = (
|
|
197
|
+
const deviceName = (_c = this.deviceList.find(device => device.path === input.path)) === null || _c === void 0 ? void 0 : _c.device.productName;
|
|
190
198
|
const protocolHint = input.expectedProtocol
|
|
191
199
|
? undefined
|
|
192
|
-
: (
|
|
200
|
+
: (_e = (_d = input.protocolHint) !== null && _d !== void 0 ? _d : this.deviceProtocolHints.get(input.path)) !== null && _e !== void 0 ? _e : inferProtocolHintFromDeviceName$1(deviceName);
|
|
193
201
|
if (protocolHint) {
|
|
194
202
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
195
203
|
}
|
|
196
204
|
yield this.detectProtocol(input.path, input.expectedProtocol, protocolHint);
|
|
205
|
+
const probedDevice = (_f = this.deviceList.find(d => d.path === input.path)) === null || _f === void 0 ? void 0 : _f.device;
|
|
206
|
+
if (probedDevice) {
|
|
207
|
+
this.probedDeviceObjects.set(input.path, probedDevice);
|
|
208
|
+
}
|
|
197
209
|
}
|
|
198
210
|
this.acquiredPaths.add(input.path);
|
|
199
211
|
return yield Promise.resolve(input.path);
|
package/dist/webusb.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
14
14
|
private deviceProtocolHints;
|
|
15
15
|
private staleProtocolPaths;
|
|
16
16
|
private acquiredPaths;
|
|
17
|
+
private probedDeviceObjects;
|
|
17
18
|
private deviceEndpoints;
|
|
18
19
|
name: string;
|
|
19
20
|
stopped: boolean;
|
package/dist/webusb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,EAAE,EAQhB,0BAA0B,EAE3B,MAAM,wBAAwB,CAAC;AAUhC,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AA0BhC,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.136",
|
|
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.0-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.136",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.136"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.136",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "92945bc4aae3d6602dd44c2e028e902e6bce7b55"
|
|
33
33
|
}
|
package/src/webusb.ts
CHANGED
|
@@ -79,7 +79,8 @@ interface TransferCancelToken {
|
|
|
79
79
|
let activeWebUsbTransport: WebUsbTransport | undefined;
|
|
80
80
|
let usbDisconnectListenerAttached = false;
|
|
81
81
|
|
|
82
|
-
function
|
|
82
|
+
function registerActiveWebUsbTransport(instance: WebUsbTransport, usb: USB) {
|
|
83
|
+
activeWebUsbTransport = instance;
|
|
83
84
|
if (usbDisconnectListenerAttached) return;
|
|
84
85
|
usbDisconnectListenerAttached = true;
|
|
85
86
|
usb.addEventListener('disconnect', event => {
|
|
@@ -111,6 +112,15 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
111
112
|
/** Paths currently acquired (between a successful acquire() and its release()). */
|
|
112
113
|
private acquiredPaths: Set<string> = new Set();
|
|
113
114
|
|
|
115
|
+
/**
|
|
116
|
+
* The exact USBDevice object each cached protocol was probed against. The
|
|
117
|
+
* browser returns the same object identity for a device as long as it stays
|
|
118
|
+
* connected, and a replug/reboot always yields a new object — so an identity
|
|
119
|
+
* mismatch proves the device was re-enumerated since the probe, even when the
|
|
120
|
+
* disconnect event itself was delayed or missed.
|
|
121
|
+
*/
|
|
122
|
+
private probedDeviceObjects: Map<string, USBDevice> = new Map();
|
|
123
|
+
|
|
114
124
|
/** Per-path USB endpoint / interface numbers (discovered from USB descriptors) */
|
|
115
125
|
private deviceEndpoints: Map<string, DeviceEndpoints> = new Map();
|
|
116
126
|
|
|
@@ -158,8 +168,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
158
168
|
);
|
|
159
169
|
}
|
|
160
170
|
this.usb = usb;
|
|
161
|
-
|
|
162
|
-
attachUsbDisconnectListener(usb);
|
|
171
|
+
registerActiveWebUsbTransport(this, usb);
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
/**
|
|
@@ -174,6 +183,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
174
183
|
*/
|
|
175
184
|
markProtocolStale(path: string) {
|
|
176
185
|
this.staleProtocolPaths.add(path);
|
|
186
|
+
this.probedDeviceObjects.delete(path);
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
/**
|
|
@@ -282,6 +292,15 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
282
292
|
this.staleProtocolPaths.delete(input.path);
|
|
283
293
|
this.deviceProtocol.delete(input.path);
|
|
284
294
|
}
|
|
295
|
+
if (this.deviceProtocol.has(input.path)) {
|
|
296
|
+
const currentDevice = this.deviceList.find(d => d.path === input.path)?.device;
|
|
297
|
+
if (!currentDevice || currentDevice !== this.probedDeviceObjects.get(input.path)) {
|
|
298
|
+
// The OS re-enumerated the device since the probe (a replug/reboot we
|
|
299
|
+
// may not have seen a disconnect event for) — the cached protocol can
|
|
300
|
+
// no longer be trusted; re-probe on the wire below.
|
|
301
|
+
this.deviceProtocol.delete(input.path);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
285
304
|
const cachedProtocol = this.deviceProtocol.get(input.path);
|
|
286
305
|
if (cachedProtocol && input.expectedProtocol && cachedProtocol !== input.expectedProtocol) {
|
|
287
306
|
// The caller expects a different protocol than the cached probe result;
|
|
@@ -300,6 +319,10 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
300
319
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
301
320
|
}
|
|
302
321
|
await this.detectProtocol(input.path, input.expectedProtocol, protocolHint);
|
|
322
|
+
const probedDevice = this.deviceList.find(d => d.path === input.path)?.device;
|
|
323
|
+
if (probedDevice) {
|
|
324
|
+
this.probedDeviceObjects.set(input.path, probedDevice);
|
|
325
|
+
}
|
|
303
326
|
}
|
|
304
327
|
this.acquiredPaths.add(input.path);
|
|
305
328
|
return await Promise.resolve(input.path);
|
|
@@ -550,10 +573,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
550
573
|
*/
|
|
551
574
|
private assertAcquired(path: string) {
|
|
552
575
|
if (!this.acquiredPaths.has(path)) {
|
|
553
|
-
throw ERRORS.TypedError(
|
|
554
|
-
HardwareErrorCode.RuntimeError,
|
|
555
|
-
`Device is not acquired for ${path}`
|
|
556
|
-
);
|
|
576
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, `Device is not acquired for ${path}`);
|
|
557
577
|
}
|
|
558
578
|
}
|
|
559
579
|
|