@onekeyfe/hd-transport-react-native 1.2.0-alpha.129 → 1.2.0-alpha.130

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/dist/index.d.ts CHANGED
@@ -132,6 +132,8 @@ declare class ReactNativeBleTransport {
132
132
  private androidHighPriorityDevices;
133
133
  private androidPriorityResetTimers;
134
134
  private nextMonitorToken;
135
+ /** Serializes transport lifecycle changes for the same physical device. */
136
+ private lifecycleOperations;
135
137
  constructor(options: TransportOptions);
136
138
  init(logger: any, emitter: EventEmitter): void;
137
139
  configure(signedData: any): void;
@@ -153,14 +155,18 @@ declare class ReactNativeBleTransport {
153
155
  uuid: string;
154
156
  protocolType: ProtocolType;
155
157
  }>;
158
+ private acquireUnlocked;
156
159
  _monitorCharacteristic(characteristic: Characteristic, uuid: string, monitorToken: number, notifyTransactionId: string): Subscription;
157
160
  release(uuid: string, onclose?: boolean): Promise<boolean>;
161
+ private releaseUnlocked;
158
162
  private releaseNative;
159
163
  post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
160
164
  call(uuid: string, name: string, data: Record<string, unknown>, options?: TransportCallOptions): Promise<transport.MessageFromOneKey>;
161
165
  private callProtocolV1;
162
166
  stop(): void;
163
167
  disconnect(session: string): Promise<void>;
168
+ private disconnectUnlocked;
169
+ private runLifecycleOperation;
164
170
  cancel(): void;
165
171
  /** Run a native connect under the JS backstop budget. */
166
172
  private connectWithTimeout;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -434,6 +434,7 @@ class ReactNativeBleTransport {
434
434
  this.androidHighPriorityDevices = new Set();
435
435
  this.androidPriorityResetTimers = new Map();
436
436
  this.nextMonitorToken = 1;
437
+ this.lifecycleOperations = new Map();
437
438
  this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
438
439
  }
439
440
  init(logger, emitter) {
@@ -791,12 +792,18 @@ class ReactNativeBleTransport {
791
792
  });
792
793
  }
