usb 2.3.0 → 2.4.1
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/CHANGELOG.md +25 -1
- package/README.md +1 -1
- package/binding.gyp +3 -3
- package/dist/webusb/webusb-device.d.ts +0 -1
- package/dist/webusb/webusb-device.js +149 -243
- package/dist/webusb/webusb-device.js.map +1 -1
- package/package.json +6 -5
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +20 -22
- package/src/node_usb.cc +93 -119
- package/src/node_usb.h +27 -15
- package/src/transfer.cc +0 -5
- package/test/usb.coffee +18 -7
- package/test/worker.cjs +9 -0
- package/tsc/webusb/webusb-device.ts +67 -124
- package/dist/webusb/mutex.d.ts +0 -22
- package/dist/webusb/mutex.js +0 -89
- package/dist/webusb/mutex.js.map +0 -1
- package/tsc/webusb/mutex.ts +0 -38
package/test/usb.coffee
CHANGED
|
@@ -4,6 +4,7 @@ usb = require('../').usb
|
|
|
4
4
|
getDeviceList = require('../').getDeviceList
|
|
5
5
|
findByIds = require('../').findByIds
|
|
6
6
|
findBySerialNumber = require('../').findBySerialNumber
|
|
7
|
+
Worker = require('worker_threads').Worker
|
|
7
8
|
|
|
8
9
|
if typeof gc is 'function'
|
|
9
10
|
# running with --expose-gc, do a sweep between tests so valgrind blames the right one
|
|
@@ -20,14 +21,14 @@ describe 'USB Module', ->
|
|
|
20
21
|
assert.throws -> usb.Device()
|
|
21
22
|
assert.throws -> usb.Device.prototype.open.call({})
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
describe 'setDebugLevel', ->
|
|
25
|
+
it 'should throw when passed invalid args', ->
|
|
26
|
+
assert.throws((-> usb.setDebugLevel()), TypeError)
|
|
27
|
+
assert.throws((-> usb.setDebugLevel(-1)), TypeError)
|
|
28
|
+
assert.throws((-> usb.setDebugLevel(5)), TypeError)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
it 'should succeed with good args', ->
|
|
31
|
+
assert.doesNotThrow(-> usb.setDebugLevel(0))
|
|
31
32
|
|
|
32
33
|
describe 'getDeviceList', ->
|
|
33
34
|
it 'should return at least one device', ->
|
|
@@ -201,3 +202,13 @@ describe 'Device', ->
|
|
|
201
202
|
|
|
202
203
|
after ->
|
|
203
204
|
device.close()
|
|
205
|
+
|
|
206
|
+
if process.platform != 'win32'
|
|
207
|
+
describe 'Context Aware', ->
|
|
208
|
+
it 'should handle opening the same device from different contexts', ->
|
|
209
|
+
for n in [1..5]
|
|
210
|
+
worker = new Worker('./test/worker.cjs')
|
|
211
|
+
worker.on 'message', (serial) ->
|
|
212
|
+
assert.equal(serial, 'TEST_DEVICE')
|
|
213
|
+
worker.on 'exit', (code) ->
|
|
214
|
+
assert.equal(code, 0)
|
package/test/worker.cjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const parentPort = require('worker_threads').parentPort
|
|
2
|
+
const findByIds = require('../dist').findByIds;
|
|
3
|
+
|
|
4
|
+
const device = findByIds(0x59e3, 0x0a23);
|
|
5
|
+
device.open();
|
|
6
|
+
device.getStringDescriptor(device.deviceDescriptor.iSerialNumber, (_, serial) => {
|
|
7
|
+
parentPort.postMessage(serial);
|
|
8
|
+
device.close();
|
|
9
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as usb from '../usb';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
3
|
import { Endpoint, InEndpoint, OutEndpoint } from '../usb/endpoint';
|
|
4
|
-
import { Mutex } from './mutex';
|
|
5
4
|
|
|
6
5
|
const LIBUSB_TRANSFER_TYPE_MASK = 0x03;
|
|
7
6
|
const ENDPOINT_NUMBER_MASK = 0x7f;
|
|
@@ -39,8 +38,6 @@ export class WebUSBDevice implements USBDevice {
|
|
|
39
38
|
public serialNumber?: string | undefined;
|
|
40
39
|
public configurations: USBConfiguration[] = [];
|
|
41
40
|
|
|
42
|
-
private deviceMutex = new Mutex();
|
|
43
|
-
|
|
44
41
|
private constructor(private device: usb.Device) {
|
|
45
42
|
const usbVersion = this.decodeVersion(device.deviceDescriptor.bcdUSB);
|
|
46
43
|
this.usbVersionMajor = usbVersion.major;
|
|
@@ -73,8 +70,6 @@ export class WebUSBDevice implements USBDevice {
|
|
|
73
70
|
|
|
74
71
|
public async open(): Promise<void> {
|
|
75
72
|
try {
|
|
76
|
-
await this.deviceMutex.lock();
|
|
77
|
-
|
|
78
73
|
if (this.opened) {
|
|
79
74
|
return;
|
|
80
75
|
}
|
|
@@ -82,15 +77,11 @@ export class WebUSBDevice implements USBDevice {
|
|
|
82
77
|
this.device.open();
|
|
83
78
|
} catch (error) {
|
|
84
79
|
throw new Error(`open error: ${error}`);
|
|
85
|
-
} finally {
|
|
86
|
-
this.deviceMutex.unlock();
|
|
87
80
|
}
|
|
88
81
|
}
|
|
89
82
|
|
|
90
83
|
public async close(): Promise<void> {
|
|
91
84
|
try {
|
|
92
|
-
await this.deviceMutex.lock();
|
|
93
|
-
|
|
94
85
|
if (!this.opened) {
|
|
95
86
|
return;
|
|
96
87
|
}
|
|
@@ -115,137 +106,110 @@ export class WebUSBDevice implements USBDevice {
|
|
|
115
106
|
this.device.close();
|
|
116
107
|
} catch (error) {
|
|
117
108
|
throw new Error(`close error: ${error}`);
|
|
118
|
-
} finally {
|
|
119
|
-
this.deviceMutex.unlock();
|
|
120
109
|
}
|
|
121
110
|
}
|
|
122
111
|
|
|
123
112
|
public async selectConfiguration(configurationValue: number): Promise<void> {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (!this.opened || !this.device.configDescriptor) {
|
|
128
|
-
throw new Error('selectConfiguration error: invalid state');
|
|
129
|
-
}
|
|
113
|
+
if (!this.opened || !this.device.configDescriptor) {
|
|
114
|
+
throw new Error('selectConfiguration error: invalid state');
|
|
115
|
+
}
|
|
130
116
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
117
|
+
if (this.device.configDescriptor.bConfigurationValue === configurationValue) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
134
120
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
121
|
+
const config = this.configurations.find(configuration => configuration.configurationValue === configurationValue);
|
|
122
|
+
if (!config) {
|
|
123
|
+
throw new Error('selectConfiguration error: configuration not found');
|
|
124
|
+
}
|
|
139
125
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
} finally {
|
|
147
|
-
this.deviceMutex.unlock();
|
|
126
|
+
try {
|
|
127
|
+
const setConfiguration = promisify(this.device.setConfiguration).bind(this.device);
|
|
128
|
+
await setConfiguration(configurationValue);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
throw new Error(`selectConfiguration error: ${error}`);
|
|
148
131
|
}
|
|
149
132
|
}
|
|
150
133
|
|
|
151
134
|
public async claimInterface(interfaceNumber: number): Promise<void> {
|
|
152
|
-
|
|
153
|
-
|
|
135
|
+
if (!this.opened) {
|
|
136
|
+
throw new Error('claimInterface error: invalid state');
|
|
137
|
+
}
|
|
154
138
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
139
|
+
if (!this.configuration) {
|
|
140
|
+
throw new Error('claimInterface error: interface not found');
|
|
141
|
+
}
|
|
158
142
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
143
|
+
const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
|
|
144
|
+
if (!iface) {
|
|
145
|
+
throw new Error('claimInterface error: interface not found');
|
|
146
|
+
}
|
|
162
147
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
148
|
+
if (iface.claimed) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
167
151
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
152
|
+
try {
|
|
153
|
+
this.device.interface(interfaceNumber).claim();
|
|
154
|
+
|
|
155
|
+
// Re-create the USBInterface to set the claimed attribute
|
|
156
|
+
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
157
|
+
interfaceNumber,
|
|
158
|
+
alternate: iface.alternate,
|
|
159
|
+
alternates: iface.alternates,
|
|
160
|
+
claimed: true
|
|
161
|
+
};
|
|
162
|
+
} catch (error) {
|
|
163
|
+
throw new Error(`claimInterface error: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
|
|
167
|
+
public async releaseInterface(interfaceNumber: number): Promise<void> {
|
|
168
|
+
await this._releaseInterface(interfaceNumber);
|
|
174
169
|
|
|
170
|
+
if (this.configuration) {
|
|
171
|
+
const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
|
|
172
|
+
if (iface) {
|
|
175
173
|
// Re-create the USBInterface to set the claimed attribute
|
|
176
174
|
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
177
175
|
interfaceNumber,
|
|
178
176
|
alternate: iface.alternate,
|
|
179
177
|
alternates: iface.alternates,
|
|
180
|
-
claimed:
|
|
178
|
+
claimed: false
|
|
181
179
|
};
|
|
182
|
-
} catch (error) {
|
|
183
|
-
throw new Error(`claimInterface error: ${error}`);
|
|
184
|
-
}
|
|
185
|
-
} finally {
|
|
186
|
-
this.deviceMutex.unlock();
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
public async releaseInterface(interfaceNumber: number): Promise<void> {
|
|
191
|
-
try {
|
|
192
|
-
await this.deviceMutex.lock();
|
|
193
|
-
await this._releaseInterface(interfaceNumber);
|
|
194
|
-
|
|
195
|
-
if (this.configuration) {
|
|
196
|
-
const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
|
|
197
|
-
if (iface) {
|
|
198
|
-
// Re-create the USBInterface to set the claimed attribute
|
|
199
|
-
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
200
|
-
interfaceNumber,
|
|
201
|
-
alternate: iface.alternate,
|
|
202
|
-
alternates: iface.alternates,
|
|
203
|
-
claimed: false
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
180
|
}
|
|
207
|
-
|
|
208
|
-
} finally {
|
|
209
|
-
this.deviceMutex.unlock();
|
|
210
181
|
}
|
|
211
182
|
}
|
|
212
183
|
|
|
213
184
|
public async selectAlternateInterface(interfaceNumber: number, alternateSetting: number): Promise<void> {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (!this.opened) {
|
|
218
|
-
throw new Error('selectAlternateInterface error: invalid state');
|
|
219
|
-
}
|
|
185
|
+
if (!this.opened) {
|
|
186
|
+
throw new Error('selectAlternateInterface error: invalid state');
|
|
187
|
+
}
|
|
220
188
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
189
|
+
if (!this.configuration) {
|
|
190
|
+
throw new Error('selectAlternateInterface error: interface not found');
|
|
191
|
+
}
|
|
224
192
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
193
|
+
const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
|
|
194
|
+
if (!iface) {
|
|
195
|
+
throw new Error('selectAlternateInterface error: interface not found');
|
|
196
|
+
}
|
|
229
197
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
198
|
+
if (!iface.claimed) {
|
|
199
|
+
throw new Error('selectAlternateInterface error: invalid state');
|
|
200
|
+
}
|
|
233
201
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
} finally {
|
|
242
|
-
this.deviceMutex.unlock();
|
|
202
|
+
try {
|
|
203
|
+
const iface = this.device.interface(interfaceNumber);
|
|
204
|
+
const setAltSetting = promisify(iface.setAltSetting).bind(iface);
|
|
205
|
+
await setAltSetting(alternateSetting);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
throw new Error(`selectAlternateInterface error: ${error}`);
|
|
243
208
|
}
|
|
244
209
|
}
|
|
245
210
|
|
|
246
211
|
public async controlTransferIn(setup: USBControlTransferParameters, length: number): Promise<USBInTransferResult> {
|
|
247
212
|
try {
|
|
248
|
-
await this.deviceMutex.lock();
|
|
249
213
|
const type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_IN);
|
|
250
214
|
const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
|
|
251
215
|
const result = await controlTransfer(type, setup.request, setup.value, setup.index, length);
|
|
@@ -268,14 +232,11 @@ export class WebUSBDevice implements USBDevice {
|
|
|
268
232
|
}
|
|
269
233
|
|
|
270
234
|
throw new Error(`controlTransferIn error: ${error}`);
|
|
271
|
-
} finally {
|
|
272
|
-
this.deviceMutex.unlock();
|
|
273
235
|
}
|
|
274
236
|
}
|
|
275
237
|
|
|
276
238
|
public async controlTransferOut(setup: USBControlTransferParameters, data?: ArrayBuffer): Promise<USBOutTransferResult> {
|
|
277
239
|
try {
|
|
278
|
-
await this.deviceMutex.lock();
|
|
279
240
|
const type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_OUT);
|
|
280
241
|
const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
|
|
281
242
|
const buffer = data ? Buffer.from(data) : Buffer.alloc(0);
|
|
@@ -294,27 +255,21 @@ export class WebUSBDevice implements USBDevice {
|
|
|
294
255
|
}
|
|
295
256
|
|
|
296
257
|
throw new Error(`controlTransferOut error: ${error}`);
|
|
297
|
-
} finally {
|
|
298
|
-
this.deviceMutex.unlock();
|
|
299
258
|
}
|
|
300
259
|
}
|
|
301
260
|
|
|
302
261
|
public async clearHalt(direction: USBDirection, endpointNumber: number): Promise<void> {
|
|
303
262
|
try {
|
|
304
|
-
await this.deviceMutex.lock();
|
|
305
263
|
const wIndex = endpointNumber | (direction === 'in' ? usb.LIBUSB_ENDPOINT_IN : usb.LIBUSB_ENDPOINT_OUT);
|
|
306
264
|
const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
|
|
307
265
|
await controlTransfer(usb.LIBUSB_RECIPIENT_ENDPOINT, CLEAR_FEATURE, ENDPOINT_HALT, wIndex, 0);
|
|
308
266
|
} catch (error) {
|
|
309
267
|
throw new Error(`clearHalt error: ${error}`);
|
|
310
|
-
} finally {
|
|
311
|
-
this.deviceMutex.unlock();
|
|
312
268
|
}
|
|
313
269
|
}
|
|
314
270
|
|
|
315
271
|
public async transferIn(endpointNumber: number, length: number): Promise<USBInTransferResult> {
|
|
316
272
|
try {
|
|
317
|
-
await this.deviceMutex.lock();
|
|
318
273
|
const endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_IN) as InEndpoint;
|
|
319
274
|
const transfer = promisify(endpoint.transfer).bind(endpoint);
|
|
320
275
|
const result = await transfer(length);
|
|
@@ -337,14 +292,11 @@ export class WebUSBDevice implements USBDevice {
|
|
|
337
292
|
}
|
|
338
293
|
|
|
339
294
|
throw new Error(`transferIn error: ${error}`);
|
|
340
|
-
} finally {
|
|
341
|
-
this.deviceMutex.unlock();
|
|
342
295
|
}
|
|
343
296
|
}
|
|
344
297
|
|
|
345
298
|
public async transferOut(endpointNumber: number, data: ArrayBuffer): Promise<USBOutTransferResult> {
|
|
346
299
|
try {
|
|
347
|
-
await this.deviceMutex.lock();
|
|
348
300
|
const endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_OUT) as OutEndpoint;
|
|
349
301
|
const transfer = promisify(endpoint.transfer).bind(endpoint);
|
|
350
302
|
const buffer = Buffer.from(data);
|
|
@@ -363,20 +315,15 @@ export class WebUSBDevice implements USBDevice {
|
|
|
363
315
|
}
|
|
364
316
|
|
|
365
317
|
throw new Error(`transferOut error: ${error}`);
|
|
366
|
-
} finally {
|
|
367
|
-
this.deviceMutex.unlock();
|
|
368
318
|
}
|
|
369
319
|
}
|
|
370
320
|
|
|
371
321
|
public async reset(): Promise<void> {
|
|
372
322
|
try {
|
|
373
|
-
await this.deviceMutex.lock();
|
|
374
323
|
const reset = promisify(this.device.reset).bind(this.device);
|
|
375
324
|
await reset();
|
|
376
325
|
} catch (error) {
|
|
377
326
|
throw new Error(`reset error: ${error}`);
|
|
378
|
-
} finally {
|
|
379
|
-
this.deviceMutex.unlock();
|
|
380
327
|
}
|
|
381
328
|
}
|
|
382
329
|
|
|
@@ -394,8 +341,6 @@ export class WebUSBDevice implements USBDevice {
|
|
|
394
341
|
|
|
395
342
|
private async initialize(): Promise<void> {
|
|
396
343
|
try {
|
|
397
|
-
await this.deviceMutex.lock();
|
|
398
|
-
|
|
399
344
|
if (!this.opened) {
|
|
400
345
|
this.device.open();
|
|
401
346
|
}
|
|
@@ -410,8 +355,6 @@ export class WebUSBDevice implements USBDevice {
|
|
|
410
355
|
if (this.opened) {
|
|
411
356
|
this.device.close();
|
|
412
357
|
}
|
|
413
|
-
|
|
414
|
-
this.deviceMutex.unlock();
|
|
415
358
|
}
|
|
416
359
|
}
|
|
417
360
|
|
package/dist/webusb/mutex.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A mutex implementation that can be used to lock access between concurrent async functions
|
|
3
|
-
*/
|
|
4
|
-
export declare class Mutex {
|
|
5
|
-
private locked;
|
|
6
|
-
/**
|
|
7
|
-
* Create a new Mutex
|
|
8
|
-
*/
|
|
9
|
-
constructor();
|
|
10
|
-
/**
|
|
11
|
-
* Yield the current execution context, effectively moving it to the back of the promise queue
|
|
12
|
-
*/
|
|
13
|
-
private sleep;
|
|
14
|
-
/**
|
|
15
|
-
* Wait until the Mutex is available and claim it
|
|
16
|
-
*/
|
|
17
|
-
lock(): Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Unlock the Mutex
|
|
20
|
-
*/
|
|
21
|
-
unlock(): void;
|
|
22
|
-
}
|
package/dist/webusb/mutex.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.Mutex = void 0;
|
|
40
|
-
/**
|
|
41
|
-
* A mutex implementation that can be used to lock access between concurrent async functions
|
|
42
|
-
*/
|
|
43
|
-
var Mutex = /** @class */ (function () {
|
|
44
|
-
/**
|
|
45
|
-
* Create a new Mutex
|
|
46
|
-
*/
|
|
47
|
-
function Mutex() {
|
|
48
|
-
this.locked = false;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Yield the current execution context, effectively moving it to the back of the promise queue
|
|
52
|
-
*/
|
|
53
|
-
Mutex.prototype.sleep = function () {
|
|
54
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
55
|
-
return __generator(this, function (_a) {
|
|
56
|
-
return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, 1); })];
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Wait until the Mutex is available and claim it
|
|
62
|
-
*/
|
|
63
|
-
Mutex.prototype.lock = function () {
|
|
64
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
65
|
-
return __generator(this, function (_a) {
|
|
66
|
-
switch (_a.label) {
|
|
67
|
-
case 0:
|
|
68
|
-
if (!this.locked) return [3 /*break*/, 2];
|
|
69
|
-
return [4 /*yield*/, this.sleep()];
|
|
70
|
-
case 1:
|
|
71
|
-
_a.sent();
|
|
72
|
-
return [3 /*break*/, 0];
|
|
73
|
-
case 2:
|
|
74
|
-
this.locked = true;
|
|
75
|
-
return [2 /*return*/];
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Unlock the Mutex
|
|
82
|
-
*/
|
|
83
|
-
Mutex.prototype.unlock = function () {
|
|
84
|
-
this.locked = false;
|
|
85
|
-
};
|
|
86
|
-
return Mutex;
|
|
87
|
-
}());
|
|
88
|
-
exports.Mutex = Mutex;
|
|
89
|
-
//# sourceMappingURL=mutex.js.map
|
package/dist/webusb/mutex.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../tsc/webusb/mutex.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;GAEG;AACH;IAGI;;OAEG;IACH;QACI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACxB,CAAC;IAED;;OAEG;IACW,qBAAK,GAAnB;;;gBACI,sBAAO,IAAI,OAAO,CAAC,UAAA,OAAO,IAAI,OAAA,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,EAAtB,CAAsB,CAAC,EAAC;;;KACzD;IAED;;OAEG;IACU,oBAAI,GAAjB;;;;;6BACW,IAAI,CAAC,MAAM;wBACd,qBAAM,IAAI,CAAC,KAAK,EAAE,EAAA;;wBAAlB,SAAkB,CAAC;;;wBAGvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;;;;;KACtB;IAED;;OAEG;IACI,sBAAM,GAAb;QACI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACxB,CAAC;IACL,YAAC;AAAD,CAAC,AAlCD,IAkCC;AAlCY,sBAAK"}
|
package/tsc/webusb/mutex.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A mutex implementation that can be used to lock access between concurrent async functions
|
|
3
|
-
*/
|
|
4
|
-
export class Mutex {
|
|
5
|
-
private locked: boolean;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Create a new Mutex
|
|
9
|
-
*/
|
|
10
|
-
constructor() {
|
|
11
|
-
this.locked = false;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Yield the current execution context, effectively moving it to the back of the promise queue
|
|
16
|
-
*/
|
|
17
|
-
private async sleep(): Promise<void> {
|
|
18
|
-
return new Promise(resolve => setTimeout(resolve, 1));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Wait until the Mutex is available and claim it
|
|
23
|
-
*/
|
|
24
|
-
public async lock(): Promise<void> {
|
|
25
|
-
while (this.locked) {
|
|
26
|
-
await this.sleep();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
this.locked = true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Unlock the Mutex
|
|
34
|
-
*/
|
|
35
|
-
public unlock(): void {
|
|
36
|
-
this.locked = false;
|
|
37
|
-
}
|
|
38
|
-
}
|