Initial Sample.
This commit is contained in:
1 parent
ef2b65f673
commit
5269ec3c66
2575 files changed
+282312
No files matched your search
+40
@@ -0,0 +1,40 @@
|
||||
import type { Operation } from "../core/index.js";
|
||||
/**
|
||||
* Advanced mode: a function that implements the strategy for calculating delays
|
||||
* for particular responses.
|
||||
*/
|
||||
export interface DelayFunction {
|
||||
(count: number, operation: Operation, error: any): number;
|
||||
}
|
||||
export interface DelayFunctionOptions {
|
||||
/**
|
||||
* The number of milliseconds to wait before attempting the first retry.
|
||||
*
|
||||
* Delays will increase exponentially for each attempt. E.g. if this is
|
||||
* set to 100, subsequent retries will be delayed by 200, 400, 800, etc,
|
||||
* until they reach maxDelay.
|
||||
*
|
||||
* Note that if jittering is enabled, this is the _average_ delay.
|
||||
*
|
||||
* Defaults to 300.
|
||||
*/
|
||||
initial?: number;
|
||||
/**
|
||||
* The maximum number of milliseconds that the link should wait for any
|
||||
* retry.
|
||||
*
|
||||
* Defaults to Infinity.
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* Whether delays between attempts should be randomized.
|
||||
*
|
||||
* This helps avoid thundering herd type situations by better distributing
|
||||
* load during major outages.
|
||||
*
|
||||
* Defaults to true.
|
||||
*/
|
||||
jitter?: boolean;
|
||||
}
|
||||
export declare function buildDelayFunction(delayOptions?: DelayFunctionOptions): DelayFunction;
|
||||
//# sourceMappingURL=delayFunction.d.ts.map
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
export 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;
|
||||
// If we're jittering, baseDelay is half of the maximum delay for that
|
||||
// attempt (and is, on average, the delay we will encounter).
|
||||
// If we're not jittering, adjust baseDelay so that the first attempt
|
||||
// lines up with initialDelay, for everyone's sanity.
|
||||
var baseDelay = jitter ? initial : initial / 2;
|
||||
return function delayFunction(count) {
|
||||
var delay = Math.min(max, baseDelay * Math.pow(2, count));
|
||||
if (jitter) {
|
||||
// We opt for a full jitter approach for a mostly uniform distribution,
|
||||
// but bound it within initialDelay and delay for everyone's sanity.
|
||||
delay = Math.random() * delay;
|
||||
}
|
||||
return delay;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=delayFunction.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"delayFunction.js","sourceRoot":"","sources":["../../../src/link/retry/delayFunction.ts"],"names":[],"mappings":"AA2CA,MAAM,UAAU,kBAAkB,CAChC,YAAmC;IAE7B,IAAA,KAAmD,YAAY,IAAI,EAAE,EAAnE,eAAa,EAAb,OAAO,mBAAG,GAAG,KAAA,EAAE,cAAa,EAAb,MAAM,mBAAG,IAAI,KAAA,EAAE,WAAc,EAAd,GAAG,mBAAG,QAAQ,KAAuB,CAAC;IAC5E,sEAAsE;IACtE,6DAA6D;IAC7D,qEAAqE;IACrE,qDAAqD;IACrD,IAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;IAEjD,OAAO,SAAS,aAAa,CAAC,KAAa;QACzC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,GAAG,SAAA,CAAC,EAAI,KAAK,CAAA,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,uEAAuE;YACvE,oEAAoE;YACpE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC;QAChC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Operation } from \"../core/index.js\";\n\n/**\n * Advanced mode: a function that implements the strategy for calculating delays\n * for particular responses.\n */\nexport interface DelayFunction {\n (count: number, operation: Operation, error: any): number;\n}\n\nexport interface DelayFunctionOptions {\n /**\n * The number of milliseconds to wait before attempting the first retry.\n *\n * Delays will increase exponentially for each attempt. E.g. if this is\n * set to 100, subsequent retries will be delayed by 200, 400, 800, etc,\n * until they reach maxDelay.\n *\n * Note that if jittering is enabled, this is the _average_ delay.\n *\n * Defaults to 300.\n */\n initial?: number;\n\n /**\n * The maximum number of milliseconds that the link should wait for any\n * retry.\n *\n * Defaults to Infinity.\n */\n max?: number;\n\n /**\n * Whether delays between attempts should be randomized.\n *\n * This helps avoid thundering herd type situations by better distributing\n * load during major outages.\n *\n * Defaults to true.\n */\n jitter?: boolean;\n}\n\nexport function buildDelayFunction(\n delayOptions?: DelayFunctionOptions\n): DelayFunction {\n const { initial = 300, jitter = true, max = Infinity } = delayOptions || {};\n // If we're jittering, baseDelay is half of the maximum delay for that\n // attempt (and is, on average, the delay we will encounter).\n // If we're not jittering, adjust baseDelay so that the first attempt\n // lines up with initialDelay, for everyone's sanity.\n const baseDelay = jitter ? initial : initial / 2;\n\n return function delayFunction(count: number) {\n let delay = Math.min(max, baseDelay * 2 ** count);\n if (jitter) {\n // We opt for a full jitter approach for a mostly uniform distribution,\n // but bound it within initialDelay and delay for everyone's sanity.\n delay = Math.random() * delay;\n }\n\n return delay;\n };\n}\n"]}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export * from "./retryLink.js";
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export * from "./retryLink.js";
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/link/retry/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC","sourcesContent":["export * from \"./retryLink.js\";\n"]}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@apollo/client/link/retry",
|
||||
"type": "module",
|
||||
"main": "retry.cjs",
|
||||
"module": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"sideEffects": false
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var tslib = require('tslib');
|
||||
var core = require('../core');
|
||||
var utilities = require('../../utilities');
|
||||
|
||||
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(observer, operation, forward, delayFor, retryIf) {
|
||||
var _this = this;
|
||||
this.observer = observer;
|
||||
this.operation = operation;
|
||||
this.forward = forward;
|
||||
this.delayFor = delayFor;
|
||||
this.retryIf = retryIf;
|
||||
this.retryCount = 0;
|
||||
this.currentSubscription = null;
|
||||
this.onError = function (error) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
||||
var shouldRetry;
|
||||
return tslib.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.retryCount += 1;
|
||||
return [4 , this.retryIf(this.retryCount, this.operation, error)];
|
||||
case 1:
|
||||
shouldRetry = _a.sent();
|
||||
if (shouldRetry) {
|
||||
this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));
|
||||
return [2 ];
|
||||
}
|
||||
this.observer.error(error);
|
||||
return [2 ];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
this.try();
|
||||
}
|
||||
RetryableOperation.prototype.cancel = function () {
|
||||
if (this.currentSubscription) {
|
||||
this.currentSubscription.unsubscribe();
|
||||
}
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = undefined;
|
||||
this.currentSubscription = null;
|
||||
};
|
||||
RetryableOperation.prototype.try = function () {
|
||||
this.currentSubscription = this.forward(this.operation).subscribe({
|
||||
next: this.observer.next.bind(this.observer),
|
||||
error: this.onError,
|
||||
complete: this.observer.complete.bind(this.observer),
|
||||
});
|
||||
};
|
||||
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 = undefined;
|
||||
_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 _this = this;
|
||||
return new utilities.Observable(function (observer) {
|
||||
var retryable = new RetryableOperation(observer, operation, nextLink, _this.delayFor, _this.retryIf);
|
||||
return function () {
|
||||
retryable.cancel();
|
||||
};
|
||||
});
|
||||
};
|
||||
return RetryLink;
|
||||
}(core.ApolloLink));
|
||||
|
||||
exports.RetryLink = RetryLink;
|
||||
//# sourceMappingURL=retry.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"retry.cjs","sources":["delayFunction.js","retryFunction.js","retryLink.js"],"sourcesContent":["export function buildDelayFunction(delayOptions) {\n 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;\n // If we're jittering, baseDelay is half of the maximum delay for that\n // attempt (and is, on average, the delay we will encounter).\n // If we're not jittering, adjust baseDelay so that the first attempt\n // lines up with initialDelay, for everyone's sanity.\n var baseDelay = jitter ? initial : initial / 2;\n return function delayFunction(count) {\n var delay = Math.min(max, baseDelay * Math.pow(2, count));\n if (jitter) {\n // We opt for a full jitter approach for a mostly uniform distribution,\n // but bound it within initialDelay and delay for everyone's sanity.\n delay = Math.random() * delay;\n }\n return delay;\n };\n}\n//# sourceMappingURL=delayFunction.js.map","export function buildRetryFunction(retryOptions) {\n var _a = retryOptions || {}, retryIf = _a.retryIf, _b = _a.max, max = _b === void 0 ? 5 : _b;\n return function retryFunction(count, operation, error) {\n if (count >= max)\n return false;\n return retryIf ? retryIf(error, operation) : !!error;\n };\n}\n//# sourceMappingURL=retryFunction.js.map","import { __awaiter, __extends, __generator } from \"tslib\";\nimport { ApolloLink } from \"../core/index.js\";\nimport { Observable } from \"../../utilities/index.js\";\nimport { buildDelayFunction } from \"./delayFunction.js\";\nimport { buildRetryFunction } from \"./retryFunction.js\";\n/**\n * Tracking and management of operations that may be (or currently are) retried.\n */\nvar RetryableOperation = /** @class */ (function () {\n function RetryableOperation(observer, operation, forward, delayFor, retryIf) {\n var _this = this;\n this.observer = observer;\n this.operation = operation;\n this.forward = forward;\n this.delayFor = delayFor;\n this.retryIf = retryIf;\n this.retryCount = 0;\n this.currentSubscription = null;\n this.onError = function (error) { return __awaiter(_this, void 0, void 0, function () {\n var shouldRetry;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n this.retryCount += 1;\n return [4 /*yield*/, this.retryIf(this.retryCount, this.operation, error)];\n case 1:\n shouldRetry = _a.sent();\n if (shouldRetry) {\n this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));\n return [2 /*return*/];\n }\n this.observer.error(error);\n return [2 /*return*/];\n }\n });\n }); };\n this.try();\n }\n /**\n * Stop retrying for the operation, and cancel any in-progress requests.\n */\n RetryableOperation.prototype.cancel = function () {\n if (this.currentSubscription) {\n this.currentSubscription.unsubscribe();\n }\n clearTimeout(this.timerId);\n this.timerId = undefined;\n this.currentSubscription = null;\n };\n RetryableOperation.prototype.try = function () {\n this.currentSubscription = this.forward(this.operation).subscribe({\n next: this.observer.next.bind(this.observer),\n error: this.onError,\n complete: this.observer.complete.bind(this.observer),\n });\n };\n RetryableOperation.prototype.scheduleRetry = function (delay) {\n var _this = this;\n if (this.timerId) {\n throw new Error(\"RetryLink BUG! Encountered overlapping retries\");\n }\n this.timerId = setTimeout(function () {\n _this.timerId = undefined;\n _this.try();\n }, delay);\n };\n return RetryableOperation;\n}());\nvar RetryLink = /** @class */ (function (_super) {\n __extends(RetryLink, _super);\n function RetryLink(options) {\n var _this = _super.call(this) || this;\n var _a = options || {}, attempts = _a.attempts, delay = _a.delay;\n _this.delayFor =\n typeof delay === \"function\" ? delay : buildDelayFunction(delay);\n _this.retryIf =\n typeof attempts === \"function\" ? attempts : buildRetryFunction(attempts);\n return _this;\n }\n RetryLink.prototype.request = function (operation, nextLink) {\n var _this = this;\n return new Observable(function (observer) {\n var retryable = new RetryableOperation(observer, operation, nextLink, Line truncated
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var tslib = require('tslib');
|
||||
var core = require('../core');
|
||||
var utilities = require('../../utilities');
|
||||
|
||||
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(observer, operation, forward, delayFor, retryIf) {
|
||||
var _this = this;
|
||||
this.observer = observer;
|
||||
this.operation = operation;
|
||||
this.forward = forward;
|
||||
this.delayFor = delayFor;
|
||||
this.retryIf = retryIf;
|
||||
this.retryCount = 0;
|
||||
this.currentSubscription = null;
|
||||
this.onError = function (error) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
||||
var shouldRetry;
|
||||
return tslib.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.retryCount += 1;
|
||||
return [4 , this.retryIf(this.retryCount, this.operation, error)];
|
||||
case 1:
|
||||
shouldRetry = _a.sent();
|
||||
if (shouldRetry) {
|
||||
this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));
|
||||
return [2 ];
|
||||
}
|
||||
this.observer.error(error);
|
||||
return [2 ];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
this.try();
|
||||
}
|
||||
RetryableOperation.prototype.cancel = function () {
|
||||
if (this.currentSubscription) {
|
||||
this.currentSubscription.unsubscribe();
|
||||
}
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = undefined;
|
||||
this.currentSubscription = null;
|
||||
};
|
||||
RetryableOperation.prototype.try = function () {
|
||||
this.currentSubscription = this.forward(this.operation).subscribe({
|
||||
next: this.observer.next.bind(this.observer),
|
||||
error: this.onError,
|
||||
complete: this.observer.complete.bind(this.observer),
|
||||
});
|
||||
};
|
||||
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 = undefined;
|
||||
_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 _this = this;
|
||||
return new utilities.Observable(function (observer) {
|
||||
var retryable = new RetryableOperation(observer, operation, nextLink, _this.delayFor, _this.retryIf);
|
||||
return function () {
|
||||
retryable.cancel();
|
||||
};
|
||||
});
|
||||
};
|
||||
return RetryLink;
|
||||
}(core.ApolloLink));
|
||||
|
||||
exports.RetryLink = RetryLink;
|
||||
//# sourceMappingURL=retry.cjs.map
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import type { Operation } from "../core/index.js";
|
||||
/**
|
||||
* Advanced mode: a function that determines both whether a particular
|
||||
* response should be retried.
|
||||
*/
|
||||
export interface RetryFunction {
|
||||
(count: number, operation: Operation, error: any): boolean | Promise<boolean>;
|
||||
}
|
||||
export interface RetryFunctionOptions {
|
||||
/**
|
||||
* The max number of times to try a single operation before giving up.
|
||||
*
|
||||
* Note that this INCLUDES the initial request as part of the count.
|
||||
* E.g. maxTries of 1 indicates no retrying should occur.
|
||||
*
|
||||
* Defaults to 5. Pass Infinity for infinite retries.
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* Predicate function that determines whether a particular error should
|
||||
* trigger a retry.
|
||||
*
|
||||
* For example, you may want to not retry 4xx class HTTP errors.
|
||||
*
|
||||
* By default, all errors are retried.
|
||||
*/
|
||||
retryIf?: (error: any, operation: Operation) => boolean | Promise<boolean>;
|
||||
}
|
||||
export declare function buildRetryFunction(retryOptions?: RetryFunctionOptions): RetryFunction;
|
||||
//# sourceMappingURL=retryFunction.d.ts.map
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export 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;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=retryFunction.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"retryFunction.js","sourceRoot":"","sources":["../../../src/link/retry/retryFunction.ts"],"names":[],"mappings":"AAgCA,MAAM,UAAU,kBAAkB,CAChC,YAAmC;IAE7B,IAAA,KAAuB,YAAY,IAAK,EAA2B,EAAjE,OAAO,aAAA,EAAE,WAAO,EAAP,GAAG,mBAAG,CAAC,KAAiD,CAAC;IAC1E,OAAO,SAAS,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK;QACnD,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,KAAK,CAAC;QAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Operation } from \"../core/index.js\";\n\n/**\n * Advanced mode: a function that determines both whether a particular\n * response should be retried.\n */\nexport interface RetryFunction {\n (count: number, operation: Operation, error: any): boolean | Promise<boolean>;\n}\n\nexport interface RetryFunctionOptions {\n /**\n * The max number of times to try a single operation before giving up.\n *\n * Note that this INCLUDES the initial request as part of the count.\n * E.g. maxTries of 1 indicates no retrying should occur.\n *\n * Defaults to 5. Pass Infinity for infinite retries.\n */\n max?: number;\n\n /**\n * Predicate function that determines whether a particular error should\n * trigger a retry.\n *\n * For example, you may want to not retry 4xx class HTTP errors.\n *\n * By default, all errors are retried.\n */\n retryIf?: (error: any, operation: Operation) => boolean | Promise<boolean>;\n}\n\nexport function buildRetryFunction(\n retryOptions?: RetryFunctionOptions\n): RetryFunction {\n const { retryIf, max = 5 } = retryOptions || ({} as RetryFunctionOptions);\n return function retryFunction(count, operation, error) {\n if (count >= max) return false;\n return retryIf ? retryIf(error, operation) : !!error;\n };\n}\n"]}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import type { Operation, FetchResult, NextLink } from "../core/index.js";
|
||||
import { ApolloLink } from "../core/index.js";
|
||||
import { Observable } from "../../utilities/index.js";
|
||||
import type { DelayFunction, DelayFunctionOptions } from "./delayFunction.js";
|
||||
import type { RetryFunction, RetryFunctionOptions } from "./retryFunction.js";
|
||||
export declare namespace RetryLink {
|
||||
interface Options {
|
||||
/**
|
||||
* Configuration for the delay strategy to use, or a custom delay strategy.
|
||||
*/
|
||||
delay?: DelayFunctionOptions | DelayFunction;
|
||||
/**
|
||||
* Configuration for the retry strategy to use, or a custom retry strategy.
|
||||
*/
|
||||
attempts?: RetryFunctionOptions | RetryFunction;
|
||||
}
|
||||
}
|
||||
export declare class RetryLink extends ApolloLink {
|
||||
private delayFor;
|
||||
private retryIf;
|
||||
constructor(options?: RetryLink.Options);
|
||||
request(operation: Operation, nextLink: NextLink): Observable<FetchResult>;
|
||||
}
|
||||
//# sourceMappingURL=retryLink.d.ts.map
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import { __awaiter, __extends, __generator } from "tslib";
|
||||
import { ApolloLink } from "../core/index.js";
|
||||
import { Observable } from "../../utilities/index.js";
|
||||
import { buildDelayFunction } from "./delayFunction.js";
|
||||
import { buildRetryFunction } from "./retryFunction.js";
|
||||
/**
|
||||
* Tracking and management of operations that may be (or currently are) retried.
|
||||
*/
|
||||
var RetryableOperation = /** @class */ (function () {
|
||||
function RetryableOperation(observer, operation, forward, delayFor, retryIf) {
|
||||
var _this = this;
|
||||
this.observer = observer;
|
||||
this.operation = operation;
|
||||
this.forward = forward;
|
||||
this.delayFor = delayFor;
|
||||
this.retryIf = retryIf;
|
||||
this.retryCount = 0;
|
||||
this.currentSubscription = null;
|
||||
this.onError = function (error) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var shouldRetry;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.retryCount += 1;
|
||||
return [4 /*yield*/, this.retryIf(this.retryCount, this.operation, error)];
|
||||
case 1:
|
||||
shouldRetry = _a.sent();
|
||||
if (shouldRetry) {
|
||||
this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));
|
||||
return [2 /*return*/];
|
||||
}
|
||||
this.observer.error(error);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
this.try();
|
||||
}
|
||||
/**
|
||||
* Stop retrying for the operation, and cancel any in-progress requests.
|
||||
*/
|
||||
RetryableOperation.prototype.cancel = function () {
|
||||
if (this.currentSubscription) {
|
||||
this.currentSubscription.unsubscribe();
|
||||
}
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = undefined;
|
||||
this.currentSubscription = null;
|
||||
};
|
||||
RetryableOperation.prototype.try = function () {
|
||||
this.currentSubscription = this.forward(this.operation).subscribe({
|
||||
next: this.observer.next.bind(this.observer),
|
||||
error: this.onError,
|
||||
complete: this.observer.complete.bind(this.observer),
|
||||
});
|
||||
};
|
||||
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 = undefined;
|
||||
_this.try();
|
||||
}, delay);
|
||||
};
|
||||
return RetryableOperation;
|
||||
}());
|
||||
var RetryLink = /** @class */ (function (_super) {
|
||||
__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 _this = this;
|
||||
return new Observable(function (observer) {
|
||||
var retryable = new RetryableOperation(observer, operation, nextLink, _this.delayFor, _this.retryIf);
|
||||
return function () {
|
||||
retryable.cancel();
|
||||
};
|
||||
});
|
||||
};
|
||||
return RetryLink;
|
||||
}(ApolloLink));
|
||||
export { RetryLink };
|
||||
//# sourceMappingURL=retryLink.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"retryLink.js","sourceRoot":"","sources":["../../../src/link/retry/retryLink.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Operation, FetchResult, NextLink } from \"../core/index.js\";\nimport { ApolloLink } from \"../core/index.js\";\nimport type { ObservableSubscription } from \"../../utilities/index.js\";\nimport { Observable } from \"../../utilities/index.js\";\nimport type { DelayFunction, DelayFunctionOptions } from \"./delayFunction.js\";\nimport { buildDelayFunction } from \"./delayFunction.js\";\nimport type { RetryFunction, RetryFunctionOptions } from \"./retryFunction.js\";\nimport { buildRetryFunction } from \"./retryFunction.js\";\nimport type { SubscriptionObserver } from \"zen-observable-ts\";\n\nexport namespace RetryLink {\n export interface Options {\n /**\n * Configuration for the delay strategy to use, or a custom delay strategy.\n */\n delay?: DelayFunctionOptions | DelayFunction;\n\n /**\n * Configuration for the retry strategy to use, or a custom retry strategy.\n */\n attempts?: RetryFunctionOptions | RetryFunction;\n }\n}\n\n/**\n * Tracking and management of operations that may be (or currently are) retried.\n */\nclass RetryableOperation {\n private retryCount: number = 0;\n private currentSubscription: ObservableSubscription | null = null;\n private timerId: number | undefined;\n\n constructor(\n private observer: SubscriptionObserver<FetchResult>,\n private operation: Operation,\n private forward: NextLink,\n private delayFor: DelayFunction,\n private retryIf: RetryFunction\n ) {\n this.try();\n }\n\n /**\n * Stop retrying for the operation, and cancel any in-progress requests.\n */\n public cancel() {\n if (this.currentSubscription) {\n this.currentSubscription.unsubscribe();\n }\n clearTimeout(this.timerId);\n this.timerId = undefined;\n this.currentSubscription = null;\n }\n\n private try() {\n this.currentSubscription = this.forward(this.operation).subscribe({\n next: this.observer.next.bind(this.observer),\n error: this.onError,\n complete: this.observer.complete.bind(this.observer),\n });\n }\n\n private onError = async (error: any) => {\n this.retryCount += 1;\n\n // Should we retry?\n const shouldRetry = await this.retryIf(\n this.retryCount,\n this.operation,\n error\n );\n if (shouldRetry) {\n this.scheduleRetry(this.delayFor(this.retryCount, this.operation, error));\n return;\n }\n\n tLine truncated
|
||||
Reference in new issue
Block a user