UNPKG

3.48 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.promiseTracker = promiseTracker;
7exports.toPromiseMethod = toPromiseMethod;
8
9var _rxjs = require("rxjs");
10
11var _util = require("@polkadot/util");
12
13// Copyright 2017-2022 @polkadot/api authors & contributors
14// SPDX-License-Identifier: Apache-2.0
15// a Promise completion tracker, wrapping an isComplete variable that ensures
16// that the promise only resolves once
17function promiseTracker(resolve, reject) {
18 let isCompleted = false;
19 return {
20 reject: error => {
21 if (!isCompleted) {
22 isCompleted = true;
23 reject(error);
24 }
25
26 return _rxjs.EMPTY;
27 },
28 resolve: value => {
29 if (!isCompleted) {
30 isCompleted = true;
31 resolve(value);
32 }
33 }
34 };
35} // extract the arguments and callback params from a value array possibly containing a callback
36
37
38function extractArgs(args, needsCallback) {
39 const actualArgs = args.slice(); // If the last arg is a function, we pop it, put it into callback.
40 // actualArgs will then hold the actual arguments to be passed to `method`
41
42 const callback = args.length && (0, _util.isFunction)(args[args.length - 1]) ? actualArgs.pop() : undefined; // When we need a subscription, ensure that a valid callback is actually passed
43
44 (0, _util.assert)(!needsCallback || (0, _util.isFunction)(callback), 'Expected a callback to be passed with subscriptions');
45 return [actualArgs, callback];
46} // Decorate a call for a single-shot result - retrieve and then immediate unsubscribe
47
48
49function decorateCall(method, args) {
50 return new Promise((resolve, reject) => {
51 // single result tracker - either reject with Error or resolve with Codec result
52 const tracker = promiseTracker(resolve, reject); // encoding errors reject immediately, any result unsubscribes and resolves
53
54 const subscription = method(...args).pipe((0, _rxjs.catchError)(error => tracker.reject(error))).subscribe(result => {
55 tracker.resolve(result);
56 setTimeout(() => subscription.unsubscribe(), 0);
57 });
58 });
59} // Decorate a subscription where we have a result callback specified
60
61
62function decorateSubscribe(method, args, resultCb) {
63 return new Promise((resolve, reject) => {
64 // either reject with error or resolve with unsubscribe callback
65 const tracker = promiseTracker(resolve, reject); // errors reject immediately, the first result resolves with an unsubscribe promise, all results via callback
66
67 const subscription = method(...args).pipe((0, _rxjs.catchError)(error => tracker.reject(error)), (0, _rxjs.tap)(() => tracker.resolve(() => subscription.unsubscribe()))).subscribe(result => {
68 // queue result (back of queue to clear current)
69 setTimeout(() => resultCb(result), 0);
70 });
71 });
72}
73/**
74 * @description Decorate method for ApiPromise, where the results are converted to the Promise equivalent
75 */
76
77
78function toPromiseMethod(method, options) {
79 const needsCallback = !!(options && options.methodName && options.methodName.includes('subscribe'));
80 return function () {
81 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
82 args[_key] = arguments[_key];
83 }
84
85 const [actualArgs, resultCb] = extractArgs(args, needsCallback);
86 return resultCb ? decorateSubscribe(method, actualArgs, resultCb) : decorateCall((options === null || options === void 0 ? void 0 : options.overrideNoSub) || method, actualArgs);
87 };
88}
\No newline at end of file