UNPKG

6.26 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var tslib = require('tslib');
6var core = require('../core');
7var utilities = require('../../utilities');
8
9function buildDelayFunction(delayOptions) {
10 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;
11 var baseDelay = jitter ? initial : initial / 2;
12 return function delayFunction(count) {
13 var delay = Math.min(max, baseDelay * Math.pow(2, count));
14 if (jitter) {
15 delay = Math.random() * delay;
16 }
17 return delay;
18 };
19}
20
21function buildRetryFunction(retryOptions) {
22 var _a = retryOptions || {}, retryIf = _a.retryIf, _b = _a.max, max = _b === void 0 ? 5 : _b;
23 return function retryFunction(count, operation, error) {
24 if (count >= max)
25 return false;
26 return retryIf ? retryIf(error, operation) : !!error;
27 };
28}
29
30var RetryableOperation = (function () {
31 function RetryableOperation(operation, nextLink, delayFor, retryIf) {
32 var _this = this;
33 this.operation = operation;
34 this.nextLink = nextLink;
35 this.delayFor = delayFor;
36 this.retryIf = retryIf;
37 this.retryCount = 0;
38 this.values = [];
39 this.complete = false;
40 this.canceled = false;
41 this.observers = [];
42 this.currentSubscription = null;
43 this.onNext = function (value) {
44 _this.values.push(value);
45 for (var _i = 0, _a = _this.observers; _i < _a.length; _i++) {
46 var observer = _a[_i];
47 if (!observer)
48 continue;
49 observer.next(value);
50 }
51 };
52 this.onComplete = function () {
53 _this.complete = true;
54 for (var _i = 0, _a = _this.observers; _i < _a.length; _i++) {
55 var observer = _a[_i];
56 if (!observer)
57 continue;
58 observer.complete();
59 }
60 };
61 this.onError = function (error) { return tslib.__awaiter(_this, void 0, void 0, function () {
62 var shouldRetry, _i, _a, observer;
63 return tslib.__generator(this, function (_b) {
64 switch (_b.label) {
65 case 0:
66 this.retryCount += 1;
67 return [4, this.retryIf(this.retryCount, this.operation, error)];
68 case 1:
69 shouldRetry = _b.sent();
70 if (shouldRetry) {
71 this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));
72 return [2];
73 }
74 this.error = error;
75 for (_i = 0, _a = this.observers; _i < _a.length; _i++) {
76 observer = _a[_i];
77 if (!observer)
78 continue;
79 observer.error(error);
80 }
81 return [2];
82 }
83 });
84 }); };
85 }
86 RetryableOperation.prototype.subscribe = function (observer) {
87 if (this.canceled) {
88 throw new Error("Subscribing to a retryable link that was canceled is not supported");
89 }
90 this.observers.push(observer);
91 for (var _i = 0, _a = this.values; _i < _a.length; _i++) {
92 var value = _a[_i];
93 observer.next(value);
94 }
95 if (this.complete) {
96 observer.complete();
97 }
98 else if (this.error) {
99 observer.error(this.error);
100 }
101 };
102 RetryableOperation.prototype.unsubscribe = function (observer) {
103 var index = this.observers.indexOf(observer);
104 if (index < 0) {
105 throw new Error("RetryLink BUG! Attempting to unsubscribe unknown observer!");
106 }
107 this.observers[index] = null;
108 if (this.observers.every(function (o) { return o === null; })) {
109 this.cancel();
110 }
111 };
112 RetryableOperation.prototype.start = function () {
113 if (this.currentSubscription)
114 return;
115 this.try();
116 };
117 RetryableOperation.prototype.cancel = function () {
118 if (this.currentSubscription) {
119 this.currentSubscription.unsubscribe();
120 }
121 clearTimeout(this.timerId);
122 this.timerId = undefined;
123 this.currentSubscription = null;
124 this.canceled = true;
125 };
126 RetryableOperation.prototype.try = function () {
127 this.currentSubscription = this.nextLink(this.operation).subscribe({
128 next: this.onNext,
129 error: this.onError,
130 complete: this.onComplete,
131 });
132 };
133 RetryableOperation.prototype.scheduleRetry = function (delay) {
134 var _this = this;
135 if (this.timerId) {
136 throw new Error("RetryLink BUG! Encountered overlapping retries");
137 }
138 this.timerId = setTimeout(function () {
139 _this.timerId = undefined;
140 _this.try();
141 }, delay);
142 };
143 return RetryableOperation;
144}());
145var RetryLink = (function (_super) {
146 tslib.__extends(RetryLink, _super);
147 function RetryLink(options) {
148 var _this = _super.call(this) || this;
149 var _a = options || {}, attempts = _a.attempts, delay = _a.delay;
150 _this.delayFor =
151 typeof delay === 'function' ? delay : buildDelayFunction(delay);
152 _this.retryIf =
153 typeof attempts === 'function' ? attempts : buildRetryFunction(attempts);
154 return _this;
155 }
156 RetryLink.prototype.request = function (operation, nextLink) {
157 var retryable = new RetryableOperation(operation, nextLink, this.delayFor, this.retryIf);
158 retryable.start();
159 return new utilities.Observable(function (observer) {
160 retryable.subscribe(observer);
161 return function () {
162 retryable.unsubscribe(observer);
163 };
164 });
165 };
166 return RetryLink;
167}(core.ApolloLink));
168
169exports.RetryLink = RetryLink;
170//# sourceMappingURL=retry.cjs.map