UNPKG

apollo-link-retry

Version:

Retry Apollo Link for GraphQL Network Stack

170 lines (163 loc) 6.22 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib = require('tslib'); var apolloLink = require('apollo-link'); function buildDelayFunction(delayOptions) { var _a = delayOptions || {}, _b = _a.initial, initial = _b === void 0 ? 300 : _b, _c = _a.jitter, jitter = _c === void 0 ? true : _c, _d = _a.max, max = _d === void 0 ? Infinity : _d; var baseDelay = jitter ? initial : initial / 2; return function delayFunction(count) { var delay = Math.min(max, baseDelay * Math.pow(2, count)); if (jitter) { delay = Math.random() * delay; } return delay; }; } function buildRetryFunction(retryOptions) { var _a = retryOptions || {}, retryIf = _a.retryIf, _b = _a.max, max = _b === void 0 ? 5 : _b; return function retryFunction(count, operation, error) { if (count >= max) return false; return retryIf ? retryIf(error, operation) : !!error; }; } var RetryableOperation = (function () { function RetryableOperation(operation, nextLink, delayFor, retryIf) { var _this = this; this.operation = operation; this.nextLink = nextLink; this.delayFor = delayFor; this.retryIf = retryIf; this.retryCount = 0; this.values = []; this.complete = false; this.canceled = false; this.observers = []; this.currentSubscription = null; this.onNext = function (value) { _this.values.push(value); for (var _i = 0, _a = _this.observers; _i < _a.length; _i++) { var observer = _a[_i]; if (!observer) continue; observer.next(value); } }; this.onComplete = function () { _this.complete = true; for (var _i = 0, _a = _this.observers; _i < _a.length; _i++) { var observer = _a[_i]; if (!observer) continue; observer.complete(); } }; this.onError = function (error) { return tslib.__awaiter(_this, void 0, void 0, function () { var shouldRetry, _i, _a, observer; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: this.retryCount += 1; return [4, this.retryIf(this.retryCount, this.operation, error)]; case 1: shouldRetry = _b.sent(); if (shouldRetry) { this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error)); return [2]; } this.error = error; for (_i = 0, _a = this.observers; _i < _a.length; _i++) { observer = _a[_i]; if (!observer) continue; observer.error(error); } return [2]; } }); }); }; } RetryableOperation.prototype.subscribe = function (observer) { if (this.canceled) { throw new Error("Subscribing to a retryable link that was canceled is not supported"); } this.observers.push(observer); for (var _i = 0, _a = this.values; _i < _a.length; _i++) { var value = _a[_i]; observer.next(value); } if (this.complete) { observer.complete(); } else if (this.error) { observer.error(this.error); } }; RetryableOperation.prototype.unsubscribe = function (observer) { var index = this.observers.indexOf(observer); if (index < 0) { throw new Error("RetryLink BUG! Attempting to unsubscribe unknown observer!"); } this.observers[index] = null; if (this.observers.every(function (o) { return o === null; })) { this.cancel(); } }; RetryableOperation.prototype.start = function () { if (this.currentSubscription) return; this.try(); }; RetryableOperation.prototype.cancel = function () { if (this.currentSubscription) { this.currentSubscription.unsubscribe(); } clearTimeout(this.timerId); this.timerId = null; this.currentSubscription = null; this.canceled = true; }; RetryableOperation.prototype.try = function () { this.currentSubscription = this.nextLink(this.operation).subscribe({ next: this.onNext, error: this.onError, complete: this.onComplete, }); }; RetryableOperation.prototype.scheduleRetry = function (delay) { var _this = this; if (this.timerId) { throw new Error("RetryLink BUG! Encountered overlapping retries"); } this.timerId = setTimeout(function () { _this.timerId = null; _this.try(); }, delay); }; return RetryableOperation; }()); var RetryLink = (function (_super) { tslib.__extends(RetryLink, _super); function RetryLink(options) { var _this = _super.call(this) || this; var _a = options || {}, attempts = _a.attempts, delay = _a.delay; _this.delayFor = typeof delay === 'function' ? delay : buildDelayFunction(delay); _this.retryIf = typeof attempts === 'function' ? attempts : buildRetryFunction(attempts); return _this; } RetryLink.prototype.request = function (operation, nextLink) { var retryable = new RetryableOperation(operation, nextLink, this.delayFor, this.retryIf); retryable.start(); return new apolloLink.Observable(function (observer) { retryable.subscribe(observer); return function () { retryable.unsubscribe(observer); }; }); }; return RetryLink; }(apolloLink.ApolloLink)); exports.RetryLink = RetryLink; //# sourceMappingURL=bundle.cjs.js.map