@onekeyfe/hd-core 1.2.0-alpha.60 → 1.2.0-alpha.61

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.
@@ -1,6 +1,10 @@
1
1
  import { createDeferred } from '@onekeyfe/hd-shared';
2
2
 
3
- import { findUiPromiseForResponse, rejectUiPromises } from '../src/core/uiPromiseRegistry';
3
+ import {
4
+ consumeUiPromise,
5
+ findUiPromiseForResponse,
6
+ rejectUiPromises,
7
+ } from '../src/core/uiPromiseRegistry';
4
8
  import { UI_RESPONSE } from '../src/events';
5
9
 
6
10
  import type { UiPromise, UiPromiseResponse } from '../src/events';
@@ -17,6 +21,20 @@ const asRegistry = (promises: UiPromise<typeof UI_RESPONSE.RECEIVE_PIN>[]) =>
17
21
  promises as UiPromise<UiPromiseResponse['type']>[];
18
22
 
19
23
  describe('UI response promise correlation', () => {
24
+ test('consumes a rejected UI promise and normalizes its callback error', async () => {
25
+ const pending = createDeferred<string>();
26
+ const onFulfilled = jest.fn();
27
+ const onRejected = jest.fn();
28
+
29
+ consumeUiPromise(pending.promise, onFulfilled, onRejected);
30
+ pending.reject('cancelled' as unknown as Error);
31
+ await Promise.resolve();
32
+
33
+ expect(onFulfilled).not.toHaveBeenCalled();
34
+ expect(onRejected).toHaveBeenCalledWith(expect.any(Error));
35
+ expect(onRejected.mock.calls[0][0].message).toBe('cancelled');
36
+ });
37
+
20
38
  test('matches a sensitive response by type, interactionId and deviceId', () => {
21
39
  const deviceA = createPinPromise('interaction-a', 'device-a');
22
40
  const deviceB = createPinPromise('interaction-b', 'device-b');
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AA+BlC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAWhC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAgE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AA82BF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAkF9D,CAAC;AAmGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAwKF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IAoBhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AA+BlC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAWhC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAgE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AA82BF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAkF9D,CAAC;AAoGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IAoBhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { UiPromise, UiPromiseResponse } from '../events/ui-promise';
2
2
  import type { UiResponseEvent } from '../events/ui-response';
3
+ export declare const consumeUiPromise: <T>(promise: Promise<T>, onFulfilled: (value: T) => void, onRejected: (error: Error) => void) => void;
3
4
  export declare const rejectUiPromises: (uiPromises: UiPromise<UiPromiseResponse['type']>[], error: Error) => void;
4
5
  export declare const findUiPromiseForResponse: (uiPromises: UiPromise<UiPromiseResponse['type']>[], response: UiResponseEvent) => UiPromise<"ui-receive_pin" | "ui-receive_passphrase" | "ui-receive_select-device-in-bootloader-for-web-device" | "ui-receive_select-device-for-switch-firmware-web-device" | "device-disconnect"> | undefined;
5
6
  //# sourceMappingURL=uiPromiseRegistry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uiPromiseRegistry.d.ts","sourceRoot":"","sources":["../../src/core/uiPromiseRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,eAAO,MAAM,gBAAgB,eACf,UAAU,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,SAC3C,KAAK,SAKb,CAAC;AASF,eAAO,MAAM,wBAAwB,eACvB,UAAU,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,YACxC,eAAe,kNA0B1B,CAAC"}
1
+ {"version":3,"file":"uiPromiseRegistry.d.ts","sourceRoot":"","sources":["../../src/core/uiPromiseRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,eAAO,MAAM,gBAAgB,sDAEA,IAAI,sBACX,KAAK,KAAK,IAAI,SAKnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,eACf,UAAU,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,SAC3C,KAAK,SAKb,CAAC;AASF,eAAO,MAAM,wBAAwB,eACvB,UAAU,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,YACxC,eAAe,kNA0B1B,CAAC"}
package/dist/index.js CHANGED
@@ -61400,6 +61400,12 @@ class RequestQueue {
61400
61400
  }
61401
61401
  }
61402
61402
 
61403
+ const normalizeUiPromiseError = (error) => error instanceof Error ? error : new Error(String(error));
61404
+ const consumeUiPromise = (promise, onFulfilled, onRejected) => {
61405
+ promise.then(onFulfilled, error => {
61406
+ onRejected(normalizeUiPromiseError(error));
61407
+ });
61408
+ };
61403
61409
  const rejectUiPromises = (uiPromises, error) => {
61404
61410
  for (const uiPromise of uiPromises) {
61405
61411
  uiPromise.reject(error);
@@ -62370,7 +62376,7 @@ const onTransportDeviceDisconnectHandler = (event) => {
62370
62376
  device.markTransportDisconnected();
62371
62377
  DevicePool.emitter.emit(DEVICE.DISCONNECT, device);
62372
62378
  };
62373
- const onDevicePinHandler = (...[device, type, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62379
+ const onDevicePinHandler = (...[device, type, callback]) => {
62374
62380
  Log.log('request Input PIN');
62375
62381
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PIN, device);
62376
62382
  postMessage(createUiMessage(UI_REQUEST.REQUEST_PIN, {
@@ -62378,9 +62384,8 @@ const onDevicePinHandler = (...[device, type, callback]) => __awaiter(void 0, vo
62378
62384
  type,
62379
62385
  responseCorrelation: uiPromise.responseCorrelation,
62380
62386
  }));
62381
- const uiResp = yield uiPromise.promise;
62382
- callback(null, uiResp.payload);
62383
- });
62387
+ consumeUiPromise(uiPromise.promise, uiResp => callback(null, uiResp.payload), error => callback(error, ''));
62388
+ };
62384
62389
  const onDeviceButtonHandler = (...[device, request]) => {
62385
62390
  postMessage(createDeviceMessage(DEVICE.BUTTON, Object.assign(Object.assign({}, request), { device: device.toMessageObject() })));
62386
62391
  if (request.code === 'ButtonRequest_PinEntry' || request.code === 'ButtonRequest_AttachPin') {
@@ -62401,19 +62406,20 @@ const onDeviceFeaturesHandler = (...[_, features]) => {
62401
62406
  const onDeviceStateHandler = (...[_, stateEvent]) => {
62402
62407
  postMessage(createDeviceMessage(DEVICE.STATE, stateEvent));
62403
62408
  };
62404
- const onDevicePassphraseHandler = (...[device, requestPayload, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62409
+ const onDevicePassphraseHandler = (...[device, requestPayload, callback]) => {
62405
62410
  Log.debug('onDevicePassphraseHandler');
62406
62411
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PASSPHRASE, device);
62407
62412
  postMessage(createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE, Object.assign(Object.assign({ device: device.toMessageObject(), passphraseState: device.passphraseState, existsAttachPinUser: requestPayload.existsAttachPinUser, deviceOnly: requestPayload.deviceOnly, source: requestPayload.source, reason: requestPayload.reason, expectedPassphraseState: requestPayload.expectedPassphraseState }, (requestPayload.interaction ? { interaction: requestPayload.interaction } : {})), { responseCorrelation: uiPromise.responseCorrelation })));
62408
- const uiResp = yield uiPromise.promise;
62409
- const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
62410
- callback({
62411
- passphrase: value.normalize('NFKD'),
62412
- passphraseOnDevice,
62413
- attachPinOnDevice,
62414
- cache: save,
62415
- });
62416
- });
62413
+ consumeUiPromise(uiPromise.promise, uiResp => {
62414
+ const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
62415
+ callback({
62416
+ passphrase: value.normalize('NFKD'),
62417
+ passphraseOnDevice,
62418
+ attachPinOnDevice,
62419
+ cache: save,
62420
+ });
62421
+ }, error => callback({}, error));
62422
+ };
62417
62423
  const onEmptyPassphraseHandler = (...[_, , callback]) => {
62418
62424
  Log.debug('onEmptyPassphraseHandler');
62419
62425
  callback({ passphrase: '' });
@@ -62433,24 +62439,22 @@ const onEnterPinOnDeviceHandler = (...[device, pinType, metadata]) => {
62433
62439
  const onPinOnDeviceCompleteHandler = (...[_, metadata]) => {
62434
62440
  postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW, metadata));
62435
62441
  };
62436
- const onSelectDeviceInBootloaderForWebDeviceHandler = (...[device, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62442
+ const onSelectDeviceInBootloaderForWebDeviceHandler = (...[device, callback]) => {
62437
62443
  Log.debug('onSelectDeviceInBootloaderForWebDeviceHandler');
62438
62444
  const uiPromise = createUiPromise(UI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE, device);
62439
62445
  postMessage(createUiMessage(UI_REQUEST.REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE, {
62440
62446
  device: device.toMessageObject(),
62441
62447
  }));
62442
- const uiResp = yield uiPromise.promise;
62443
- callback(null, uiResp.payload.deviceId);
62444
- });
62445
- const onSelectDeviceForSwitchFirmwareWebDeviceHandler = (...[device, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62448
+ consumeUiPromise(uiPromise.promise, uiResp => callback(null, uiResp.payload.deviceId), error => callback(error, ''));
62449
+ };
62450
+ const onSelectDeviceForSwitchFirmwareWebDeviceHandler = (...[device, callback]) => {
62446
62451
  Log.debug('onSelectDeviceForSwitchFirmwareWebDeviceHandler');
62447
62452
  const uiPromise = createUiPromise(UI_RESPONSE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE, device);
62448
62453
  postMessage(createUiMessage(UI_REQUEST.REQUEST_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE, {
62449
62454
  device: device.toMessageObject(),
62450
62455
  }));
62451
- const uiResp = yield uiPromise.promise;
62452
- callback(null, uiResp.payload.deviceId);
62453
- });
62456
+ consumeUiPromise(uiPromise.promise, uiResp => callback(null, uiResp.payload.deviceId), error => callback(error, ''));
62457
+ };
62454
62458
  const postMessage = (message) => {
62455
62459
  if (!_core) {
62456
62460
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.0-alpha.60",
3
+ "version": "1.2.0-alpha.61",
4
4
  "description": "Core processes and APIs for communicating with OneKey hardware devices.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,8 +25,8 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-shared": "1.2.0-alpha.60",
29
- "@onekeyfe/hd-transport": "1.2.0-alpha.60",
28
+ "@onekeyfe/hd-shared": "1.2.0-alpha.61",
29
+ "@onekeyfe/hd-transport": "1.2.0-alpha.61",
30
30
  "axios": "1.15.2",
31
31
  "bignumber.js": "^9.0.2",
32
32
  "bytebuffer": "^5.0.1",
@@ -44,5 +44,5 @@
44
44
  "@types/w3c-web-usb": "^1.0.10",
45
45
  "@types/web-bluetooth": "^0.0.21"
46
46
  },
47
- "gitHead": "bde29baa04ac87453fd0eff54fd1cafe905f0ec8"
47
+ "gitHead": "19c6dc68cec2250bab703e802209ec7be586521d"
48
48
  }
package/src/core/index.ts CHANGED
@@ -54,7 +54,7 @@ import {
54
54
  import TransportManager from '../data-manager/TransportManager';
55
55
  import DeviceConnector from '../device/DeviceConnector';
56
56
  import RequestQueue from './RequestQueue';
57
- import { findUiPromiseForResponse, rejectUiPromises } from './uiPromiseRegistry';
57
+ import { consumeUiPromise, findUiPromiseForResponse, rejectUiPromises } from './uiPromiseRegistry';
58
58
  import { registerHardwareUiEventListeners } from './deviceEventRegistration';
59
59
  import { getSynchronize } from '../utils/getSynchronize';
60
60
  import { runMethodWithUnlockPolicy } from '../protocols/protocol-v2/unlockPolicyRunner';
@@ -1273,7 +1273,7 @@ const onTransportDeviceDisconnectHandler = (event: TransportDeviceDisconnectEven
1273
1273
  DevicePool.emitter.emit(DEVICE.DISCONNECT, device);
1274
1274
  };
1275
1275
 
1276
- const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin']) => {
1276
+ const onDevicePinHandler = (...[device, type, callback]: DeviceEvents['pin']) => {
1277
1277
  Log.log('request Input PIN');
1278
1278
  // create ui promise
1279
1279
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PIN, device);
@@ -1285,10 +1285,11 @@ const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin
1285
1285
  responseCorrelation: uiPromise.responseCorrelation,
1286
1286
  })
1287
1287
  );
1288
- // wait for pin
1289
- const uiResp = await uiPromise.promise;
1290
- // callback.apply(null, [null, pin]);
1291
- callback(null, uiResp.payload);
1288
+ consumeUiPromise(
1289
+ uiPromise.promise,
1290
+ uiResp => callback(null, uiResp.payload),
1291
+ error => callback(error, '')
1292
+ );
1292
1293
  };
1293
1294
 
1294
1295
  export const onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
@@ -1316,7 +1317,7 @@ const onDeviceStateHandler = (...[_, stateEvent]: [...DeviceEvents['state']]) =>
1316
1317
  postMessage(createDeviceMessage(DEVICE.STATE, stateEvent));
1317
1318
  };
1318
1319
 
1319
- const onDevicePassphraseHandler = async (
1320
+ const onDevicePassphraseHandler = (
1320
1321
  ...[device, requestPayload, callback]: DeviceEvents['passphrase']
1321
1322
  ) => {
1322
1323
  Log.debug('onDevicePassphraseHandler');
@@ -1334,16 +1335,19 @@ const onDevicePassphraseHandler = async (
1334
1335
  responseCorrelation: uiPromise.responseCorrelation,
1335
1336
  })
1336
1337
  );
1337
- // wait for passphrase
1338
- const uiResp = await uiPromise.promise;
1339
- const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
1340
- // send as PassphrasePromptResponse
1341
- callback({
1342
- passphrase: value.normalize('NFKD'),
1343
- passphraseOnDevice,
1344
- attachPinOnDevice,
1345
- cache: save,
1346
- });
1338
+ consumeUiPromise(
1339
+ uiPromise.promise,
1340
+ uiResp => {
1341
+ const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
1342
+ callback({
1343
+ passphrase: value.normalize('NFKD'),
1344
+ passphraseOnDevice,
1345
+ attachPinOnDevice,
1346
+ cache: save,
1347
+ });
1348
+ },
1349
+ error => callback({}, error)
1350
+ );
1347
1351
  };
1348
1352
 
1349
1353
  const onEmptyPassphraseHandler = (...[_, , callback]: DeviceEvents['passphrase']) => {
@@ -1408,7 +1412,7 @@ const onPinOnDeviceCompleteHandler = (
1408
1412
  postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW, metadata));
1409
1413
  };
1410
1414
 
1411
- const onSelectDeviceInBootloaderForWebDeviceHandler = async (
1415
+ const onSelectDeviceInBootloaderForWebDeviceHandler = (
1412
1416
  ...[device, callback]: [...DeviceEvents['select_device_in_bootloader_for_web_device']]
1413
1417
  ) => {
1414
1418
  Log.debug('onSelectDeviceInBootloaderForWebDeviceHandler');
@@ -1418,11 +1422,14 @@ const onSelectDeviceInBootloaderForWebDeviceHandler = async (
1418
1422
  device: device.toMessageObject() as KnownDevice,
1419
1423
  })
1420
1424
  );
1421
- const uiResp = await uiPromise.promise;
1422
- callback(null, uiResp.payload.deviceId);
1425
+ consumeUiPromise(
1426
+ uiPromise.promise,
1427
+ uiResp => callback(null, uiResp.payload.deviceId),
1428
+ error => callback(error, '')
1429
+ );
1423
1430
  };
