@onekeyfe/hd-transport-electron 1.2.3-alpha.3 → 1.2.3-alpha.4

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.
@@ -55,13 +55,13 @@ function invokeNobleBleIpc(request) {
55
55
 
56
56
  function initNobleBleSupport(webContents) {
57
57
  return __awaiter(this, void 0, void 0, function* () {
58
- const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-263d4736.js'); });
58
+ const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-23c86603.js'); });
59
59
  setupNobleBleHandlers(webContents);
60
60
  });
61
61
  }
62
62
  function disposeNobleBleSupport(releaseNoble) {
63
63
  return __awaiter(this, void 0, void 0, function* () {
64
- const handler = yield Promise.resolve().then(function () { return require('./noble-ble-handler-263d4736.js'); });
64
+ const handler = yield Promise.resolve().then(function () { return require('./noble-ble-handler-23c86603.js'); });
65
65
  yield handler.disposeNobleBleSupport(releaseNoble);
66
66
  });
67
67
  }
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-985e2bf3.js');
5
+ var index = require('./index-474dbbae.js');
6
6
 
7
7
 
8
8
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-985e2bf3.js');
3
+ var index = require('./index-474dbbae.js');
4
4
  var hdShared = require('@onekeyfe/hd-shared');
5
5
  var pRetry = require('p-retry');
6
6
 
@@ -887,7 +887,6 @@ function enumerateDevices(isWindowDestroyed) {
887
887
  return [];
888
888
  const nobleInstance = noble;
889
889
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Starting device enumeration');
890
- discoveredDevices.clear();
891
890
  ensureDiscoverListener();
892
891
  return new Promise((resolve, reject) => {
893
892
  const devices = [];
@@ -1281,7 +1280,10 @@ function connectDevice(deviceId, webContents) {
1281
1280
  totalDiscovered: discoveredDevices.size,
1282
1281
  totalConnected: connectedDevices.size,
1283
1282
  });
1284
- let peripheral = (_a = discoveredDevices.get(deviceId)) !== null && _a !== void 0 ? _a : connectedDevices.get(deviceId);
1283
+ let peripheral = (_a = connectedDevices.get(deviceId)) !== null && _a !== void 0 ? _a : discoveredDevices.get(deviceId);
1284
+ if ((peripheral === null || peripheral === void 0 ? void 0 : peripheral.state) !== 'connected') {
1285
+ peripheral = undefined;
1286
+ }
1285
1287
  if (!peripheral) {
1286
1288
  if (!noble) {
1287
1289
  yield initializeNoble();
@@ -1 +1 @@
1
- {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAiC1F,KAAK,mBAAmB,GAAG,KAAK,GAAG;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,mBAAmB,EAAE,aAAa,SAAK,+CAiB3F;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAgCvF;AA+KD,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE,oBAAoB,UAI7E;AAkyDD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAkOpE;AAOD,wBAAgB,sBAAsB,CACpC,YAAY,GAAE,CAAC,QAAQ,EAAE;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,KAAK,IAAkC,GAC/E,OAAO,CAAC,IAAI,CAAC,CAiEf"}
1
+ {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAiC1F,KAAK,mBAAmB,GAAG,KAAK,GAAG;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,mBAAmB,EAAE,aAAa,SAAK,+CAiB3F;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAgCvF;AA+KD,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE,oBAAoB,UAI7E;AAqyDD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAkOpE;AAOD,wBAAgB,sBAAsB,CACpC,YAAY,GAAE,CAAC,QAAQ,EAAE;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,KAAK,IAAkC,GAC/E,OAAO,CAAC,IAAI,CAAC,CAiEf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-electron",
3
- "version": "1.2.3-alpha.3",
3
+ "version": "1.2.3-alpha.4",
4
4
  "author": "OneKey",
5
5
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
6
6
  "license": "MIT",
@@ -25,9 +25,9 @@
25
25
  "electron-log": ">=4.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-core": "1.2.3-alpha.3",
29
- "@onekeyfe/hd-shared": "1.2.3-alpha.3",
30
- "@onekeyfe/hd-transport": "1.2.3-alpha.3",
28
+ "@onekeyfe/hd-core": "1.2.3-alpha.4",
29
+ "@onekeyfe/hd-shared": "1.2.3-alpha.4",
30
+ "@onekeyfe/hd-transport": "1.2.3-alpha.4",
31
31
  "@stoprocent/noble": "2.3.16",
32
32
  "p-retry": "^4.6.2"
33
33
  },
@@ -36,5 +36,5 @@
36
36
  "electron": "^25.0.0",
37
37
  "typescript": "^5.3.3"
38
38
  },
39
- "gitHead": "8b116adb144b967f042f189cd27384a75ca1f7ae"
39
+ "gitHead": "705729baaec54b86a4fc28cce310a85b67b82730"
40
40
  }
@@ -225,6 +225,133 @@ describe('Electron Noble BLE device discovery', () => {
225
225
  ]);
226
226
  });
227
227
 
228
+ test.each(['Pro A1B2', 'Pro2 A1B2'])(
229
+ 'retains %s across scan rounds until Bluetooth is powered off',
230
+ async name => {
231
+ jest.useFakeTimers({ doNotFake: ['performance'] });
232
+
233
+ const handlers = new Map<string, IpcHandler>();
234
+ const ipcMain = {
235
+ handle: jest.fn((channel: string, handler: IpcHandler) => {
236
+ handlers.set(channel, handler);
237
+ }),
238
+ removeHandler: jest.fn((channel: string) => {
239
+ handlers.delete(channel);
240
+ }),
241
+ };
242
+ const noble = Object.assign(new EventEmitter(), {
243
+ state: 'poweredOn',
244
+ startScanning: jest.fn(),
245
+ stopScanning: jest.fn(callback => callback?.()),
246
+ });
247
+
248
+ jest.doMock('@stoprocent/noble', () => noble);
249
+ jest.doMock('electron', () => ({ ipcMain }));
250
+ jest.doMock('electron-log', () => ({
251
+ info: jest.fn(),
252
+ debug: jest.fn(),
253
+ error: jest.fn(),
254
+ }));
255
+
256
+ const { setupNobleBleHandlers } = await import('../noble-ble-handler');
257
+ setupNobleBleHandlers({
258
+ on: jest.fn(),
259
+ send: jest.fn(),
260
+ } as unknown as WebContents);
261
+
262
+ const enumerate = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_ENUMERATE);
263
+ if (!enumerate) {
264
+ throw new Error('Electron Noble BLE enumerate handler was not registered');
265
+ }
266
+
267
+ const scan = async (peripherals: ReturnType<typeof createPeripheral>[]) => {
268
+ let resolveScanStarted = () => undefined;
269
+ const scanStarted = new Promise<void>(resolve => {
270
+ resolveScanStarted = resolve;
271
+ });
272
+ noble.startScanning.mockImplementationOnce((_services, _duplicates, callback) => {
273
+ callback?.();
274
+ peripherals.forEach(peripheral => noble.emit('discover', peripheral));
275
+ resolveScanStarted();
276
+ });
277
+ const devices = Promise.resolve(enumerate());
278
+ await scanStarted;
279
+ jest.advanceTimersByTime(5_000);
280
+ return devices;
281
+ };
282
+
283
+ const firstDevice = createPeripheral('first-device', name);
284
+ const secondDevice = createPeripheral('second-device', 'Pro2 C3D4');
285
+ await expect(scan([firstDevice])).resolves.toEqual([
286
+ expect.objectContaining({ id: 'first-device', name }),
287
+ ]);
288
+ await expect(scan([secondDevice, secondDevice])).resolves.toEqual([
289
+ expect.objectContaining({ id: 'first-device', name }),
290
+ expect.objectContaining({ id: 'second-device', name: 'Pro2 C3D4' }),
291
+ ]);
292
+ await expect(scan([])).resolves.toHaveLength(2);
293
+
294
+ noble.state = 'poweredOff';
295
+ noble.emit('stateChange', 'poweredOff');
296
+ noble.state = 'poweredOn';
297
+ noble.emit('stateChange', 'poweredOn');
298
+ await expect(scan([])).resolves.toEqual([]);
299
+ }
300
+ );
301
+
302
+ test.each(['Pro A1B2', 'Pro2 A1B2'])(
303
+ 'refreshes a retained disconnected %s peripheral before cold connecting',
304
+ async name => {
305
+ const handlers = new Map<string, IpcHandler>();
306
+ const stalePeripheral = Object.assign(new EventEmitter(), createPeripheral('device', name), {
307
+ connect: jest.fn(),
308
+ });
309
+ const freshPeripheral = Object.assign(new EventEmitter(), createPeripheral('device', name), {
310
+ connect: jest.fn((callback: (error?: Error) => void) => {
311
+ callback(new Error('expected fresh connection failure'));
312
+ }),
313
+ });
314
+ const noble = Object.assign(new EventEmitter(), {
315
+ state: 'poweredOn',
316
+ startScanning: jest.fn((_services, _duplicates, callback) => {
317
+ callback?.();
318
+ noble.emit('discover', freshPeripheral);
319
+ }),
320
+ stopScanning: jest.fn(callback => callback?.()),
321
+ connectAsync: jest.fn(() => Promise.resolve(undefined)),
322
+ });
323
+ jest.doMock('@stoprocent/noble', () => noble);
324
+ jest.doMock('electron', () => ({
325
+ ipcMain: {
326
+ handle: (channel: string, handler: IpcHandler) => handlers.set(channel, handler),
327
+ removeHandler: (channel: string) => handlers.delete(channel),
328
+ },
329
+ }));
330
+ jest.doMock('electron-log', () => ({
331
+ info: jest.fn(),
332
+ debug: jest.fn(),
333
+ error: jest.fn(),
334
+ }));
335
+ const { setupNobleBleHandlers } = await import('../noble-ble-handler');
336
+ setupNobleBleHandlers({ on: jest.fn(), send: jest.fn() } as unknown as WebContents);
337
+ const availability = handlers.get(EOneKeyBleMessageKeys.BLE_AVAILABILITY_CHECK);
338
+ const connect = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_CONNECT);
339
+ if (!availability || !connect) throw new Error('Noble handlers were not registered');
340
+ await availability();
341
+ noble.emit('discover', stalePeripheral);
342
+
343
+ await expect(Promise.resolve(connect(undefined, stalePeripheral.id))).resolves.toMatchObject({
344
+ success: false,
345
+ error: { message: 'expected fresh connection failure' },
346
+ });
347
+
348
+ expect(stalePeripheral.connect).not.toHaveBeenCalled();
349
+ expect(freshPeripheral.connect).toHaveBeenCalledTimes(1);
350
+ expect(noble.startScanning).toHaveBeenCalledTimes(1);
351
+ expect(noble.connectAsync).toHaveBeenCalledTimes(name.startsWith('Pro2') ? 1 : 0);
352
+ }
353
+ );
354
+
228
355
  test('waits for a targeted scan to stop before connecting', async () => {
229
356
  jest.useFakeTimers({ doNotFake: ['performance'] });
230
357
 
@@ -846,9 +973,12 @@ describe('Noble BLE process shutdown', () => {
846
973
  discoverServices: jest.fn(),
847
974
  });
848
975
  native.emit('discover', peripheral);
976
+ native.startScanning.mockImplementationOnce((_uuids, _duplicates, callback) => {
977
+ callback?.();
978
+ native.emit('discover', peripheral);
979
+ });
849
980
  const connecting = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_CONNECT)?.({}, peripheral.id);
850
- await Promise.resolve();
851
- await Promise.resolve();
981
+ await flushCallbacks();
852
982
  expect(peripheral.connect).toHaveBeenCalledTimes(1);
853
983
  const disposing = sdk.disposeNobleBleSupport();
854
984
  await flushCallbacks();
@@ -886,7 +1016,13 @@ describe('Noble BLE process shutdown', () => {
886
1016
  );
887
1017
  const cancelConnect = jest.fn();
888
1018
  if (route === 'direct') Object.assign(native, { connectAsync, cancelConnect });
889
- else native.emit('discover', peripheral);
1019
+ else {
1020
+ native.emit('discover', peripheral);
1021
+ native.startScanning.mockImplementationOnce((_uuids, _duplicates, callback) => {
1022
+ callback?.();
1023
+ native.emit('discover', peripheral);
1024
+ });
1025
+ }
890
1026
  const connecting = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_CONNECT)?.({}, peripheral.id);
891
1027
  await flushCallbacks();
892
1028
  if (route === 'direct') {
@@ -1167,8 +1167,7 @@ async function enumerateDevices(isWindowDestroyed: () => boolean): Promise<Devic
1167
1167
 
1168
1168
  logger?.info('[NobleBLE] Starting device enumeration');
1169
1169
 
1170
- // Clear previous discoveries
1171
- discoveredDevices.clear();
1170
+ // Keep prior discoveries when a polling round misses an advertisement.
1172
1171
 
1173
1172
  // Ensure discover listener is properly set up before scanning
1174
1173
  // This is crucial to fix the issue where devices are not found after web-usb failures
@@ -1766,8 +1765,12 @@ async function connectDevice(deviceId: string, webContents: WebContents): Promis
1766
1765
  totalConnected: connectedDevices.size,
1767
1766
  });
1768
1767
 
1769
- // enumerate clears the discovery map; a kept-alive link outlives it.
1770
- let peripheral = discoveredDevices.get(deviceId) ?? connectedDevices.get(deviceId);
1768
+ // Retained discoveries are display metadata, not proof of a reusable native link.
1769
+ // Prefer the live connection when an older discovery exists for the same device.
1770
+ let peripheral = connectedDevices.get(deviceId) ?? discoveredDevices.get(deviceId);
1771
+ if (peripheral?.state !== 'connected') {
1772
+ peripheral = undefined;
1773
+ }
1771
1774
 
1772
1775
  if (!peripheral) {
1773
1776
  // Initialize Noble if not already done