1 | {"version":3,"file":"bundle.umd.js","sources":["../src/delayFunction.ts","../src/retryFunction.ts","../src/retryLink.ts"],"sourcesContent":["import { Operation } from 'apollo-link';\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","import { Operation } from 'apollo-link';\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","import {\n ApolloLink,\n Observable,\n Operation,\n NextLink,\n FetchResult,\n} from 'apollo-link';\n\nimport {\n DelayFunction,\n DelayFunctionOptions,\n buildDelayFunction,\n} from './delayFunction';\nimport {\n RetryFunction,\n RetryFunctionOptions,\n buildRetryFunction,\n} from './retryFunction';\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<TValue = any> {\n private retryCount: number = 0;\n private values: any[] = [];\n private error: any;\n private complete = false;\n private canceled = false;\n private observers: ZenObservable.Observer<TValue>[] = [];\n private currentSubscription: ZenObservable.Subscription = null;\n private timerId: number;\n\n constructor(\n private operation: Operation,\n private nextLink: NextLink,\n private delayFor: DelayFunction,\n private retryIf: RetryFunction,\n ) {}\n\n /**\n * Register a new observer for this operation.\n *\n * If the operation has previously emitted other events, they will be\n * immediately triggered for the observer.\n */\n public subscribe(observer: ZenObservable.Observer<TValue>) {\n if (this.canceled) {\n throw new Error(\n `Subscribing to a retryable link that was canceled is not supported`,\n );\n }\n this.observers.push(observer);\n\n // If we've already begun, catch this observer up.\n for (const value of this.values) {\n observer.next(value);\n }\n\n if (this.complete) {\n observer.complete();\n } else if (this.error) {\n observer.error(this.error);\n }\n }\n\n /**\n * Remove a previously registered observer from this operation.\n *\n * If no observers remain, the operation will stop retrying, and unsubscribe\n * from its downstream link.\n */\n public unsubscribe(observer: ZenObservable.Observer<TValue>) {\n const index = this.observers.indexOf(observer);\n if (index < 0) {\n throw new Error(\n `RetryLink BUG! Attempting to unsubscribe unknown observer!`,\n );\n }\n // Note that we are careful not to change the order of length of the array,\n // as we are often mid-iteration when calling this method.\n this.observers[index] = null;\n\n // If this is the last observer, we're done.\n if (this.observers.every(o => o === null)) {\n this.cancel();\n }\n }\n\n /**\n * Start the initial request.\n */\n public start() {\n if (this.currentSubscription) return; // Already started.\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 = null;\n this.currentSubscription = null;\n this.canceled = true;\n }\n\n private try() {\n this.currentSubscription = this.nextLink(this.operation).subscribe({\n next: this.onNext,\n error: this.onError,\n complete: this.onComplete,\n });\n }\n\n private onNext = (value: any) => {\n this.values.push(value);\n for (const observer of this.observers) {\n if (!observer) continue;\n observer.next(value);\n }\n };\n\n private onComplete = () => {\n this.complete = true;\n for (const observer of this.observers) {\n if (!observer) continue;\n observer.complete();\n }\n };\n\n private onError = async error => {\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 this.error = error;\n for (const observer of this.observers) {\n if (!observer) continue;\n observer.error(error);\n }\n };\n\n private scheduleRetry(delay) {\n if (this.timerId) {\n throw new Error(`RetryLink BUG! Encountered overlapping retries`);\n }\n\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.try();\n }, delay);\n }\n}\n\nexport class RetryLink extends ApolloLink {\n private delayFor: DelayFunction;\n private retryIf: RetryFunction;\n\n constructor(options?: RetryLink.Options) {\n super();\n const { attempts, delay } = options || ({} as RetryLink.Options);\n this.delayFor =\n typeof delay === 'function' ? delay : buildDelayFunction(delay);\n this.retryIf =\n typeof attempts === 'function' ? attempts : buildRetryFunction(attempts);\n }\n\n public request(\n operation: Operation,\n nextLink: NextLink,\n ): Observable<FetchResult> {\n const retryable = new RetryableOperation(\n operation,\n nextLink,\n this.delayFor,\n this.retryIf,\n );\n retryable.start();\n\n return new Observable(observer => {\n retryable.subscribe(observer);\n return () => {\n retryable.unsubscribe(observer);\n };\n });\n }\n}\n"],"names":["tslib_1.__extends","Observable","ApolloLink"],"mappings":"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"} |