ccxt 4.4.20 → 4.4.21

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.
Files changed (53) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +4 -4
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/base/Exchange.js +13 -0
  5. package/dist/cjs/src/base/ws/Future.js +3 -1
  6. package/dist/cjs/src/binance.js +0 -10
  7. package/dist/cjs/src/bingx.js +6 -1
  8. package/dist/cjs/src/bybit.js +65 -3
  9. package/dist/cjs/src/htx.js +28 -0
  10. package/dist/cjs/src/hyperliquid.js +7 -6
  11. package/dist/cjs/src/kucoin.js +16 -36
  12. package/dist/cjs/src/kucoinfutures.js +2 -2
  13. package/dist/cjs/src/okx.js +8 -10
  14. package/dist/cjs/src/paradex.js +1 -2
  15. package/dist/cjs/src/static_dependencies/noble-hashes/_sha2.js +1 -1
  16. package/dist/cjs/src/static_dependencies/noble-hashes/hmac.js +1 -1
  17. package/dist/cjs/src/static_dependencies/noble-hashes/sha3.js +1 -1
  18. package/dist/cjs/src/static_dependencies/watchable/src/unpromise.js +298 -0
  19. package/js/ccxt.d.ts +1 -1
  20. package/js/ccxt.js +1 -1
  21. package/js/src/abstract/bybit.d.ts +1 -0
  22. package/js/src/abstract/kucoin.d.ts +1 -0
  23. package/js/src/abstract/kucoinfutures.d.ts +1 -0
  24. package/js/src/abstract/okx.d.ts +3 -0
  25. package/js/src/base/Exchange.d.ts +3 -1
  26. package/js/src/base/Exchange.js +13 -0
  27. package/js/src/base/ws/Future.js +2 -1
  28. package/js/src/binance.d.ts +0 -1
  29. package/js/src/binance.js +0 -10
  30. package/js/src/bingx.js +6 -1
  31. package/js/src/bybit.d.ts +1 -0
  32. package/js/src/bybit.js +65 -3
  33. package/js/src/htx.d.ts +2 -2
  34. package/js/src/htx.js +28 -0
  35. package/js/src/hyperliquid.js +7 -6
  36. package/js/src/kucoin.d.ts +0 -1
  37. package/js/src/kucoin.js +16 -36
  38. package/js/src/kucoinfutures.js +2 -2
  39. package/js/src/okx.d.ts +0 -1
  40. package/js/src/okx.js +9 -11
  41. package/js/src/paradex.js +1 -1
  42. package/js/src/static_dependencies/noble-hashes/_blake2.js +1 -1
  43. package/js/src/static_dependencies/noble-hashes/_sha2.js +1 -1
  44. package/js/src/static_dependencies/noble-hashes/hmac.js +1 -1
  45. package/js/src/static_dependencies/noble-hashes/sha3-addons.js +5 -5
  46. package/js/src/static_dependencies/noble-hashes/sha3.js +1 -1
  47. package/js/src/static_dependencies/watchable/src/index.d.ts +2 -0
  48. package/js/src/static_dependencies/watchable/src/index.js +7 -0
  49. package/js/src/static_dependencies/watchable/src/types.d.ts +28 -0
  50. package/js/src/static_dependencies/watchable/src/types.js +8 -0
  51. package/js/src/static_dependencies/watchable/src/unpromise.d.ts +120 -0
  52. package/js/src/static_dependencies/watchable/src/unpromise.js +297 -0
  53. package/package.json +1 -1
@@ -645,9 +645,9 @@ export default class hyperliquid extends Exchange {
645
645
  const code = this.safeCurrencyCode(this.safeString(balance, 'coin'));
646
646
  const account = this.account();
647
647
  const total = this.safeString(balance, 'total');
648
- const free = this.safeString(balance, 'hold');
648
+ const used = this.safeString(balance, 'hold');
649
649
  account['total'] = total;
650
- account['used'] = free;
650
+ account['used'] = used;
651
651
  spotBalances[code] = account;
652
652
  }
653
653
  return this.safeBalance(spotBalances);