793
794
  acquire(input) {
794
- var _a, _b;
795
795
  return __awaiter(this, void 0, void 0, function* () {
796
- const { uuid, forceCleanRunPromise, expectedProtocol } = input;
796
+ const { uuid } = input;
797
797
  if (!uuid) {
798
798
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleRequiredUUID);
799
799
  }
800
+ return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
801
+ });
802
+ }
803
+ acquireUnlocked(input) {
804
+ var _a, _b;
805
+ return __awaiter(this, void 0, void 0, function* () {
806
+ const { uuid, forceCleanRunPromise, expectedProtocol } = input;
800
807
  const cachedTransport = transportCache[uuid];
801
808
  if (cachedTransport) {
802
809
  const cachedProtocol = this.deviceProtocol.get(uuid);
@@ -808,7 +815,7 @@ class ReactNativeBleTransport {
808
815
  return { uuid, protocolType: cachedProtocol };
809
816
  }
810
817
  Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
811
- yield this.release(uuid, true);
818
+ yield this.releaseUnlocked(uuid, true);
812
819
  }
813
820
  let device = null;
814
821
  if (forceCleanRunPromise && this.runPromise) {
@@ -909,7 +916,7 @@ class ReactNativeBleTransport {
909
916
  const protocolHint = expectedProtocol
910
917
  ? undefined
911
918
  : (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
912
- yield this.release(uuid, true);
919
+ yield this.releaseUnlocked(uuid, true);
913
920
  if (protocolHint) {
914
921
  this.deviceProtocolHints.set(uuid, protocolHint);
915
922
  }
@@ -929,7 +936,7 @@ class ReactNativeBleTransport {
929
936
  return { uuid, protocolType };
930
937
  }
931
938
  catch (error) {
932
- yield this.release(uuid, true);
939
+ yield this.releaseUnlocked(uuid, true);
933
940
  throw error;
934
941
  }
935
942
  });
@@ -1040,6 +1047,11 @@ class ReactNativeBleTransport {
1040
1047
  return subscription;
1041
1048
  }
1042
1049
  release(uuid, onclose = false) {
1050
+ return __awaiter(this, void 0, void 0, function* () {
1051
+ return this.runLifecycleOperation(uuid, () => this.releaseUnlocked(uuid, onclose));
1052
+ });
1053
+ }
1054
+ releaseUnlocked(uuid, onclose = false) {
1043
1055
  return __awaiter(this, void 0, void 0, function* () {
1044
1056
  yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
1045
1057
  return this.releaseNative(uuid, onclose);
@@ -1331,6 +1343,11 @@ class ReactNativeBleTransport {
1331
1343
  this.stopped = true;
1332
1344
  }
1333
1345
  disconnect(session) {
1346
+ return __awaiter(this, void 0, void 0, function* () {
1347
+ return this.runLifecycleOperation(session, () => this.disconnectUnlocked(session));
1348
+ });
1349
+ }
1350
+ disconnectUnlocked(session) {
1334
1351
  var _a, _b, _c, _d, _e;
1335
1352
  return __awaiter(this, void 0, void 0, function* () {
1336
1353
  yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
@@ -1400,6 +1417,28 @@ class ReactNativeBleTransport {
1400
1417
  yield new Promise(resolve => setTimeout(() => resolve(), 100));
1401
1418
  });
1402
1419
  }
1420
+ runLifecycleOperation(uuid, operation) {
1421
+ var _a;
1422
+ return __awaiter(this, void 0, void 0, function* () {
1423
+ const previousOperation = (_a = this.lifecycleOperations.get(uuid)) !== null && _a !== void 0 ? _a : Promise.resolve();
1424
+ let completeOperation;
1425
+ const operationGate = new Promise(resolve => {
1426
+ completeOperation = resolve;
1427
+ });
1428
+ const operationTail = previousOperation.catch(() => undefined).then(() => operationGate);
1429
+ this.lifecycleOperations.set(uuid, operationTail);
1430
+ yield previousOperation.catch(() => undefined);
1431
+ try {
1432
+ return yield operation();
1433
+ }
1434
+ finally {
1435
+ completeOperation();
1436
+ if (this.lifecycleOperations.get(uuid) === operationTail) {
1437
+ this.lifecycleOperations.delete(uuid);
1438
+ }
1439
+ }
1440
+ });
1441
+ }
1403
1442
  cancel() {
1404
1443
  Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
1405
1444
  if (this.runPromise) ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-react-native",
3
- "version": "1.2.0-alpha.129",
3
+ "version": "1.2.0-alpha.130",
4
4
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -20,11 +20,11 @@
20
20
  "lint:fix": "eslint . --fix"
21
21
  },
22
22
  "dependencies": {
23
- "@onekeyfe/hd-core": "1.2.0-alpha.129",
24
- "@onekeyfe/hd-shared": "1.2.0-alpha.129",
25
- "@onekeyfe/hd-transport": "1.2.0-alpha.129",
23
+ "@onekeyfe/hd-core": "1.2.0-alpha.130",
24
+ "@onekeyfe/hd-shared": "1.2.0-alpha.130",
25
+ "@onekeyfe/hd-transport": "1.2.0-alpha.130",
26
26
  "@onekeyfe/react-native-ble-utils": "^0.1.6",
27
27
  "react-native-ble-plx": "3.5.1"
28
28
  },
29
- "gitHead": "d996758fef2d61a868b1989efcce1f04c8ef5e22"
29
+ "gitHead": "287003096bc4df3a5824f2bea77e50f7fdc20565"
30
30
  }
@@ -420,6 +420,43 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
420
420
  await transport.release(uuid, true);
421
421
  });
422
422
 
423
+ test('waits for an in-flight release before reacquiring the same device', async () => {
424
+ const { transport, uuid } = createHarness();
425
+ await transport.acquire({ uuid, expectedProtocol: 'V2' });
426
+ const releaseGate = createDeferred<void>();
427
+ const releaseStarted = createDeferred<void>();
428
+ const { protocolV2Links } = transport as any;
429
+ const invalidateLink = protocolV2Links.invalidateLink.bind(protocolV2Links);
430
+ jest
431
+ .spyOn(protocolV2Links, 'invalidateLink')
432
+ .mockImplementationOnce(async (...args: unknown[]) => {
433
+ releaseStarted.resolve();
434
+ await releaseGate.promise;
435
+ return invalidateLink(...args);
436
+ });
437
+
438
+ const release = transport.release(uuid, true);
439
+ await releaseStarted.promise;
440
+ let reacquired = false;
441
+ const acquire = transport.acquire({ uuid, expectedProtocol: 'V2' }).then(result => {
442
+ reacquired = true;
443
+ return result;
444
+ });
445
+
446
+ await Promise.resolve();
447
+ expect(reacquired).toBe(false);
448
+
449
+ releaseGate.resolve();
450
+ await release;
451
+ await expect(acquire).resolves.toEqual({ uuid, protocolType: 'V2' });
452
+ await expect(transport.call(uuid, 'Ping', { message: 'after-release' })).resolves.toMatchObject(
453
+ {
454
+ type: 'Success',
455
+ message: { message: 'ok' },
456
+ }
457
+ );
458
+ });
459
+
423
460
  test('falls back to the other active probe on iOS when protocol metadata is absent', async () => {
424
461
  const { transport, uuid } = createHarness({ deviceName: 'OneKey' });
425
462
  const probeProtocolV1 = jest
package/src/index.ts CHANGED
@@ -422,6 +422,9 @@ export default class ReactNativeBleTransport {
422
422
 
423
423
  private nextMonitorToken = 1;
424
424
 
425
+ /** Serializes transport lifecycle changes for the same physical device. */
426
+ private lifecycleOperations: Map<string, Promise<void>> = new Map();
427
+
425
428
  constructor(options: TransportOptions) {
426
429
  this.scanTimeout = options.scanTimeout ?? DEVICE_SCAN_TIMEOUT_MS;
427
430
  }
@@ -860,12 +863,18 @@ export default class ReactNativeBleTransport {
860
863
  }
861
864
 
862
865
  async acquire(input: BleAcquireInput) {
863
- const { uuid, forceCleanRunPromise, expectedProtocol } = input;
866
+ const { uuid } = input;
864
867
 
865
868
  if (!uuid) {
866
869
  throw ERRORS.TypedError(HardwareErrorCode.BleRequiredUUID);
867
870
  }
868
871
 
872
+ return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
873
+ }
874
+
875
+ private async acquireUnlocked(input: BleAcquireInput) {
876
+ const { uuid, forceCleanRunPromise, expectedProtocol } = input;
877
+
869
878
  const cachedTransport = transportCache[uuid];
870
879
  if (cachedTransport) {
871
880
  const cachedProtocol = this.deviceProtocol.get(uuid);
@@ -884,7 +893,7 @@ export default class ReactNativeBleTransport {
884
893
  * connection, clean it up before creating a new transport instance.
885
894
  */
886
895
  Log?.debug('transport not reusable, will release: ', uuid);
887
- await this.release(uuid, true);
896
+ await this.releaseUnlocked(uuid, true);
888
897
  }
889
898
 
890
899
  let device: Device | null = null;
@@ -1010,7 +1019,7 @@ export default class ReactNativeBleTransport {
1010
1019
  inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
1011
1020
 
1012
1021
  // release transport before new transport instance
1013
- await this.release(uuid, true);
1022
+ await this.releaseUnlocked(uuid, true);
1014
1023
  if (protocolHint) {
1015
1024
  this.deviceProtocolHints.set(uuid, protocolHint);
1016
1025
  }
@@ -1036,7 +1045,7 @@ export default class ReactNativeBleTransport {
1036
1045
  this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
1037
1046
  return { uuid, protocolType };
1038
1047
  } catch (error) {
1039
- await this.release(uuid, true);
1048
+ await this.releaseUnlocked(uuid, true);
1040
1049
  throw error;
1041
1050
  }
1042
1051
  }
@@ -1181,6 +1190,10 @@ export default class ReactNativeBleTransport {
1181
1190
  }
1182
1191
 
1183
1192
  async release(uuid: string, onclose = false) {
1193
+ return this.runLifecycleOperation(uuid, () => this.releaseUnlocked(uuid, onclose));
1194
+ }
1195
+
1196
+ private async releaseUnlocked(uuid: string, onclose = false) {
1184
1197
  await this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
1185
1198
  return this.releaseNative(uuid, onclose);
1186
1199
  }
@@ -1552,6 +1565,10 @@ export default class ReactNativeBleTransport {
1552
1565
  }
1553
1566
 
1554
1567
  async disconnect(session: string) {
1568
+ return this.runLifecycleOperation(session, () => this.disconnectUnlocked(session));
1569
+ }
1570
+
1571
+ private async disconnectUnlocked(session: string) {
1555
1572
  await this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
1556
1573
  const transport = transportCache[session];
1557
1574
  const monitorToken = transport?.monitorToken ?? this.monitorTokens.get(session);
@@ -1632,6 +1649,26 @@ export default class ReactNativeBleTransport {
1632
1649
  await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
1633
1650
  }
1634
1651
 
1652
+ private async runLifecycleOperation<T>(uuid: string, operation: () => Promise<T>): Promise<T> {
1653
+ const previousOperation = this.lifecycleOperations.get(uuid) ?? Promise.resolve();
1654
+ let completeOperation!: () => void;
1655
+ const operationGate = new Promise<void>(resolve => {
1656
+ completeOperation = resolve;
1657
+ });
1658
+ const operationTail = previousOperation.catch(() => undefined).then(() => operationGate);
1659
+ this.lifecycleOperations.set(uuid, operationTail);
1660
+
1661
+ await previousOperation.catch(() => undefined);
1662
+ try {
1663
+ return await operation();
1664
+ } finally {
1665
+ completeOperation();
1666
+ if (this.lifecycleOperations.get(uuid) === operationTail) {
1667
+ this.lifecycleOperations.delete(uuid);
1668
+ }
1669
+ }
1670
+ }
1671
+
1635
1672
  cancel() {
1636
1673
  Log?.debug('transport-react-native transport cancel');
1637
1674
  if (this.runPromise) {