@onekeyfe/hd-transport-react-native 1.2.0-alpha.75 → 1.2.0-alpha.76
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/BleTransport.d.ts.map +1 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +298 -44
- package/jest.config.js +5 -0
- package/package.json +5 -5
- package/src/BleTransport.ts +9 -6
- package/src/__tests__/BleTransport.test.ts +24 -3
- package/src/__tests__/connectTimeout.test.ts +280 -0
- package/src/__tests__/protocolReprobe.test.ts +132 -0
- package/src/__tests__/protocolV1SchemaFixture.ts +39 -0
- package/src/__tests__/protocolV2Link.test.ts +35 -5
- package/src/__tests__/staleCallTimeout.test.ts +210 -0
- package/src/__tests__/writePacketTimeout.test.ts +305 -0
- package/src/index.ts +449 -39
package/dist/index.js
CHANGED
|
@@ -216,10 +216,6 @@ class BleTransport {
|
|
|
216
216
|
}
|
|
217
217
|
writeWithRetry(data) {
|
|
218
218
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
if (reactNative.Platform.OS === 'ios' && this.writeCharacteristic.isWritableWithResponse) {
|
|
220
|
-
yield this.writeCharacteristic.writeWithResponse(data);
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
219
|
yield this.writeCharacteristic.writeWithoutResponse(data);
|
|
224
220
|
});
|
|
225
221
|
}
|
|
@@ -280,6 +276,12 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
280
276
|
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
281
277
|
const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
|
|
282
278
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
279
|
+
const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
280
|
+
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
281
|
+
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
282
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
283
|
+
error.message.startsWith(WEDGED_WRITE_MESSAGE);
|
|
284
|
+
const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
283
285
|
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
284
286
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
285
287
|
const ANDROID_NOTIFY_READY_DELAY_MS = 300;
|
|
@@ -319,11 +321,24 @@ const ANDROID_REQUEST_MTU = 517;
|
|
|
319
321
|
const BLE_MTU_REFRESH_RETRY_DELAY_MS = 200;
|
|
320
322
|
const ANDROID_HIGH_PRIORITY_IDLE_MS = 1000;
|
|
321
323
|
const getRequestedBleMtu = () => reactNative.Platform.OS === 'android' ? ANDROID_REQUEST_MTU : IOS_REQUEST_MTU;
|
|
324
|
+
const BLE_NATIVE_CONNECT_TIMEOUT_MS = 3000;
|
|
322
325
|
const connectOptions = {
|
|
323
326
|
requestMTU: getRequestedBleMtu(),
|
|
324
|
-
timeout:
|
|
327
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
325
328
|
refreshGatt: 'OnConnected',
|
|
326
329
|
};
|
|
330
|
+
const fallbackConnectOptions = {
|
|
331
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
332
|
+
};
|
|
333
|
+
const BLE_CONNECT_TIMEOUT_MS = BLE_NATIVE_CONNECT_TIMEOUT_MS * 2 + 2000;
|
|
334
|
+
const BLE_GATT_SETUP_TIMEOUT_MS = 10000;
|
|
335
|
+
const PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = 3;
|
|
336
|
+
const BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
337
|
+
const CONNECT_TIMEOUT_MESSAGE = 'BLE connect timeout after';
|
|
338
|
+
const isConnectTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleConnectedError &&
|
|
339
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
340
|
+
error.message.startsWith(CONNECT_TIMEOUT_MESSAGE);
|
|
341
|
+
const isNativeOperationTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === reactNativeBlePlx.BleErrorCode.OperationTimedOut;
|
|
327
342
|
const tryToGetConfiguration = (device) => {
|
|
328
343
|
if (!device || !device.serviceUUIDs)
|
|
329
344
|
return null;
|
|
@@ -383,7 +398,12 @@ class ReactNativeBleTransport {
|
|
|
383
398
|
this.runPromiseDeviceId = null;
|
|
384
399
|
this.firmwareUploadWriteRecoveryIds = new Set();
|
|
385
400
|
this.deviceProtocol = new Map();
|
|
401
|
+
this.probingProtocols = new Map();
|
|
402
|
+
this.writeTimeoutCounts = new Map();
|
|
403
|
+
this.connectionSetupTimeoutCounts = new Map();
|
|
386
404
|
this.deviceProtocolHints = new Map();
|
|
405
|
+
this.sessionProtocols = new Map();
|
|
406
|
+
this.protocolReprobeFailures = new Map();
|
|
387
407
|
this.protocolV2Assemblers = new Map();
|
|
388
408
|
this.protocolV2FrameQueues = new Map();
|
|
389
409
|
this.protocolV2FramePromises = new Map();
|
|
@@ -578,19 +598,19 @@ class ReactNativeBleTransport {
|
|
|
578
598
|
const isConnected = yield device.isConnected().catch(() => false);
|
|
579
599
|
if (!isConnected) {
|
|
580
600
|
try {
|
|
581
|
-
device = yield device.connect(connectOptions);
|
|
601
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect(connectOptions));
|
|
582
602
|
}
|
|
583
603
|
catch (e) {
|
|
584
604
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
585
605
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
586
|
-
device = yield device.connect();
|
|
606
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect());
|
|
587
607
|
}
|
|
588
608
|
else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
589
609
|
throw e;
|
|
590
610
|
}
|
|
591
611
|
}
|
|
592
612
|
}
|
|
593
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
613
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, device);
|
|
594
614
|
transport.device = device;
|
|
595
615
|
transport.writeCharacteristic = writeCharacteristic;
|
|
596
616
|
transport.notifyCharacteristic = notifyCharacteristic;
|
|
@@ -727,7 +747,7 @@ class ReactNativeBleTransport {
|
|
|
727
747
|
}
|
|
728
748
|
installTransportForAcquire(uuid, device, characteristics) {
|
|
729
749
|
return __awaiter(this, void 0, void 0, function* () {
|
|
730
|
-
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.
|
|
750
|
+
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
|
|
731
751
|
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
732
752
|
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : undefined;
|
|
733
753
|
const monitorToken = this.nextMonitorToken;
|
|
@@ -834,14 +854,17 @@ class ReactNativeBleTransport {
|
|
|
834
854
|
if (!device) {
|
|
835
855
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
|
|
836
856
|
try {
|
|
837
|
-
device = yield blePlxManager.connectToDevice(uuid, connectOptions);
|
|
857
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, connectOptions));
|
|
838
858
|
}
|
|
839
859
|
catch (e) {
|
|
840
860
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
|
|
861
|
+
if (isConnectTimeoutError(e)) {
|
|
862
|
+
throw e;
|
|
863
|
+
}
|
|
841
864
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
842
865
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
843
866
|
Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
|
|
844
|
-
device = yield blePlxManager.connectToDevice(uuid);
|
|
867
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, fallbackConnectOptions));
|
|
845
868
|
}
|
|
846
869
|
else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
847
870
|
Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
|
|
@@ -857,23 +880,27 @@ class ReactNativeBleTransport {
|
|
|
857
880
|
}
|
|
858
881
|
if (!(yield device.isConnected())) {
|
|
859
882
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
|
|
883
|
+
const disconnectedDevice = device;
|
|
860
884
|
try {
|
|
861
|
-
device = yield
|
|
885
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(connectOptions));
|
|
862
886
|
}
|
|
863
887
|
catch (e) {
|
|
864
888
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
|
|
889
|
+
if (isConnectTimeoutError(e)) {
|
|
890
|
+
throw e;
|
|
891
|
+
}
|
|
865
892
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
866
893
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
867
894
|
Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
|
|
868
895
|
try {
|
|
869
|
-
device = yield
|
|
896
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
870
897
|
}
|
|
871
898
|
catch (e) {
|
|
872
899
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
|
|
873
900
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
874
901
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
875
|
-
yield
|
|
876
|
-
device = yield
|
|
902
|
+
yield disconnectedDevice.cancelConnection();
|
|
903
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
877
904
|
}
|
|
878
905
|
}
|
|
879
906
|
}
|
|
@@ -884,7 +911,7 @@ class ReactNativeBleTransport {
|
|
|
884
911
|
}
|
|
885
912
|
device = yield resolveNegotiatedMtu(device);
|
|
886
913
|
const acquiredDevice = device;
|
|
887
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
914
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
|
|
888
915
|
const protocolHint = expectedProtocol
|
|
889
916
|
? undefined
|
|
890
917
|
: (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
@@ -929,7 +956,7 @@ class ReactNativeBleTransport {
|
|
|
929
956
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
|
|
930
957
|
return;
|
|
931
958
|
}
|
|
932
|
-
if (this.
|
|
959
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
933
960
|
let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
934
961
|
if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
|
|
935
962
|
errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
@@ -980,7 +1007,7 @@ class ReactNativeBleTransport {
|
|
|
980
1007
|
}
|
|
981
1008
|
try {
|
|
982
1009
|
const data = buffer.Buffer.from(c.value, 'base64');
|
|
983
|
-
const protocol = this.
|
|
1010
|
+
const protocol = this.getActiveProtocol(uuid);
|
|
984
1011
|
if (!protocol) {
|
|
985
1012
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
|
|
986
1013
|
return;
|
|
@@ -1008,7 +1035,7 @@ class ReactNativeBleTransport {
|
|
|
1008
1035
|
catch (error) {
|
|
1009
1036
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
1010
1037
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1011
|
-
if (this.
|
|
1038
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
1012
1039
|
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
1013
1040
|
}
|
|
1014
1041
|
else if (this.runPromiseDeviceId === uuid) {
|
|
@@ -1066,6 +1093,7 @@ class ReactNativeBleTransport {
|
|
|
1066
1093
|
}
|
|
1067
1094
|
this.protocolV2HighVolumeLogSignatures.delete(uuid);
|
|
1068
1095
|
this.deviceProtocol.delete(uuid);
|
|
1096
|
+
this.probingProtocols.delete(uuid);
|
|
1069
1097
|
(_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
|
|
1070
1098
|
this.protocolV2Assemblers.delete(uuid);
|
|
1071
1099
|
this.resetProtocolV2Frames(uuid);
|
|
@@ -1114,8 +1142,19 @@ class ReactNativeBleTransport {
|
|
|
1114
1142
|
const transport = this.getCachedTransport(uuid);
|
|
1115
1143
|
const runPromise = hdShared.createDeferred();
|
|
1116
1144
|
runPromise.promise.catch(() => undefined);
|
|
1145
|
+
const supersededRunPromise = this.runPromise;
|
|
1146
|
+
if (supersededRunPromise) {
|
|
1147
|
+
supersededRunPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
1148
|
+
}
|
|
1117
1149
|
this.runPromise = runPromise;
|
|
1118
1150
|
this.runPromiseDeviceId = uuid;
|
|
1151
|
+
const releaseOwnershipIfCurrent = () => {
|
|
1152
|
+
if (this.runPromise === runPromise) {
|
|
1153
|
+
this.runPromise = null;
|
|
1154
|
+
this.runPromiseDeviceId = null;
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
const isCurrentOwner = () => this.runPromise === runPromise;
|
|
1119
1158
|
const messages = this._messages;
|
|
1120
1159
|
const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
|
|
1121
1160
|
let timeout;
|
|
@@ -1136,6 +1175,9 @@ class ReactNativeBleTransport {
|
|
|
1136
1175
|
}
|
|
1137
1176
|
catch (e) {
|
|
1138
1177
|
onError(e);
|
|
1178
|
+
if (isWedgedWriteError(e)) {
|
|
1179
|
+
throw e;
|
|
1180
|
+
}
|
|
1139
1181
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1140
1182
|
}
|
|
1141
1183
|
}
|
|
@@ -1163,6 +1205,9 @@ class ReactNativeBleTransport {
|
|
|
1163
1205
|
}
|
|
1164
1206
|
catch (e) {
|
|
1165
1207
|
onError(e);
|
|
1208
|
+
if (isWedgedWriteError(e)) {
|
|
1209
|
+
throw e;
|
|
1210
|
+
}
|
|
1166
1211
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1167
1212
|
}
|
|
1168
1213
|
}
|
|
@@ -1173,8 +1218,8 @@ class ReactNativeBleTransport {
|
|
|
1173
1218
|
});
|
|
1174
1219
|
}
|
|
1175
1220
|
if (name === 'EmmcFileWrite') {
|
|
1176
|
-
yield writeChunkedData(buffers, data => transport.writeWithRetry(
|
|
1177
|
-
|
|
1221
|
+
yield writeChunkedData(buffers, data => this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner), e => {
|
|
1222
|
+
releaseOwnershipIfCurrent();
|
|
1178
1223
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1179
1224
|
});
|
|
1180
1225
|
}
|
|
@@ -1190,7 +1235,7 @@ class ReactNativeBleTransport {
|
|
|
1190
1235
|
let attempt = 0;
|
|
1191
1236
|
while (true) {
|
|
1192
1237
|
try {
|
|
1193
|
-
yield transport.writeWithRetry(
|
|
1238
|
+
yield this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner);
|
|
1194
1239
|
return;
|
|
1195
1240
|
}
|
|
1196
1241
|
catch (error) {
|
|
@@ -1209,7 +1254,7 @@ class ReactNativeBleTransport {
|
|
|
1209
1254
|
}
|
|
1210
1255
|
}
|
|
1211
1256
|
}), e => {
|
|
1212
|
-
|
|
1257
|
+
releaseOwnershipIfCurrent();
|
|
1213
1258
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1214
1259
|
});
|
|
1215
1260
|
}
|
|
@@ -1218,16 +1263,16 @@ class ReactNativeBleTransport {
|
|
|
1218
1263
|
const outData = o.toString('base64');
|
|
1219
1264
|
try {
|
|
1220
1265
|
const shouldUseWriteWithResponse = reactNative.Platform.OS === 'ios' && transport.writeCharacteristic.isWritableWithResponse;
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
else {
|
|
1225
|
-
yield transport.writeCharacteristic.writeWithoutResponse(outData);
|
|
1226
|
-
}
|
|
1266
|
+
yield this.writeBlePacket(uuid, outData, payload => shouldUseWriteWithResponse
|
|
1267
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1268
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
|
|
1227
1269
|
}
|
|
1228
1270
|
catch (e) {
|
|
1229
1271
|
Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
|
|
1230
|
-
|
|
1272
|
+
releaseOwnershipIfCurrent();
|
|
1273
|
+
if (isWedgedWriteError(e)) {
|
|
1274
|
+
throw e;
|
|
1275
|
+
}
|
|
1231
1276
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
|
|
1232
1277
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
|
|
1233
1278
|
}
|
|
@@ -1267,7 +1312,9 @@ class ReactNativeBleTransport {
|
|
|
1267
1312
|
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1268
1313
|
}
|
|
1269
1314
|
const isProbeTimeout = name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS;
|
|
1315
|
+
const isStaleCall = this.runPromise !== runPromise;
|
|
1270
1316
|
if (!isProbeTimeout &&
|
|
1317
|
+
!isStaleCall &&
|
|
1271
1318
|
(e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError) {
|
|
1272
1319
|
yield this.disconnect(uuid);
|
|
1273
1320
|
}
|
|
@@ -1338,7 +1385,10 @@ class ReactNativeBleTransport {
|
|
|
1338
1385
|
delete transportCache[session];
|
|
1339
1386
|
}
|
|
1340
1387
|
this.deviceProtocol.delete(session);
|
|
1388
|
+
this.probingProtocols.delete(session);
|
|
1341
1389
|
this.deviceProtocolHints.delete(session);
|
|
1390
|
+
this.sessionProtocols.delete(session);
|
|
1391
|
+
this.protocolReprobeFailures.delete(session);
|
|
1342
1392
|
this.protocolV2Assemblers.delete(session);
|
|
1343
1393
|
this.resetProtocolV2Frames(session);
|
|
1344
1394
|
try {
|
|
@@ -1359,6 +1409,91 @@ class ReactNativeBleTransport {
|
|
|
1359
1409
|
this.runPromise = null;
|
|
1360
1410
|
this.runPromiseDeviceId = null;
|
|
1361
1411
|
}
|
|
1412
|
+
connectWithTimeout(uuid, connect) {
|
|
1413
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1414
|
+
let timer;
|
|
1415
|
+
let timedOut = false;
|
|
1416
|
+
const pending = connect();
|
|
1417
|
+
pending.catch(() => undefined);
|
|
1418
|
+
try {
|
|
1419
|
+
const result = yield Promise.race([
|
|
1420
|
+
pending,
|
|
1421
|
+
new Promise((_, reject) => {
|
|
1422
|
+
timer = setTimeout(() => {
|
|
1423
|
+
timedOut = true;
|
|
1424
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE connect timeout after ${BLE_CONNECT_TIMEOUT_MS}ms for ${uuid}`));
|
|
1425
|
+
}, BLE_CONNECT_TIMEOUT_MS);
|
|
1426
|
+
}),
|
|
1427
|
+
]);
|
|
1428
|
+
return result;
|
|
1429
|
+
}
|
|
1430
|
+
catch (error) {
|
|
1431
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1432
|
+
this.abandonStalledConnection(uuid, timedOut ? 'connect-backstop' : 'connect-native');
|
|
1433
|
+
}
|
|
1434
|
+
throw error;
|
|
1435
|
+
}
|
|
1436
|
+
finally {
|
|
1437
|
+
if (timer)
|
|
1438
|
+
clearTimeout(timer);
|
|
1439
|
+
}
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
resolveCharacteristicsWithTimeout(uuid, device) {
|
|
1443
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1444
|
+
let timer;
|
|
1445
|
+
let timedOut = false;
|
|
1446
|
+
const pending = this.resolveCharacteristics(device);
|
|
1447
|
+
pending.catch(() => undefined);
|
|
1448
|
+
try {
|
|
1449
|
+
const result = yield Promise.race([
|
|
1450
|
+
pending,
|
|
1451
|
+
new Promise((_, reject) => {
|
|
1452
|
+
timer = setTimeout(() => {
|
|
1453
|
+
timedOut = true;
|
|
1454
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE GATT setup timeout after ${BLE_GATT_SETUP_TIMEOUT_MS}ms for ${uuid}`));
|
|
1455
|
+
}, BLE_GATT_SETUP_TIMEOUT_MS);
|
|
1456
|
+
}),
|
|
1457
|
+
]);
|
|
1458
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1459
|
+
return result;
|
|
1460
|
+
}
|
|
1461
|
+
catch (error) {
|
|
1462
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1463
|
+
this.abandonStalledConnection(uuid, timedOut ? 'gatt-backstop' : 'gatt-native');
|
|
1464
|
+
}
|
|
1465
|
+
throw error;
|
|
1466
|
+
}
|
|
1467
|
+
finally {
|
|
1468
|
+
if (timer)
|
|
1469
|
+
clearTimeout(timer);
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
abandonStalledConnection(uuid, stage) {
|
|
1474
|
+
var _a, _b;
|
|
1475
|
+
const timeouts = ((_a = this.connectionSetupTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1476
|
+
this.connectionSetupTimeoutCounts.set(uuid, timeouts);
|
|
1477
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup timed out:', uuid, {
|
|
1478
|
+
stage,
|
|
1479
|
+
setupTimeoutsSinceSuccess: timeouts,
|
|
1480
|
+
});
|
|
1481
|
+
(_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(uuid).catch(() => {
|
|
1482
|
+
});
|
|
1483
|
+
const stalled = transportCache[uuid];
|
|
1484
|
+
if (stalled) {
|
|
1485
|
+
delete transportCache[uuid];
|
|
1486
|
+
}
|
|
1487
|
+
this.deviceProtocol.delete(uuid);
|
|
1488
|
+
this.probingProtocols.delete(uuid);
|
|
1489
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1490
|
+
this.resetProtocolV2Frames(uuid);
|
|
1491
|
+
if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1492
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup wedged repeatedly, resetting BLE manager');
|
|
1493
|
+
this.resetPlxManager();
|
|
1494
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1362
1497
|
getCachedTransport(uuid) {
|
|
1363
1498
|
const transport = transportCache[uuid];
|
|
1364
1499
|
if (!transport) {
|
|
@@ -1366,6 +1501,82 @@ class ReactNativeBleTransport {
|
|
|
1366
1501
|
}
|
|
1367
1502
|
return transport;
|
|
1368
1503
|
}
|
|
1504
|
+
writeBlePacket(uuid, data, write, isCurrentOwner) {
|
|
1505
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1506
|
+
let timer;
|
|
1507
|
+
let timedOut = false;
|
|
1508
|
+
try {
|
|
1509
|
+
yield Promise.race([
|
|
1510
|
+
write(data),
|
|
1511
|
+
new Promise((_, reject) => {
|
|
1512
|
+
timer = setTimeout(() => {
|
|
1513
|
+
timedOut = true;
|
|
1514
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, `BLE write timeout after ${BLE_WRITE_PACKET_TIMEOUT_MS}ms`));
|
|
1515
|
+
}, BLE_WRITE_PACKET_TIMEOUT_MS);
|
|
1516
|
+
}),
|
|
1517
|
+
]);
|
|
1518
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1519
|
+
}
|
|
1520
|
+
catch (error) {
|
|
1521
|
+
if (timedOut) {
|
|
1522
|
+
if (isCurrentOwner && !isCurrentOwner()) {
|
|
1523
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] stale BLE write timed out, link kept:', uuid);
|
|
1524
|
+
}
|
|
1525
|
+
else {
|
|
1526
|
+
this.tearDownWedgedLink(uuid);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
throw error;
|
|
1530
|
+
}
|
|
1531
|
+
finally {
|
|
1532
|
+
if (timer)
|
|
1533
|
+
clearTimeout(timer);
|
|
1534
|
+
}
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
tearDownWedgedLink(uuid) {
|
|
1538
|
+
var _a;
|
|
1539
|
+
const timeouts = ((_a = this.writeTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1540
|
+
this.writeTimeoutCounts.set(uuid, timeouts);
|
|
1541
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE write timed out, tearing down link:', uuid, {
|
|
1542
|
+
consecutiveWriteTimeouts: timeouts,
|
|
1543
|
+
});
|
|
1544
|
+
const wedged = transportCache[uuid];
|
|
1545
|
+
this.disconnect(uuid).catch(error => {
|
|
1546
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] wedged link teardown failed (ignored):', error);
|
|
1547
|
+
});
|
|
1548
|
+
if (wedged && transportCache[uuid] === wedged) {
|
|
1549
|
+
delete transportCache[uuid];
|
|
1550
|
+
}
|
|
1551
|
+
this.deviceProtocol.delete(uuid);
|
|
1552
|
+
this.probingProtocols.delete(uuid);
|
|
1553
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1554
|
+
this.resetProtocolV2Frames(uuid);
|
|
1555
|
+
if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1556
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE writes wedged repeatedly, resetting BLE manager');
|
|
1557
|
+
this.resetPlxManager();
|
|
1558
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
resetPlxManager() {
|
|
1562
|
+
const manager = this.blePlxManager;
|
|
1563
|
+
this.blePlxManager = undefined;
|
|
1564
|
+
Object.keys(transportCache).forEach(key => {
|
|
1565
|
+
delete transportCache[key];
|
|
1566
|
+
});
|
|
1567
|
+
this.deviceProtocol.clear();
|
|
1568
|
+
this.probingProtocols.clear();
|
|
1569
|
+
this.sessionProtocols.clear();
|
|
1570
|
+
this.protocolReprobeFailures.clear();
|
|
1571
|
+
this.monitorTokens.clear();
|
|
1572
|
+
this.protocolV2Assemblers.clear();
|
|
1573
|
+
try {
|
|
1574
|
+
manager === null || manager === void 0 ? void 0 : manager.destroy();
|
|
1575
|
+
}
|
|
1576
|
+
catch (error) {
|
|
1577
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1369
1580
|
createProtocolMismatchError(expected) {
|
|
1370
1581
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1371
1582
|
}
|
|
@@ -1373,11 +1584,19 @@ class ReactNativeBleTransport {
|
|
|
1373
1584
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
1374
1585
|
}
|
|
1375
1586
|
clearProbeProtocol(uuid, protocol) {
|
|
1587
|
+
if (this.probingProtocols.get(uuid) === protocol) {
|
|
1588
|
+
this.probingProtocols.delete(uuid);
|
|
1589
|
+
}
|
|
1376
1590
|
if (this.deviceProtocol.get(uuid) === protocol) {
|
|
1377
1591
|
this.deviceProtocol.delete(uuid);
|
|
1378
1592
|
}
|
|
1379
1593
|
}
|
|
1594
|
+
getActiveProtocol(uuid) {
|
|
1595
|
+
var _a;
|
|
1596
|
+
return (_a = this.deviceProtocol.get(uuid)) !== null && _a !== void 0 ? _a : this.probingProtocols.get(uuid);
|
|
1597
|
+
}
|
|
1380
1598
|
detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
|
|
1599
|
+
var _a;
|
|
1381
1600
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1382
1601
|
if (reactNative.Platform.OS === 'ios' && expectedProtocol) {
|
|
1383
1602
|
this.deviceProtocol.set(uuid, expectedProtocol);
|
|
@@ -1391,6 +1610,7 @@ class ReactNativeBleTransport {
|
|
|
1391
1610
|
if (expectedProtocol === 'V1') {
|
|
1392
1611
|
if (yield this.probeProtocolV1(uuid)) {
|
|
1393
1612
|
this.deviceProtocol.set(uuid, 'V1');
|
|
1613
|
+
this.sessionProtocols.set(uuid, 'V1');
|
|
1394
1614
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1395
1615
|
deviceId: uuid,
|
|
1396
1616
|
protocol: 'V1',
|
|
@@ -1403,6 +1623,7 @@ class ReactNativeBleTransport {
|
|
|
1403
1623
|
if (expectedProtocol === 'V2') {
|
|
1404
1624
|
if (yield this.probeProtocolV2(uuid)) {
|
|
1405
1625
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1626
|
+
this.sessionProtocols.set(uuid, 'V2');
|
|
1406
1627
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1407
1628
|
deviceId: uuid,
|
|
1408
1629
|
protocol: 'V2',
|
|
@@ -1412,7 +1633,13 @@ class ReactNativeBleTransport {
|
|
|
1412
1633
|
}
|
|
1413
1634
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1414
1635
|
}
|
|
1415
|
-
const
|
|
1636
|
+
const sessionProtocol = this.sessionProtocols.get(uuid);
|
|
1637
|
+
const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1638
|
+
const fullProbeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1639
|
+
const trustSessionProtocol = sessionProtocol !== undefined &&
|
|
1640
|
+
!protocolHint &&
|
|
1641
|
+
reprobeFailures < PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1642
|
+
const probeOrder = trustSessionProtocol ? [sessionProtocol] : fullProbeOrder;
|
|
1416
1643
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
1417
1644
|
const protocol = probeOrder[i];
|
|
1418
1645
|
if (i > 0) {
|
|
@@ -1427,6 +1654,8 @@ class ReactNativeBleTransport {
|
|
|
1427
1654
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1428
1655
|
if (detected) {
|
|
1429
1656
|
this.deviceProtocol.set(uuid, protocol);
|
|
1657
|
+
this.sessionProtocols.set(uuid, protocol);
|
|
1658
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1430
1659
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1431
1660
|
deviceId: uuid,
|
|
1432
1661
|
protocol,
|
|
@@ -1435,7 +1664,14 @@ class ReactNativeBleTransport {
|
|
|
1435
1664
|
return protocol;
|
|
1436
1665
|
}
|
|
1437
1666
|
}
|
|
1667
|
+
if (trustSessionProtocol) {
|
|
1668
|
+
this.protocolReprobeFailures.set(uuid, reprobeFailures + 1);
|
|
1669
|
+
}
|
|
1670
|
+
else {
|
|
1671
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1672
|
+
}
|
|
1438
1673
|
this.deviceProtocol.delete(uuid);
|
|
1674
|
+
this.probingProtocols.delete(uuid);
|
|
1439
1675
|
throw this.createProtocolDetectionError();
|
|
1440
1676
|
});
|
|
1441
1677
|
}
|
|
@@ -1487,13 +1723,17 @@ class ReactNativeBleTransport {
|
|
|
1487
1723
|
return false;
|
|
1488
1724
|
}
|
|
1489
1725
|
try {
|
|
1490
|
-
this.
|
|
1726
|
+
this.probingProtocols.set(uuid, 'V1');
|
|
1491
1727
|
yield this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
|
|
1728
|
+
this.probingProtocols.delete(uuid);
|
|
1492
1729
|
return true;
|
|
1493
1730
|
}
|
|
1494
1731
|
catch (error) {
|
|
1495
1732
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1496
1733
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
|
|
1734
|
+
if (isWedgedWriteError(error)) {
|
|
1735
|
+
throw error;
|
|
1736
|
+
}
|
|
1497
1737
|
return false;
|
|
1498
1738
|
}
|
|
1499
1739
|
});
|
|
@@ -1504,7 +1744,7 @@ class ReactNativeBleTransport {
|
|
|
1504
1744
|
if (!this._messages || !this._messagesV2) {
|
|
1505
1745
|
return false;
|
|
1506
1746
|
}
|
|
1507
|
-
this.
|
|
1747
|
+
this.probingProtocols.set(uuid, 'V2');
|
|
1508
1748
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1509
1749
|
const detected = yield transport.probeProtocolV2({
|
|
1510
1750
|
call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
|
|
@@ -1520,6 +1760,9 @@ class ReactNativeBleTransport {
|
|
|
1520
1760
|
if (!detected) {
|
|
1521
1761
|
this.clearProbeProtocol(uuid, 'V2');
|
|
1522
1762
|
}
|
|
1763
|
+
else {
|
|
1764
|
+
this.probingProtocols.delete(uuid);
|
|
1765
|
+
}
|
|
1523
1766
|
return detected;
|
|
1524
1767
|
});
|
|
1525
1768
|
}
|
|
@@ -1591,7 +1834,7 @@ class ReactNativeBleTransport {
|
|
|
1591
1834
|
}
|
|
1592
1835
|
});
|
|
1593
1836
|
}
|
|
1594
|
-
writeProtocolV2Packet(transport, base64, context, assertCurrentGeneration) {
|
|
1837
|
+
writeProtocolV2Packet(uuid, transport, base64, context, assertCurrentGeneration) {
|
|
1595
1838
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1596
1839
|
const shouldUseWriteWithResponse = shouldWriteProtocolV2WithResponse({
|
|
1597
1840
|
platform: reactNative.Platform.OS,
|
|
@@ -1606,12 +1849,17 @@ class ReactNativeBleTransport {
|
|
|
1606
1849
|
throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
|
|
1607
1850
|
}
|
|
1608
1851
|
try {
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1852
|
+
yield this.writeBlePacket(uuid, base64, payload => shouldUseWriteWithResponse
|
|
1853
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1854
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), () => {
|
|
1855
|
+
try {
|
|
1856
|
+
assertCurrentGeneration();
|
|
1857
|
+
return !context.signal.aborted;
|
|
1858
|
+
}
|
|
1859
|
+
catch (_a) {
|
|
1860
|
+
return false;
|
|
1861
|
+
}
|
|
1862
|
+
});
|
|
1615
1863
|
assertCurrentGeneration();
|
|
1616
1864
|
return;
|
|
1617
1865
|
}
|
|
@@ -1632,7 +1880,7 @@ class ReactNativeBleTransport {
|
|
|
1632
1880
|
}
|
|
1633
1881
|
});
|
|
1634
1882
|
}
|
|
1635
|
-
writeProtocolV2Frame(transport$1, frame, context, assertCurrentGeneration) {
|
|
1883
|
+
writeProtocolV2Frame(uuid, transport$1, frame, context, assertCurrentGeneration) {
|
|
1636
1884
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1637
1885
|
const tuning = getProtocolV2BleTuning();
|
|
1638
1886
|
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
@@ -1648,7 +1896,7 @@ class ReactNativeBleTransport {
|
|
|
1648
1896
|
signal: context.signal,
|
|
1649
1897
|
abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
|
|
1650
1898
|
wait: delay,
|
|
1651
|
-
writePacket: packet => this.writeProtocolV2Packet(transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1899
|
+
writePacket: packet => this.writeProtocolV2Packet(uuid, transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1652
1900
|
});
|
|
1653
1901
|
});
|
|
1654
1902
|
}
|
|
@@ -1802,7 +2050,7 @@ class ReactNativeBleTransport {
|
|
|
1802
2050
|
writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
|
|
1803
2051
|
assertCurrentGeneration();
|
|
1804
2052
|
const currentTransport = this.getCachedTransport(uuid);
|
|
1805
|
-
yield this.writeProtocolV2Frame(currentTransport, frame, context, assertCurrentGeneration);
|
|
2053
|
+
yield this.writeProtocolV2Frame(uuid, currentTransport, frame, context, assertCurrentGeneration);
|
|
1806
2054
|
}),
|
|
1807
2055
|
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1808
2056
|
assertCurrentGeneration();
|
|
@@ -1823,10 +2071,16 @@ class ReactNativeBleTransport {
|
|
|
1823
2071
|
};
|
|
1824
2072
|
}
|
|
1825
2073
|
getProtocolType(path) {
|
|
1826
|
-
return this.
|
|
2074
|
+
return this.getActiveProtocol(path);
|
|
1827
2075
|
}
|
|
1828
2076
|
}
|
|
1829
2077
|
|
|
2078
|
+
exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2079
|
+
exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
|
|
2080
|
+
exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
|
|
2081
|
+
exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
|
|
2082
|
+
exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2083
|
+
exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1830
2084
|
exports.configureProtocolV2BleTuning = configureProtocolV2BleTuning;
|
|
1831
2085
|
exports["default"] = ReactNativeBleTransport;
|
|
1832
2086
|
exports.getFirmwareUploadWriteRetryType = getFirmwareUploadWriteRetryType;
|
package/jest.config.js
CHANGED
|
@@ -2,4 +2,9 @@ module.exports = {
|
|
|
2
2
|
preset: '../../jest.config.js',
|
|
3
3
|
testEnvironment: 'node',
|
|
4
4
|
modulePathIgnorePatterns: ['node_modules', '<rootDir>/dist'],
|
|
5
|
+
moduleNameMapper: {
|
|
6
|
+
// The workspace symlinks resolve to prebuilt dist outputs that can lag behind src.
|
|
7
|
+
'^@onekeyfe/hd-transport$': '<rootDir>/../hd-transport/src/index.ts',
|
|
8
|
+
'^@onekeyfe/hd-shared$': '<rootDir>/../shared/src/index.ts',
|
|
9
|
+
},
|
|
5
10
|
};
|