UNPKG

@emeraldpay/api

Version:
128 lines 4.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OnceSuccess = exports.AlwaysRepeat = exports.Retry = exports.isContinueCheck = void 0; const Channel_1 = require("./Channel"); const Executor_1 = require("./Executor"); function isContinueCheck(checker) { return (typeof checker === 'object' && checker != null && 'shouldContinue' in checker && typeof checker.shouldContinue === 'function'); } exports.isContinueCheck = isContinueCheck; class Retry { constructor(channel, executor, checker) { this.status = Channel_1.ConnectionStatus.PENDING; if (channel == null || !(0, Channel_1.isChannel)(channel)) { throw new Error('Channel is not provided'); } if (executor == null || !(0, Executor_1.isMethodExecutor)(executor)) { throw new Error('Executor is not provided'); } if (checker == null || !isContinueCheck(checker)) { throw new Error('Continue checker is not provided'); } this.channel = channel; this.checker = checker; this.executor = executor; } callWhenReady() { if (!this.checker.shouldContinue()) { this.notify(Channel_1.ConnectionStatus.CLOSED); if (this.checker.failed === true) { this.executor.terminate(); } return; } this.notify(Channel_1.ConnectionStatus.CONNECTING); const connection = this.channel.getState(); const isReady = (state, retry) => { var _a, _b, _c, _d; if (state === Channel_1.ConnectivityState.READY) { (_b = (_a = this.checker).onConnected) === null || _b === void 0 ? void 0 : _b.call(_a); this.executor.connected(); return true; } if (state === Channel_1.ConnectivityState.SHUTDOWN) { this.checker.onClose(); return false; } if (state === Channel_1.ConnectivityState.TRANSIENT_FAILURE) { (_d = (_c = this.checker).onFail) === null || _d === void 0 ? void 0 : _d.call(_c); } if (retry) { setTimeout(this.callWhenReady.bind(this), 1000, this.executor, this.checker); } return false; }; const execute = () => this.executor.execute(() => { this.notify(Channel_1.ConnectionStatus.CONNECTING); setTimeout(this.callWhenReady.bind(this), 1000, this.executor, this.checker); }); if (isReady(connection, false)) { this.notify(Channel_1.ConnectionStatus.CONNECTED); execute(); } else { this.notify(Channel_1.ConnectionStatus.CONNECTING); this.channel.watch(connection, 5000, (error, state) => { var _a, _b; if (error != null) { (_b = (_a = this.checker).onFail) === null || _b === void 0 ? void 0 : _b.call(_a); } if (isReady(state, true)) { execute(); } }); } } setConnectionListener(listener) { this.statusListener = listener; listener(this.status); } notify(status) { var _a; if (status != this.status) { this.status = status; } (_a = this.statusListener) === null || _a === void 0 ? void 0 : _a.call(this, status); } } exports.Retry = Retry; class AlwaysRepeat { constructor(retries) { this.counter = 0; this.closed = false; this.retries = retries; } get failed() { return this.counter >= this.retries; } shouldContinue() { return !this.failed && !this.closed; } onFail() { this.counter += 1; } onClose() { this.closed = true; } onSuccess() { this.counter = 0; } } exports.AlwaysRepeat = AlwaysRepeat; class OnceSuccess extends AlwaysRepeat { constructor() { super(...arguments); this.succeed = false; } shouldContinue() { return !this.failed && !this.closed && !this.succeed; } onSuccess() { this.succeed = true; } } exports.OnceSuccess = OnceSuccess; //# sourceMappingURL=Retry.js.map