1424
1431
 
1425
- const onSelectDeviceForSwitchFirmwareWebDeviceHandler = async (
1432
+ const onSelectDeviceForSwitchFirmwareWebDeviceHandler = (
1426
1433
  ...[device, callback]: [...DeviceEvents['select_device_for_switch_firmware_web_device']]
1427
1434
  ) => {
1428
1435
  Log.debug('onSelectDeviceForSwitchFirmwareWebDeviceHandler');
@@ -1435,8 +1442,11 @@ const onSelectDeviceForSwitchFirmwareWebDeviceHandler = async (
1435
1442
  device: device.toMessageObject() as KnownDevice,
1436
1443
  })
1437
1444
  );
1438
- const uiResp = await uiPromise.promise;
1439
- callback(null, uiResp.payload.deviceId);
1445
+ consumeUiPromise(
1446
+ uiPromise.promise,
1447
+ uiResp => callback(null, uiResp.payload.deviceId),
1448
+ error => callback(error, '')
1449
+ );
1440
1450
  };
1441
1451
 
1442
1452
  /**
@@ -3,6 +3,19 @@ import { UI_RESPONSE } from '../events/ui-response';
3
3
  import type { UiPromise, UiPromiseResponse } from '../events/ui-promise';
4
4
  import type { UiResponseEvent } from '../events/ui-response';
5
5
 
6
+ const normalizeUiPromiseError = (error: unknown) =>
7
+ error instanceof Error ? error : new Error(String(error));
8
+
9
+ export const consumeUiPromise = <T>(
10
+ promise: Promise<T>,
11
+ onFulfilled: (value: T) => void,
12
+ onRejected: (error: Error) => void
13
+ ) => {
14
+ promise.then(onFulfilled, error => {
15
+ onRejected(normalizeUiPromiseError(error));
16
+ });
17
+ };
18
+
6
19
  export const rejectUiPromises = (
7
20
  uiPromises: UiPromise<UiPromiseResponse['type']>[],
8
21
  error: Error