2022-08-28 06:33:49 +00:00
|
|
|
import { clearTimeout, setTimeout } from "timers";
|
|
|
|
export default class RpcQueryBase {
|
|
|
|
_network;
|
|
|
|
_query;
|
|
|
|
_options;
|
|
|
|
_promise;
|
|
|
|
_timeoutTimer;
|
|
|
|
_timeout = false;
|
|
|
|
_completed = false;
|
2022-12-04 07:42:04 +00:00
|
|
|
_response;
|
|
|
|
_error;
|
2022-08-28 06:33:49 +00:00
|
|
|
_promiseResolve;
|
2023-03-18 16:11:41 +00:00
|
|
|
constructor({ network, query, options = {}, }) {
|
2022-08-28 06:33:49 +00:00
|
|
|
this._network = network;
|
|
|
|
this._query = query;
|
|
|
|
this._options = options;
|
|
|
|
}
|
|
|
|
get result() {
|
|
|
|
return this._promise;
|
|
|
|
}
|
|
|
|
handeTimeout() {
|
|
|
|
this.resolve(undefined, true);
|
|
|
|
}
|
|
|
|
resolve(data, timeout = false) {
|
|
|
|
clearTimeout(this._timeoutTimer);
|
|
|
|
this._timeout = timeout;
|
|
|
|
this._completed = true;
|
|
|
|
if (timeout) {
|
|
|
|
data = {
|
|
|
|
error: "timeout",
|
|
|
|
};
|
|
|
|
}
|
|
|
|
this._promiseResolve?.(data);
|
|
|
|
}
|
|
|
|
run() {
|
|
|
|
this._promise =
|
|
|
|
this._promise ??
|
|
|
|
new Promise((resolve) => {
|
|
|
|
this._promiseResolve = resolve;
|
|
|
|
});
|
|
|
|
this._timeoutTimer =
|
|
|
|
this._timeoutTimer ??
|
2022-12-04 07:42:04 +00:00
|
|
|
setTimeout(this.handeTimeout.bind(this), (this._options?.queryTimeout || this._network.queryTimeout) * 1000);
|
|
|
|
this._doRun();
|
2022-08-28 06:33:49 +00:00
|
|
|
return this;
|
|
|
|
}
|
2022-12-04 07:42:04 +00:00
|
|
|
async _doRun() {
|
2022-08-28 06:33:49 +00:00
|
|
|
try {
|
2022-12-04 07:42:04 +00:00
|
|
|
await this._network.ready;
|
|
|
|
await this._run();
|
2022-08-28 06:33:49 +00:00
|
|
|
}
|
|
|
|
catch (e) {
|
2022-12-04 12:19:13 +00:00
|
|
|
this._promiseResolve?.({ error: e?.message || e?.error });
|
2022-08-28 06:33:49 +00:00
|
|
|
}
|
2022-12-04 07:42:04 +00:00
|
|
|
}
|
|
|
|
setupRelayTimeout(reject) {
|
|
|
|
return setTimeout(() => {
|
|
|
|
this._error = "timeout";
|
|
|
|
reject("timeout");
|
|
|
|
}, (this._options.relayTimeout || this._network.relayTimeout) * 1000);
|
|
|
|
}
|
|
|
|
async queryRpc(rpc, request) {
|
|
|
|
let timer;
|
2022-08-28 06:33:49 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
2022-12-04 07:42:04 +00:00
|
|
|
rpc
|
|
|
|
// @ts-ignore
|
|
|
|
.request(`${request.module}.${request.method}`, request.data)
|
|
|
|
.then((resp) => {
|
|
|
|
if (resp.error) {
|
|
|
|
throw new Error(resp.error);
|
2022-08-28 06:33:49 +00:00
|
|
|
}
|
2022-12-04 07:42:04 +00:00
|
|
|
clearTimeout(timer);
|
|
|
|
this._response = resp;
|
2022-08-28 06:33:49 +00:00
|
|
|
resolve(null);
|
2022-12-04 07:42:04 +00:00
|
|
|
})
|
|
|
|
.catch((e) => {
|
|
|
|
this._error = e.message;
|
|
|
|
reject({ error: e.message });
|
|
|
|
clearTimeout(timer);
|
2022-08-28 06:33:49 +00:00
|
|
|
});
|
2022-12-04 07:42:04 +00:00
|
|
|
timer = this.setupRelayTimeout(reject);
|
2022-08-28 06:33:49 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|