Initial Sample.

This commit is contained in:
2024-06-03 20:23:50 +05:30
parent ef2b65f673
commit 5269ec3c66
2575 changed files with 282312 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"]}

View File

@@ -0,0 +1,2 @@
export * from "./retryLink.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,2 @@
export * from "./retryLink.js";
//# sourceMappingURL=index.js.map

View File

@@ -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"]}

View File

@@ -0,0 +1,8 @@
{
"name": "@apollo/client/link/retry",
"type": "module",
"main": "retry.cjs",
"module": "index.js",
"types": "index.d.ts",
"sideEffects": false
}

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"]}

View File

@@ -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

View File

@@ -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

File diff suppressed because one or more lines are too long