apollo-link-retry
Version:
Retry Apollo Link for GraphQL Network Stack
146 lines • 5.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var apollo_link_1 = require("apollo-link");
var delayFunction_1 = require("./delayFunction");
var retryFunction_1 = require("./retryFunction");
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_1.__awaiter(_this, void 0, void 0, function () {
var shouldRetry, _i, _a, observer;
return tslib_1.__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_1.__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 : delayFunction_1.buildDelayFunction(delay);
_this.retryIf =
typeof attempts === 'function' ? attempts : retryFunction_1.buildRetryFunction(attempts);
return _this;
}
RetryLink.prototype.request = function (operation, nextLink) {
var retryable = new RetryableOperation(operation, nextLink, this.delayFor, this.retryIf);
retryable.start();
return new apollo_link_1.Observable(function (observer) {
retryable.subscribe(observer);
return function () {
retryable.unsubscribe(observer);
};
});
};
return RetryLink;
}(apollo_link_1.ApolloLink));
exports.RetryLink = RetryLink;
//# sourceMappingURL=retryLink.js.map