{"version":3,"sources":["../../src/shared/retryWithBackoff.ts"],"names":["timeBeforeNextRetry","opts","numberOfErrors","minWaitTime","waitTimeOnFirstError","Math","min","waitTimeOnBackoff","maxWaitTime","retryWithBackoff","optsRaw","shouldRetry","_info","resetErrorsOnNext","sourceDescription","logger","log","info","error","toFixed","recursiveObserve","errors","source","reset","pipe","stream","time","Promise","reject"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AAqBA,SAASA,mBAAT,CAA6BC,IAA7B,EAAkDC,cAAlD,EAA0E;AACxE,SACED,IAAI,CAACE,WAAL,IACCD,cAAc,KAAK,CAAnB,GACGD,IAAI,CAACG,oBADR,GAEGC,IAAI,CAACC,GAAL,CAASL,IAAI,CAACM,iBAAL,GAAyBL,cAAlC,EAAkDD,IAAI,CAACO,WAAvD,CAHJ,CADF;AAMD;;AAEM,SAASC,gBAAT,CAA6BC,OAA7B,EAAkD;AAAA;;AACvD,QAAMT,IAAmB,GAAG;AAC1BU,IAAAA,WAAW,EAAEC,KAAK,IAAI;AACpB,aAAO,IAAP;AACD,KAHyB;AAI1BC,IAAAA,iBAAiB,EAAE,IAJO;AAK1BT,IAAAA,oBAAoB,EAAE,IAAI,IALA;AAM1BG,IAAAA,iBAAiB,EAAE,IAAI,IANG;AAO1BJ,IAAAA,WAAW,EAAE,CAPa;AAQ1BK,IAAAA,WAAW,EAAE,IAAI,EAAJ,GAAS,EAAT,GAAc,IARD;AAS1BM,IAAAA,iBAAiB,EAAE,SATO;AAU1B,OAAGJ;AAVuB,GAA5B;AAaA,QAAMK,MAAM,mBAAGd,IAAI,CAACc,MAAR,uDAAkB,kCAA9B;;AAEA,QAAMC,GAAG,GAAIC,IAAD,IAAsB;AAChCF,IAAAA,MAAM,CAACG,KAAP,CACG,WAAUjB,IAAI,CAACa,iBAAL,IAA0B,SAAU,eAC7CG,IAAI,CAACf,cACN,2BAA0B,CAACe,IAAI,CAACjB,mBAAL,GAA2B,IAA5B,EAAkCmB,OAAlC,CACzB,CADyB,CAEzB,KALJ,EAMEF,IAAI,CAACC,KANP;AAQD,GATD;;AAWA,QAAME,gBAAgB,GAAG,CACvBC,MADuB,EAEvBC,MAFuB,KAGL;AAClB,QAAIC,KAAK,GAAG,KAAZ;AACA,WAAOD,MAAM,CAACE,IAAP,CACLC,MAAM,IACJxB,IAAI,CAACY,iBAAL,GACIY,MAAM,CAACD,IAAP,CACE,oBAAI,MAAM;AACR;AACAD,MAAAA,KAAK,GAAG,IAAR;AACD,KAHD,CADF,CADJ,GAOIE,MATD,EAUL,2BAAYP,KAAD,IAAkB;AAC3B,wCAAcA,KAAd;AACA,YAAMhB,cAAc,GAAGqB,KAAK,GAAG,CAAH,GAAOF,MAAnC;AACA,YAAMK,IAAI,GAAG1B,mBAAmB,CAACC,IAAD,EAAOC,cAAc,GAAG,CAAxB,CAAhC;AACA,YAAMe,IAAI,GAAG;AACXC,QAAAA,KADW;AAEXhB,QAAAA,cAAc,EAAEA,cAAc,GAAG,CAFtB;AAGXF,QAAAA,mBAAmB,EAAE0B;AAHV,OAAb;AAKAV,MAAAA,GAAG,CAACC,IAAD,CAAH;AACA,aAAOhB,IAAI,CAACU,WAAL,CAAiBM,IAAjB,IACH,iBAAMS,IAAN,EAAYF,IAAZ,CACE,4BAAYJ,gBAAgB,CAAClB,cAAc,GAAG,CAAlB,EAAqBoB,MAArB,CAA5B,CADF,CADG,GAIH,gBAAKK,OAAO,CAACC,MAAR,CAAeV,KAAf,CAAL,CAJJ;AAKD,KAfD,CAVK,CAAP;AA2BD,GAhCD;;AAkCA,SAAQI,MAAD,IAA2BF,gBAAgB,CAAC,CAAD,EAAIE,MAAJ,CAAlD;AACD","sourcesContent":["import { Observable, timer, from } from 'rxjs';\nimport { catchError, switchMapTo, tap } from 'rxjs/operators';\nimport { registerError } from './registerError';\nimport { BasicLogger, defaultBasicLogger } from './logging';\n\ninterface IErrorInfo {\n  error: Error;\n  numberOfErrors: number;\n  timeBeforeNextRetry: number;\n}\n\nexport type RetryOpts = Partial<IRetryOptsAll>;\n\ninterface IRetryOptsAll {\n  shouldRetry: (info: IErrorInfo) => boolean;\n  sourceDescription: string;\n  resetErrorsOnNext: boolean;\n  waitTimeOnBackoff: number;\n  waitTimeOnFirstError: number;\n  minWaitTime: number;\n  maxWaitTime: number;\n  logger?: BasicLogger;\n}\n\nfunction timeBeforeNextRetry(opts: IRetryOptsAll, numberOfErrors: number) {\n  return (\n    opts.minWaitTime +\n    (numberOfErrors === 1\n      ? opts.waitTimeOnFirstError\n      : Math.min(opts.waitTimeOnBackoff * numberOfErrors, opts.maxWaitTime))\n  );\n}\n\nexport function retryWithBackoff<T>(optsRaw?: RetryOpts) {\n  const opts: IRetryOptsAll = {\n    shouldRetry: _info => {\n      return true;\n    },\n    resetErrorsOnNext: true,\n    waitTimeOnFirstError: 1 * 1000,\n    waitTimeOnBackoff: 5 * 1000,\n    minWaitTime: 1,\n    maxWaitTime: 1 * 60 * 60 * 1000,\n    sourceDescription: 'process',\n    ...optsRaw,\n  };\n\n  const logger = opts.logger ?? defaultBasicLogger();\n\n  const log = (info: IErrorInfo) => {\n    logger.error(\n      `💥  The ${opts.sourceDescription || 'process'} has failed ${\n        info.numberOfErrors\n      } time(s). Will retry in ${(info.timeBeforeNextRetry / 1000).toFixed(\n        2\n      )}s. `,\n      info.error\n    );\n  };\n\n  const recursiveObserve = (\n    errors: number,\n    source: Observable<T>\n  ): Observable<T> => {\n    let reset = false;\n    return source.pipe(\n      stream =>\n        opts.resetErrorsOnNext\n          ? stream.pipe(\n              tap(() => {\n                // if we got at least one element consider this a success\n                reset = true;\n              })\n            )\n          : stream,\n      catchError((error: Error) => {\n        registerError(error);\n        const numberOfErrors = reset ? 0 : errors;\n        const time = timeBeforeNextRetry(opts, numberOfErrors + 1);\n        const info = {\n          error,\n          numberOfErrors: numberOfErrors + 1,\n          timeBeforeNextRetry: time,\n        };\n        log(info);\n        return opts.shouldRetry(info)\n          ? timer(time).pipe(\n              switchMapTo(recursiveObserve(numberOfErrors + 1, source))\n            )\n          : from(Promise.reject(error));\n      })\n    );\n  };\n\n  return (source: Observable<T>) => recursiveObserve(0, source);\n}\n"],"file":"retryWithBackoff.js"}