@clerk/shared
Version:
Internal package utils used by the Clerk SDKs
1 lines • 4.78 kB
Source Map (JSON)
{"version":3,"file":"retry.mjs","names":[],"sources":["../src/retry.ts"],"sourcesContent":["type Milliseconds = number;\n\ntype RetryOptions = Partial<{\n /**\n * The initial delay before the first retry.\n *\n * @default 125\n */\n initialDelay: Milliseconds;\n /**\n * The maximum delay between retries.\n * The delay between retries will never exceed this value.\n * If set to 0, the delay will increase indefinitely.\n *\n * @default 0\n */\n maxDelayBetweenRetries: Milliseconds;\n /**\n * The multiplier for the exponential backoff.\n *\n * @default 2\n */\n factor: number;\n /**\n * A function to determine if the operation should be retried.\n * The callback accepts the error that was thrown and the number of iterations.\n * The iterations variable references the number of retries AFTER attempt\n * that caused the error and starts at 1 (as in, this is the 1st, 2nd, nth retry).\n *\n * @default (error, iterations) => iterations < 5\n */\n shouldRetry: (error: unknown, iterations: number) => boolean;\n /**\n * Controls whether the helper should retry the operation immediately once before applying exponential backoff.\n * The delay for the immediate retry is 100ms.\n *\n * @default false\n */\n retryImmediately: boolean;\n /**\n * If true, the intervals will be multiplied by a factor in the range of [1,2].\n *\n * @default true\n */\n jitter: boolean;\n\n /**\n * A callback that is invoked before each retry attempt.\n * The callback receives the iteration number (starting from 1 for the first retry).\n * This can be used to modify request parameters, add headers, etc.\n */\n onBeforeRetry?: (iteration: number) => void | Promise<void>;\n}>;\n\nconst defaultOptions = {\n initialDelay: 125,\n maxDelayBetweenRetries: 0,\n factor: 2,\n shouldRetry: (_: unknown, iteration: number) => iteration < 5,\n retryImmediately: false,\n jitter: true,\n};\n\nconst RETRY_IMMEDIATELY_DELAY = 100;\n\nconst sleep = async (ms: Milliseconds) => new Promise(s => setTimeout(s, ms));\n\nconst applyJitter = (delay: Milliseconds, jitter: boolean) => {\n return jitter ? delay * (1 + Math.random()) : delay;\n};\n\nconst createExponentialDelayAsyncFn = (\n opts: Required<Pick<RetryOptions, 'initialDelay' | 'maxDelayBetweenRetries' | 'factor' | 'jitter'>>,\n) => {\n let timesCalled = 0;\n\n const calculateDelayInMs = () => {\n const constant = opts.initialDelay;\n const base = opts.factor;\n let delay = constant * Math.pow(base, timesCalled);\n delay = applyJitter(delay, opts.jitter);\n return Math.min(opts.maxDelayBetweenRetries || delay, delay);\n };\n\n return async (): Promise<void> => {\n await sleep(calculateDelayInMs());\n timesCalled++;\n };\n};\n\n/**\n * Retries a callback until it succeeds or the shouldRetry function returns false.\n * See {@link RetryOptions} for the available options.\n */\nexport const retry = async <T>(callback: () => T | Promise<T>, options: RetryOptions = {}): Promise<T> => {\n let iterations = 0;\n const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter, onBeforeRetry } = {\n ...defaultOptions,\n ...options,\n };\n\n const delay = createExponentialDelayAsyncFn({\n initialDelay,\n maxDelayBetweenRetries,\n factor,\n jitter,\n });\n\n while (true) {\n try {\n return await callback();\n } catch (e) {\n iterations++;\n if (!shouldRetry(e, iterations)) {\n throw e;\n }\n\n if (onBeforeRetry) {\n await onBeforeRetry(iterations);\n }\n\n if (retryImmediately && iterations === 1) {\n await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));\n } else {\n await delay();\n }\n }\n }\n};\n"],"mappings":";AAsDA,MAAM,iBAAiB;CACrB,cAAc;CACd,wBAAwB;CACxB,QAAQ;CACR,cAAc,GAAY,cAAsB,YAAY;CAC5D,kBAAkB;CAClB,QAAQ;AACV;AAEA,MAAM,0BAA0B;AAEhC,MAAM,QAAQ,OAAO,OAAqB,IAAI,SAAQ,MAAK,WAAW,GAAG,EAAE,CAAC;AAE5E,MAAM,eAAe,OAAqB,WAAoB;CAC5D,OAAO,SAAS,SAAS,IAAI,KAAK,OAAO,KAAK;AAChD;AAEA,MAAM,iCACJ,SACG;CACH,IAAI,cAAc;CAElB,MAAM,2BAA2B;EAC/B,MAAM,WAAW,KAAK;EACtB,MAAM,OAAO,KAAK;EAClB,IAAI,QAAQ,WAAW,KAAK,IAAI,MAAM,WAAW;EACjD,QAAQ,YAAY,OAAO,KAAK,MAAM;EACtC,OAAO,KAAK,IAAI,KAAK,0BAA0B,OAAO,KAAK;CAC7D;CAEA,OAAO,YAA2B;EAChC,MAAM,MAAM,mBAAmB,CAAC;EAChC;CACF;AACF;;;;;AAMA,MAAa,QAAQ,OAAU,UAAgC,UAAwB,CAAC,MAAkB;CACxG,IAAI,aAAa;CACjB,MAAM,EAAE,aAAa,cAAc,wBAAwB,QAAQ,kBAAkB,QAAQ,kBAAkB;EAC7G,GAAG;EACH,GAAG;CACL;CAEA,MAAM,QAAQ,8BAA8B;EAC1C;EACA;EACA;EACA;CACF,CAAC;CAED,OAAO,MACL,IAAI;EACF,OAAO,MAAM,SAAS;CACxB,SAAS,GAAG;EACV;EACA,IAAI,CAAC,YAAY,GAAG,UAAU,GAC5B,MAAM;EAGR,IAAI,eACF,MAAM,cAAc,UAAU;EAGhC,IAAI,oBAAoB,eAAe,GACrC,MAAM,MAAM,YAAY,yBAAyB,MAAM,CAAC;OAExD,MAAM,MAAM;CAEhB;AAEJ"}