@@ -656,8 +656,8 @@ export default class hyperliquid extends Exchange {
656
656
  const result = {
657
657
  'info': response,
658
658
  'USDC': {
659
- 'total': this.safeFloat(data, 'accountValue'),
660
- 'used': this.safeFloat(data, 'totalMarginUsed'),
659
+ 'total': this.safeNumber(data, 'accountValue'),
660
+ 'free': this.safeNumber(response, 'withdrawable'),
661
661
  },
662
662
  };
663
663
  const timestamp = this.safeInteger(response, 'time');
@@ -2230,10 +2230,11 @@ export default class hyperliquid extends Exchange {
2230
2230
  const leverage = this.safeDict(entry, 'leverage', {});
2231
2231
  const marginMode = this.safeString(leverage, 'type');
2232
2232
  const isIsolated = (marginMode === 'isolated');
2233
- const size = this.safeNumber(entry, 'szi');
2233
+ let size = this.safeString(entry, 'szi');
2234
2234
  let side = undefined;
2235
2235
  if (size !== undefined) {
2236
- side = (size > 0) ? 'long' : 'short';
2236
+ side = Precise.stringGt(size, '0') ? 'long' : 'short';
2237
+ size = Precise.stringAbs(size);
2237
2238
  }
2238
2239
  const unrealizedPnl = this.safeNumber(entry, 'unrealizedPnl');
2239
2240
  const initialMargin = this.safeNumber(entry, 'marginUsed');
@@ -76,7 +76,6 @@ export default class kucoin extends Exchange {
76
76
  parseLedgerEntry(item: Dict, currency?: Currency): LedgerEntry;
77
77
  fetchLedger(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<LedgerEntry[]>;
78
78
  calculateRateLimiterCost(api: any, method: any, path: any, params: any, config?: {}): any;
79
- parseBorrowRateHistory(response: any, code: any, since: any, limit: any): any;
80
79
  parseBorrowRate(info: any, currency?: Currency): {
81
80
  currency: string;
82
81
  rate: number;
package/js/src/kucoin.js CHANGED
@@ -166,7 +166,8 @@ export default class kucoin extends Exchange {
166
166
  // margin trading
167
167
  'mark-price/{symbol}/current': 3,
168
168
  'mark-price/all-symbols': 3,
169
- 'margin/config': 25, // 25SW
169
+ 'margin/config': 25,
170
+ 'announcements': 20, // 20W
170
171
  },
171
172
  'post': {
172
173
  // ws
@@ -456,6 +457,7 @@ export default class kucoin extends Exchange {
456
457
  'precisionMode': TICK_SIZE,
457
458
  'exceptions': {
458
459
  'exact': {
460
+ 'The order does not exist.': OrderNotFound,
459
461
  'order not exist': OrderNotFound,
460
462
  'order not exist.': OrderNotFound,
461
463
  'order_not_exist': OrderNotFound,
@@ -656,6 +658,7 @@ export default class kucoin extends Exchange {
656
658
  'currencies/{currency}': 'v3',
657
659
  'symbols': 'v2',
658
660
  'mark-price/all-symbols': 'v3',
661
+ 'announcements': 'v3',
659
662
  },
660
663
  },
661
664
  'private': {
@@ -1544,41 +1547,28 @@ export default class kucoin extends Exchange {
1544
1547
  // "chain": "ERC20"
1545
1548
  // }
1546
1549
  //
1550
+ const minWithdrawFee = this.safeNumber(fee, 'withdrawMinFee');
1547
1551
  const result = {
1548
1552
  'info': fee,
1549
1553
  'withdraw': {
1554
+ 'fee': minWithdrawFee,
1555
+ 'percentage': false,
1556
+ },
1557
+ 'deposit': {
1550
1558
  'fee': undefined,
1551
1559
  'percentage': undefined,
1552
1560
  },
1561
+ 'networks': {},
1562
+ };
1563
+ const networkId = this.safeString(fee, 'chain');
1564
+ const networkCode = this.networkIdToCode(networkId, this.safeString(currency, 'code'));
1565
+ result['networks'][networkCode] = {
1566
+ 'withdraw': minWithdrawFee,
1553
1567
  'deposit': {
1554
1568
  'fee': undefined,
1555
1569
  'percentage': undefined,
1556
1570
  },
1557
- 'networks': {},
1558
1571
  };
1559
- const isWithdrawEnabled = this.safeBool(fee, 'isWithdrawEnabled', true);
1560
- let minFee = undefined;
1561
- if (isWithdrawEnabled) {
1562
- result['withdraw']['percentage'] = false;
1563
- const chains = this.safeList(fee, 'chains', []);
1564
- for (let i = 0; i < chains.length; i++) {
1565
- const chain = chains[i];
1566
- const networkId = this.safeString(chain, 'chainId');
1567
- const networkCode = this.networkIdToCode(networkId, this.safeString(currency, 'code'));
1568
- const withdrawFee = this.safeString(chain, 'withdrawalMinFee');
1569
- if (minFee === undefined || (Precise.stringLt(withdrawFee, minFee))) {
1570
- minFee = withdrawFee;
1571
- }
1572
- result['networks'][networkCode] = {
1573
- 'withdraw': this.parseNumber(withdrawFee),
1574
- 'deposit': {
1575
- 'fee': undefined,
1576
- 'percentage': undefined,
1577
- },
1578
- };
1579
- }
1580
- result['withdraw']['fee'] = this.parseNumber(minFee);
1581
- }
1582
1572
  return result;
1583
1573
  }
1584
1574
  isFuturesMethod(methodName, params) {
@@ -3094,7 +3084,7 @@ export default class kucoin extends Exchange {
3094
3084
  },
3095
3085
  'status': status,
3096
3086
  'lastTradeTimestamp': undefined,
3097
- 'average': undefined,
3087
+ 'average': this.safeString(order, 'avgDealPrice'),
3098
3088
  'trades': undefined,
3099
3089
  }, market);
3100
3090
  }
@@ -4429,16 +4419,6 @@ export default class kucoin extends Exchange {
4429
4419
  }
4430
4420
  return this.safeValue(config, 'cost', 1);
4431
4421
  }
4432
- parseBorrowRateHistory(response, code, since, limit) {
4433
- const result = [];
4434
- for (let i = 0; i < response.length; i++) {
4435
- const item = response[i];
4436
- const borrowRate = this.parseBorrowRate(item);
4437
- result.push(borrowRate);
4438
- }
4439
- const sorted = this.sortBy(result, 'timestamp');
4440
- return this.filterByCurrencySinceLimit(sorted, code, since, limit);
4441
- }
4442
4422
  parseBorrowRate(info, currency = undefined) {
4443
4423
  //
4444
4424
  // {
@@ -2220,8 +2220,8 @@ export default class kucoinfutures extends kucoin {
2220
2220
  const amount = this.safeString(order, 'size');
2221
2221
  const filled = this.safeString(order, 'filledSize');
2222
2222
  const cost = this.safeString(order, 'filledValue');
2223
- let average = undefined;
2224
- if (Precise.stringGt(filled, '0')) {
2223
+ let average = this.safeString(order, 'avgDealPrice');
2224
+ if ((average === undefined) && Precise.stringGt(filled, '0')) {
2225
2225
  const contractSize = this.safeString(market, 'contractSize');
2226
2226
  if (market['linear']) {
2227
2227
  average = Precise.stringDiv(cost, Precise.stringMul(contractSize, filled));
package/js/src/okx.d.ts CHANGED
@@ -107,7 +107,6 @@ export default class okx extends Exchange {
107
107
  info: any;
108
108
  };
109
109
  parseBorrowRateHistories(response: any, codes: any, since: any, limit: any): Dict;
110
- parseBorrowRateHistory(response: any, code: any, since: any, limit: any): any;
111
110
  fetchBorrowRateHistories(codes?: any, since?: Int, limit?: Int, params?: {}): Promise<Dict>;
112
111
  fetchBorrowRateHistory(code: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
113
112
  modifyMarginHelper(symbol: string, amount: any, type: any, params?: {}): Promise<MarginModification>;
package/js/src/okx.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/okx.js';
9
- import { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, DDoSProtection, PermissionDenied, InsufficientFunds, InvalidNonce, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, BadSymbol, RateLimitExceeded, NetworkError, CancelPending, NotSupported, AccountNotEnabled, ContractUnavailable, ManualInteractionNeeded } from './base/errors.js';
9
+ import { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, DDoSProtection, PermissionDenied, InsufficientFunds, InvalidNonce, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, BadSymbol, RateLimitExceeded, NetworkError, CancelPending, NotSupported, AccountNotEnabled, ContractUnavailable, ManualInteractionNeeded, OperationRejected } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TICK_SIZE } from './base/functions/number.js';
12
12
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
@@ -356,6 +356,9 @@ export default class okx extends Exchange {
356
356
  'account/fixed-loan/borrowing-limit': 4,
357
357
  'account/fixed-loan/borrowing-quote': 5,
358
358
  'account/fixed-loan/borrowing-orders-list': 5,
359
+ 'account/spot-manual-borrow-repay': 10,
360
+ 'account/set-auto-repay': 4,
361
+ 'account/spot-borrow-repay-history': 4,
359
362
  // subaccount
360
363
  'users/subaccount/list': 10,
361
364
  'account/subaccount/balances': 10 / 3,
@@ -887,6 +890,11 @@ export default class okx extends Exchange {
887
890
  '59301': ExchangeError,
888
891
  '59313': ExchangeError,
889
892
  '59401': ExchangeError,
893
+ '59410': OperationRejected,
894
+ '59411': InsufficientFunds,
895
+ '59412': OperationRejected,
896
+ '59413': OperationRejected,
897
+ '59414': BadRequest,
890
898
  '59500': ExchangeError,
891
899
  '59501': ExchangeError,
892
900
  '59502': ExchangeError,
@@ -6676,16 +6684,6 @@ export default class okx extends Exchange {
6676
6684
  }
6677
6685
  return borrowRateHistories;
6678
6686
  }
6679
- parseBorrowRateHistory(response, code, since, limit) {
6680
- const result = [];
6681
- for (let i = 0; i < response.length; i++) {
6682
- const item = response[i];
6683
- const borrowRate = this.parseBorrowRate(item);
6684
- result.push(borrowRate);
6685
- }
6686
- const sorted = this.sortBy(result, 'timestamp');
6687
- return this.filterByCurrencySinceLimit(sorted, code, since, limit);
6688
- }
6689
6687
  async fetchBorrowRateHistories(codes = undefined, since = undefined, limit = undefined, params = {}) {
6690
6688
  /**
6691
6689
  * @method
package/js/src/paradex.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
- import { Precise } from '../ccxt.js';
8
+ import { Precise } from './base/Precise.js';
9
9
  import Exchange from './abstract/paradex.js';
10
10
  import { ExchangeError, PermissionDenied, AuthenticationError, BadRequest, ArgumentsRequired, OperationRejected, InvalidOrder } from './base/errors.js';
11
11
  import { TICK_SIZE } from './base/functions/number.js';
@@ -97,7 +97,7 @@ export class BLAKE2 extends Hash {
97
97
  }
98
98
  _cloneInto(to) {
99
99
  const { buffer, length, finished, destroyed, outputLen, pos } = this;
100
- to || (to = new this.constructor({ dkLen: outputLen }));
100
+ to ||= new this.constructor({ dkLen: outputLen });
101
101
  to.set(...this.get());
102
102
  to.length = length;
103
103
  to.finished = finished;
@@ -105,7 +105,7 @@ export class SHA2 extends Hash {
105
105
  return res;
106
106
  }
107
107
  _cloneInto(to) {
108
- to || (to = new this.constructor());
108
+ to ||= new this.constructor();
109
109
  to.set(...this.get());
110
110
  const { blockLen, buffer, length, finished, destroyed, pos } = this;
111
111
  to.length = length;
@@ -55,7 +55,7 @@ class HMAC extends Hash {
55
55
  }
56
56
  _cloneInto(to) {
57
57
  // Create new instance without calling constructor since key already in state and we don't know it.
58
- to || (to = Object.create(Object.getPrototypeOf(this), {}));
58
+ to ||= Object.create(Object.getPrototypeOf(this), {});
59
59
  const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
60
60
  to = to;
61
61
  to.finished = finished;
@@ -113,7 +113,7 @@ class TupleHash extends Keccak {
113
113
  super.finish();
114
114
  }
115
115
  _cloneInto(to) {
116
- to || (to = new TupleHash(this.blockLen, this.outputLen, this.enableXOF));
116
+ to ||= new TupleHash(this.blockLen, this.outputLen, this.enableXOF);
117
117
  return super._cloneInto(to);
118
118
  }
119
119
  clone() {
@@ -142,7 +142,7 @@ class ParallelHash extends Keccak {
142
142
  this.chunksDone = 0; // How many chunks we already have
143
143
  cshakePers(this, { NISTfn: 'ParallelHash', personalization: opts.personalization });
144
144
  let { blockLen: B } = opts;
145
- B || (B = 8);
145
+ B ||= 8;
146
146
  assertNumber(B);
147
147
  this.chunkLen = B;
148
148
  super.update(leftEncode(B));
@@ -179,7 +179,7 @@ class ParallelHash extends Keccak {
179
179
  super.finish();
180
180
  }
181
181
  _cloneInto(to) {
182
- to || (to = new ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF));
182
+ to ||= new ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF);
183
183
  if (this.leafHash)
184
184
  to.leafHash = this.leafHash._cloneInto(to.leafHash);
185
185
  to.chunkPos = this.chunkPos;
@@ -273,7 +273,7 @@ class KangarooTwelve extends Keccak {
273
273
  }
274
274
  _cloneInto(to) {
275
275
  const { blockLen, leafLen, leafHash, outputLen, rounds } = this;
276
- to || (to = new KangarooTwelve(blockLen, leafLen, outputLen, rounds, {}));
276
+ to ||= new KangarooTwelve(blockLen, leafLen, outputLen, rounds, {});
277
277
  super._cloneInto(to);
278
278
  if (leafHash)
279
279
  to.leafHash = leafHash._cloneInto(to.leafHash);
@@ -340,7 +340,7 @@ class KeccakPRG extends Keccak {
340
340
  }
341
341
  _cloneInto(to) {
342
342
  const { rate } = this;
343
- to || (to = new KeccakPRG(1600 - rate));
343
+ to ||= new KeccakPRG(1600 - rate);
344
344
  super._cloneInto(to);
345
345
  to.rate = rate;
346
346
  return to;
@@ -175,7 +175,7 @@ export class Keccak extends Hash {
175
175
  }
176
176
  _cloneInto(to) {
177
177
  const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
178
- to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
178
+ to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds);
179
179
  to.state32.set(this.state32);
180
180
  to.pos = this.pos;
181
181
  to.posOut = this.posOut;
@@ -0,0 +1,2 @@
1
+ export { Unpromise } from "./unpromise";
2
+ export type { ProxyPromise, SubscribedPromise, PromiseExecutor, PromiseWithResolvers, } from "./types";
@@ -0,0 +1,7 @@
1
+ // ----------------------------------------------------------------------------
2
+
3
+ // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+ // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
+
7
+ export { Unpromise } from "./unpromise";
@@ -0,0 +1,28 @@
1
+ /** TYPES */
2
+ /** A promise that exploits a single, memory-safe upstream subscription
3
+ * to a single re-used Unpromise that persists for the VM lifetime of a
4
+ * Promise.
5
+ *
6
+ * Calling unsubscribe() removes the subscription, eliminating
7
+ * all references to the SubscribedPromise. */
8
+ export interface SubscribedPromise<T> extends Promise<T> {
9
+ unsubscribe: () => void;
10
+ }
11
+ /** Duplicate of Promise interface, except each call returns SubscribedPromise */
12
+ export interface ProxyPromise<T> extends Promise<T> {
13
+ subscribe: () => SubscribedPromise<T>;
14
+ then: <TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => SubscribedPromise<TResult1 | TResult2>;
15
+ catch: <TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined) => SubscribedPromise<T | TResult>;
16
+ finally: (onfinally?: (() => void) | null | undefined) => SubscribedPromise<T>;
17
+ }
18
+ export declare type PromiseExecutor<T> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void;
19
+ /** A standard pattern for a resolvable, rejectable Promise, based
20
+ * on the emerging ES2023 standard. Type ported from
21
+ * https://github.com/microsoft/TypeScript/pull/56593 */
22
+ export interface PromiseWithResolvers<T> {
23
+ promise: Promise<T>;
24
+ resolve: (value: T | PromiseLike<T>) => void;
25
+ reject: (reason?: any) => void;
26
+ }
27
+ /** Given an array, this is the union of its members' types. */
28
+ export declare type MemberOf<Arr extends readonly unknown[]> = Arr[number];
@@ -0,0 +1,8 @@
1
+ // ----------------------------------------------------------------------------
2
+
3
+ // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+ // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
+
7
+ /** TYPES */
8
+ export {};
@@ -0,0 +1,120 @@
1
+ import type { PromiseExecutor, PromiseWithResolvers, ProxyPromise, SubscribedPromise } from "./types";
2
+ /**
3
+ * Every `Promise<T>` can be shadowed by a single `ProxyPromise<T>`. It is
4
+ * created once, cached and reused throughout the lifetime of the Promise. Get a
5
+ * Promise's ProxyPromise using `Unpromise.proxy(promise)`.
6
+ *
7
+ * The `ProxyPromise<T>` attaches handlers to the original `Promise<T>`
8
+ * `.then()` and `.catch()` just once. Promises derived from it use a
9
+ * subscription- (and unsubscription-) based mechanism that monitors these
10
+ * handlers.
11
+ *
12
+ * Every time you call `.subscribe()`, `.then()` `.catch()` or `.finally()` on a
13
+ * `ProxyPromise<T>` it returns a `SubscribedPromise<T>` having an additional
14
+ * `unsubscribe()` method. Calling `unsubscribe()` detaches reference chains
15
+ * from the original, potentially long-lived Promise, eliminating memory leaks.
16
+ *
17
+ * This approach can eliminate the memory leaks that otherwise come about from
18
+ * repeated `race()` or `any()` calls invoking `.then()` and `.catch()` multiple
19
+ * times on the same long-lived native Promise (subscriptions which can never be
20
+ * cleaned up).
21
+ *
22
+ * `Unpromise.race(promises)` is a reference implementation of `Promise.race`
23
+ * avoiding memory leaks when using long-lived unsettled Promises.
24
+ *
25
+ * `Unpromise.any(promises)` is a reference implementation of `Promise.any`
26
+ * avoiding memory leaks when using long-lived unsettled Promises.
27
+ *
28
+ * `Unpromise.resolve(promise)` returns an ephemeral `SubscribedPromise<T>` for
29
+ * any given `Promise<T>` facilitating arbitrary async/await patterns. Behind
30
+ * the scenes, `resolve` is implemented simply as
31
+ * `Unpromise.proxy(promise).subscribe()`. Don't forget to call `.unsubscribe()`
32
+ * to tidy up!
33
+ *
34
+ */
35
+ export declare class Unpromise<T> implements ProxyPromise<T> {
36
+ /** INSTANCE IMPLEMENTATION */
37
+ /** The promise shadowed by this Unpromise<T> */
38
+ protected readonly promise: Promise<T> | PromiseLike<T>;
39
+ /** Promises expecting eventual settlement (unless unsubscribed first). This list is deleted
40
+ * after the original promise settles - no further notifications will be issued. */
41
+ protected subscribers: ReadonlyArray<PromiseWithResolvers<T>> | null;
42
+ /** The Promise's settlement (recorded when it fulfils or rejects). This is consulted when
43
+ * calling .subscribe() .then() .catch() .finally() to see if an immediately-resolving Promise
44
+ * can be returned, and therefore subscription can be bypassed. */
45
+ protected settlement: PromiseSettledResult<T> | null;
46
+ /** Constructor accepts a normal Promise executor function like `new
47
+ * Unpromise((resolve, reject) => {...})` or accepts a pre-existing Promise
48
+ * like `new Unpromise(existingPromise)`. Adds `.then()` and `.catch()`
49
+ * handlers to the Promise. These handlers pass fulfilment and rejection
50
+ * notifications to downstream subscribers and maintains records of value
51
+ * or error if the Promise ever settles. */
52
+ protected constructor(promise: Promise<T>);
53
+ protected constructor(promise: PromiseLike<T>);
54
+ protected constructor(executor: PromiseExecutor<T>);
55
+ /** Create a promise that mitigates uncontrolled subscription to a long-lived
56
+ * Promise via .then() and .catch() - otherwise a source of memory leaks.
57
+ *
58
+ * The returned promise has an `unsubscribe()` method which can be called when
59
+ * the Promise is no longer being tracked by application logic, and which
60
+ * ensures that there is no reference chain from the original promise to the
61
+ * new one, and therefore no memory leak.
62
+ *
63
+ * If original promise has not yet settled, this adds a new unique promise
64
+ * that listens to then/catch events, along with an `unsubscribe()` method to
65
+ * detach it.
66
+ *
67
+ * If original promise has settled, then creates a new Promise.resolve() or
68
+ * Promise.reject() and provided unsubscribe is a noop.
69
+ *
70
+ * If you call `unsubscribe()` before the returned Promise has settled, it
71
+ * will never settle.
72
+ */
73
+ subscribe(): SubscribedPromise<T>;
74
+ /** STANDARD PROMISE METHODS (but returning a SubscribedPromise) */
75
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): SubscribedPromise<TResult1 | TResult2>;
76
+ catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined): SubscribedPromise<T | TResult>;
77
+ finally(onfinally?: (() => void) | null | undefined): SubscribedPromise<T>;
78
+ /** TOSTRING SUPPORT */
79
+ readonly [Symbol.toStringTag] = "Unpromise";
80
+ /** Unpromise STATIC METHODS */
81
+ /** Create or Retrieve the proxy Unpromise (a re-used Unpromise for the VM lifetime
82
+ * of the provided Promise reference) */
83
+ static proxy<T>(promise: PromiseLike<T>): ProxyPromise<T>;
84
+ /** Create and store an Unpromise keyed by an original Promise. */
85
+ protected static createSubscribablePromise<T>(promise: PromiseLike<T>): Unpromise<T>;
86
+ /** Retrieve a previously-created Unpromise keyed by an original Promise. */
87
+ protected static getSubscribablePromise<T>(promise: PromiseLike<T>): ProxyPromise<T>;
88
+ /** Promise STATIC METHODS */
89
+ /** Lookup the Unpromise for this promise, and derive a SubscribedPromise from
90
+ * it (that can be later unsubscribed to eliminate Memory leaks) */
91
+ static resolve<T>(value: T | PromiseLike<T>): SubscribedPromise<Awaited<T>>;
92
+ /** Perform Promise.any() via SubscribedPromises, then unsubscribe them.
93
+ * Equivalent to Promise.any but eliminates memory leaks from long-lived
94
+ * promises accumulating .then() and .catch() subscribers. */
95
+ static any<T extends readonly unknown[] | []>(values: T): Promise<Awaited<T[number]>>;
96
+ /** Perform Promise.race via SubscribedPromises, then unsubscribe them.
97
+ * Equivalent to Promise.race but eliminates memory leaks from long-lived
98
+ * promises accumulating .then() and .catch() subscribers. */
99
+ static race<T extends readonly unknown[] | []>(values: T): Promise<Awaited<T[number]>>;
100
+ /** Create a race of SubscribedPromises that will fulfil to a single winning
101
+ * Promise (in a 1-Tuple). Eliminates memory leaks from long-lived promises
102
+ * accumulating .then() and .catch() subscribers. Allows simple logic to
103
+ * consume the result, like...
104
+ * ```ts
105
+ * const [ winner ] = await Unpromise.race([ promiseA, promiseB ]);
106
+ * if(winner === promiseB){
107
+ * const result = await promiseB;
108
+ * // do the thing
109
+ * }
110
+ * ```
111
+ * */
112
+ static raceReferences<P extends Promise<unknown>>(promises: readonly P[]): Promise<readonly [P]>;
113
+ }
114
+ /** Promises a 1-tuple containing the original promise when it resolves. Allows
115
+ * awaiting the eventual Promise ***reference*** (easy to destructure and
116
+ * exactly compare with ===). Avoids resolving to the Promise ***value*** (which
117
+ * may be ambiguous and therefore hard to identify as the winner of a race).
118
+ * You can call unsubscribe on the Promise to mitigate memory leaks.
119
+ * */
120
+ export declare function resolveSelfTuple<P extends Promise<unknown>>(promise: P): SubscribedPromise<readonly [P]>;