diff --git a/package-lock.json b/package-lock.json index cc165e7..8a78b2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1239,9 +1239,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1258,9 +1255,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1277,9 +1271,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1296,9 +1287,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1690,8 +1678,8 @@ "license": "Apache-2.0" }, "node_modules/brace-expansion": { - "version": "2.1.1", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.4", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -2195,8 +2183,8 @@ } }, "node_modules/js-yaml": { - "version": "4.2.0", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "version": "4.3.1", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "funding": [ { @@ -2744,15 +2732,15 @@ } }, "node_modules/typedoc/node_modules/brace-expansion": { - "version": "5.0.6", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.9", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/typedoc/node_modules/minimatch": { diff --git a/src/lib.rs b/src/lib.rs index 12f86b6..7a1b951 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ fn watch_task_guard( #[napi] pub struct Emitter { callbacks: Arc>, - watch_task: Arc>>>, + watch_task: Mutex>>, } #[napi] @@ -52,7 +52,7 @@ impl Emitter { })); Self { callbacks, - watch_task: Arc::new(Mutex::new(None)), + watch_task: Mutex::new(None), } } diff --git a/tsc/index.ts b/tsc/index.ts index 835beea..5bf0db3 100644 --- a/tsc/index.ts +++ b/tsc/index.ts @@ -139,11 +139,18 @@ class WebUSB extends EventTarget implements USB { protected listenerCount = 0; protected eventListeners = new Map>(); protected knownDevices: Map = new Map(); + protected nativeEmitterQueue: Promise = Promise.resolve(); constructor(private options: USBOptions = {}) { super(); } + private queueNativeEmitterOperation(operation: () => Promise): void { + const pending = this.nativeEmitterQueue.then(operation); + this.nativeEmitterQueue = pending.catch(() => {}); + pending.catch(error => setTimeout(() => { throw error; }, 0)); + } + private deviceConnectCallback = async (device: UsbDevice) => { this.knownDevices.set(device.handle, device); @@ -183,8 +190,10 @@ class WebUSB extends EventTarget implements USB { } if (!hadListeners && this.listenerCount > 0) { - this.nativeEmitter.addAttach(this.deviceConnectCallback); - this.nativeEmitter.addDetach(this.deviceDisconnectCallback); + this.queueNativeEmitterOperation(async () => { + await this.nativeEmitter.addAttach(this.deviceConnectCallback); + await this.nativeEmitter.addDetach(this.deviceDisconnectCallback); + }); nativeGetDevices().then(devices => devices.forEach(device => this.knownDevices.set(device.handle, device))); } } @@ -209,8 +218,10 @@ class WebUSB extends EventTarget implements USB { } if (removed && this.listenerCount === 0) { - this.nativeEmitter.removeAttach(); - this.nativeEmitter.removeDetach(); + this.queueNativeEmitterOperation(async () => { + await this.nativeEmitter.removeAttach(); + await this.nativeEmitter.removeDetach(); + }); this.knownDevices.clear(); } }