{"version":3,"sources":["jsdelivr-header.js","/npm/@bunchtogether/battery@1.4.10/src/queue.js"],"names":[],"mappings":"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","file":"/npm/@bunchtogether/battery@1.4.10/dist/cjs/queue.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@bunchtogether/battery@1.4.10/dist/cjs/queue.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// @flow\n\nimport PQueue from 'p-queue';\nimport EventEmitter from 'events';\nimport type { Logger } from './logger';\nimport makeLogger from './logger';\nimport type { Job } from './database';\nimport {\n  jobEmitter,\n  localJobEmitter,\n  clearDatabase,\n  dequeueFromDatabase,\n  dequeueFromDatabaseNotIn,\n  incrementJobAttemptInDatabase,\n  incrementCleanupAttemptInDatabase,\n  markJobCompleteInDatabase,\n  markJobCompleteThenRemoveFromDatabase,\n  markJobPendingInDatabase,\n  markJobErrorInDatabase,\n  markJobStartAfterInDatabase,\n  markJobAsAbortedOrRemoveFromDatabase,\n  markCleanupStartAfterInDatabase,\n  markQueuePendingInDatabase,\n  updateCleanupValuesInDatabase,\n  getCleanupFromDatabase,\n  removePathFromCleanupDataInDatabase,\n  getJobFromDatabase,\n  markQueueForCleanupInDatabase,\n  markQueueForCleanupAndRemoveInDatabase,\n  markQueueJobsGreaterThanIdCleanupAndRemoveInDatabase,\n  removeCleanupFromDatabase,\n  restoreJobToDatabaseForCleanupAndRemove,\n  getUnloadDataFromDatabase,\n  clearUnloadDataInDatabase,\n  getGreatestJobIdFromQueueInDatabase,\n  JOB_PENDING_STATUS,\n  JOB_ERROR_STATUS,\n  JOB_CLEANUP_STATUS,\n  JOB_CLEANUP_AND_REMOVE_STATUS,\n} from './database';\nimport { AbortError } from './errors';\n\nexport const CLEANUP_JOB_TYPE = 'CLEANUP_JOB_TYPE';\n\nconst BASE_PRIORITY = Math.floor(Number.MAX_SAFE_INTEGER / 2);\nconst HIGH_PRIORITY_OFFSET = Math.floor(Number.MAX_SAFE_INTEGER / 8);\n\ntype HandlerFunction = (Array<any>, AbortSignal, (Object) => Promise<void>, (number, number) => void) => Promise<void | false>;\ntype CleanupFunction = (Object | void, Array<any>, Array<string> => Promise<void>) => Promise<void>;\ntype DurationEstimateFunction = (Array<any>) => number;\ntype RetryDelayFunction = (number, Error) => number | false | Promise<number | false>;\ntype UnloadFunction = (Object | void) => Promise<void> | void;\n\ntype Options = {\n  logger?: Logger,\n  startOnJob?: boolean\n};\n\nexport default class BatteryQueue extends EventEmitter {\n  declare logger: Logger;\n  declare dequeueQueue: PQueue;\n  declare unloadQueue: PQueue;\n  declare handlerMap: Map<string, HandlerFunction>;\n  declare retryJobDelayMap: Map<string, RetryDelayFunction>;\n  declare retryCleanupDelayMap: Map<string, RetryDelayFunction>;\n  declare cleanupMap: Map<string, CleanupFunction>;\n  declare queueCurrentJobTypeMap: Map<string, string>;\n  declare durationEstimateHandlerMap: Map<string, DurationEstimateFunction>;\n  declare durationEstimateMap: Map<string, Map<number, [number, number]>>;\n  declare durationEstimateUpdaterMap: Map<number, () => number>;\n  declare queueMap: Map<string, PQueue>;\n  declare handleUnload: void | UnloadFunction;\n  declare abortControllerMap: Map<string, Map<number, AbortController>>;\n  declare isClearing: boolean;\n  declare isUnloading: boolean;\n  declare onIdlePromise: Promise<void> | void;\n  declare stopPromise: Promise<void> | void;\n  declare jobIds: Set<number>;\n  declare heartbeatExpiresTimestamp: number | void;\n\n  declare ports: Map<MessagePort, {\n    handleJobAdd: (Event) => void,\n    handleJobUpdate: (Event) => void,\n    handleJobDelete: (Event) => void,\n    handleJobsClear: (Event) => void,\n    heartbeatExpiresTimeout?: TimeoutID\n  }>;\n\n  declare handleJobAdd: void | () => void;\n  declare handleJobUpdate: void | (number, string, string, number) => void;\n  declare handleJobDelete: void | (number, string) => void;\n  declare stopped: boolean;\n\n  constructor(options?: Options = {}) {\n    super();\n    this.stopped = false;\n    this.dequeueQueue = new PQueue({ concurrency: 1 });\n    this.unloadQueue = new PQueue({ concurrency: 1 });\n    this.handlerMap = new Map();\n    this.cleanupMap = new Map();\n    this.durationEstimateHandlerMap = new Map();\n    this.durationEstimateMap = new Map();\n    this.durationEstimateUpdaterMap = new Map();\n    this.retryJobDelayMap = new Map();\n    this.retryCleanupDelayMap = new Map();\n    this.queueCurrentJobTypeMap = new Map();\n    this.queueMap = new Map();\n    this.jobIds = new Set();\n    this.durationEstimateUpdaterMap = new Map();\n    this.abortControllerMap = new Map();\n    this.isClearing = false;\n    this.isUnloading = false;\n    this.ports = new Map();\n    this.logger = options.logger || makeLogger('Battery Queue');\n    this.addListener('error', (error) => {\n      this.logger.errorStack(error);\n    });\n  }\n\n  abortJob(queueId:string, jobId:number) {\n    const queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap !== 'undefined') {\n      const abortController = queueAbortControllerMap.get(jobId);\n      if (typeof abortController !== 'undefined') {\n        abortController.abort();\n        return true;\n      }\n    }\n    return false;\n  }\n\n  enableStartOnJob() {\n    this.disableStartOnJob(); // Prevent handlers from being added multiple times\n    let didRequestJobAddDequeue = false;\n    const handleJobAdd = () => {\n      if (didRequestJobAddDequeue) {\n        return;\n      }\n      didRequestJobAddDequeue = true;\n      self.queueMicrotask(() => {\n        didRequestJobAddDequeue = false;\n        this.dequeue();\n      });\n    };\n    jobEmitter.addListener('jobAdd', handleJobAdd);\n    this.handleJobAdd = handleJobAdd;\n    const handleJobDelete = (id:number, queueId:string) => {\n      this.abortJob(queueId, id);\n    };\n    jobEmitter.addListener('jobDelete', handleJobDelete);\n    this.handleJobDelete = handleJobDelete;\n\n    const handleJobUpdate = (id:number, queueId:string, type:string, status:number) => {\n      if (status !== JOB_CLEANUP_AND_REMOVE_STATUS && status !== JOB_CLEANUP_STATUS) {\n        return;\n      }\n      const didAbort = this.abortJob(queueId, id);\n      if (didAbort) {\n        return;\n      }\n      getJobFromDatabase(id).then((job:Job | void) => {\n        if (typeof job === 'undefined') {\n          this.logger.error(`Unable to cleanup and remove ${type} job #${id} in queue ${queueId}, job does not exist`);\n          return;\n        }\n        if (this.jobIds.has(id)) {\n          return;\n        }\n        const { args, prioritize } = job;\n        this.startCleanup(id, queueId, args, type, true, prioritize);\n      }).catch((error) => {\n        this.logger.error(`Error while cleaning up and removing ${type} job #${id} in queue ${queueId}`);\n        this.logger.errorStack(error);\n      });\n    };\n    jobEmitter.addListener('jobUpdate', handleJobUpdate);\n    this.handleJobUpdate = handleJobUpdate;\n  }\n\n  disableStartOnJob() {\n    const handleJobAdd = this.handleJobAdd;\n    if (typeof handleJobAdd === 'function') {\n      jobEmitter.removeListener('jobAdd', handleJobAdd);\n      delete this.handleJobAdd;\n    }\n    const handleJobUpdate = this.handleJobUpdate;\n    if (typeof handleJobUpdate === 'function') {\n      jobEmitter.removeListener('jobUpdate', handleJobUpdate);\n      delete this.handleJobUpdate;\n    }\n    const handleJobDelete = this.handleJobDelete;\n    if (typeof handleJobDelete === 'function') {\n      jobEmitter.removeListener('jobDelete', handleJobDelete);\n      delete this.handleJobDelete;\n    }\n  }\n\n  emit(type:string, ...args:Array<any>) {\n    for (const port of this.ports.keys()) {\n      port.postMessage({ type, args });\n    }\n    return super.emit(type, ...args);\n  }\n\n  async getQueueIds() {\n    await this.dequeue();\n    const queueIds:Set<string> = new Set(this.queueMap.keys());\n    return queueIds;\n  }\n\n  setUnload(handleUnload:UnloadFunction) {\n    if (typeof this.handleUnload === 'function') {\n      throw new Error('Unload handler already exists');\n    }\n    this.handleUnload = handleUnload;\n  }\n\n  removeUnload() {\n    if (typeof this.handleUnload !== 'function') {\n      throw new Error('Unload handler does not exist');\n    }\n    delete this.handleUnload;\n  }\n\n  setRetryJobDelay(type:string, retryJobDelayFunction:RetryDelayFunction) {\n    if (this.retryJobDelayMap.has(type)) {\n      throw new Error(`Retry job delay handler for type \"${type}\" already exists`);\n    }\n    this.retryJobDelayMap.set(type, retryJobDelayFunction);\n  }\n\n  removeRetryJobDelay(type:string) {\n    if (!this.retryJobDelayMap.has(type)) {\n      throw new Error(`Retry job delay handler for type \"${type}\" does not exist`);\n    }\n    this.retryJobDelayMap.delete(type);\n  }\n\n  async getRetryJobDelay(type:string, attempt: number, error:Error) {\n    const retryJobDelayFunction = this.retryJobDelayMap.get(type);\n    if (typeof retryJobDelayFunction !== 'function') {\n      return false;\n    }\n    let result = false;\n    try {\n      result = await retryJobDelayFunction(attempt, error);\n    } catch (retryDelayError) {\n      this.logger.error(`Error in retry job delay handler for type \"${type}\" on attempt ${attempt}`);\n      this.emit('error', retryDelayError);\n      return false;\n    }\n    if (typeof result !== 'number' && result !== false) {\n      throw new Error(`Retry job delay function for type \"${type}\" returned invalid response, should be a number (milliseconds) or false`);\n    }\n    return result;\n  }\n\n  setRetryCleanupDelay(type:string, retryCleanupDelayFunction:RetryDelayFunction) {\n    if (this.retryCleanupDelayMap.has(type)) {\n      throw new Error(`Retry cleanup delay handler for type \"${type}\" already exists`);\n    }\n    this.retryCleanupDelayMap.set(type, retryCleanupDelayFunction);\n  }\n\n  removeRetryCleanupDelay(type:string) {\n    if (!this.retryCleanupDelayMap.has(type)) {\n      throw new Error(`Retry cleanup delay handler for type \"${type}\" does not exist`);\n    }\n    this.retryCleanupDelayMap.delete(type);\n  }\n\n  async getRetryCleanupDelay(type:string, attempt: number, error:Error) {\n    const retryCleanupDelayFunction = this.retryCleanupDelayMap.get(type);\n    if (typeof retryCleanupDelayFunction !== 'function') {\n      return false;\n    }\n    let result = false;\n    try {\n      result = await retryCleanupDelayFunction(attempt, error);\n    } catch (retryDelayError) {\n      this.logger.error(`Error in retry cleanup delay handler for type \"${type}\" on attempt ${attempt}`);\n      this.emit('error', retryDelayError);\n      return false;\n    }\n    if (typeof result !== 'number' && result !== false) {\n      throw new Error(`Retry cleanup delay function for type \"${type}\" returned invalid response, should be a number (milliseconds) or false`);\n    }\n    return result;\n  }\n\n  setHandler(type:string, handler: HandlerFunction) {\n    if (this.handlerMap.has(type)) {\n      throw new Error(`Handler for type \"${type}\" already exists`);\n    }\n    this.handlerMap.set(type, handler);\n  }\n\n  removeHandler(type:string) {\n    if (!this.handlerMap.has(type)) {\n      throw new Error(`Handler for type \"${type}\" does not exist`);\n    }\n    this.handlerMap.delete(type);\n  }\n\n  setCleanup(type:string, cleanup: CleanupFunction) {\n    if (this.cleanupMap.has(type)) {\n      throw new Error(`Cleanup for type \"${type}\" already exists`);\n    }\n    this.cleanupMap.set(type, cleanup);\n  }\n\n  removeCleanup(type:string) {\n    if (!this.cleanupMap.has(type)) {\n      throw new Error(`Cleanup for type \"${type}\" does not exist`);\n    }\n    this.cleanupMap.delete(type);\n  }\n\n  setDurationEstimateHandler(type:string, timeEstimationHandler: DurationEstimateFunction) {\n    if (this.durationEstimateHandlerMap.has(type)) {\n      throw new Error(`Time estimation handler for type \"${type}\" already exists`);\n    }\n    this.durationEstimateHandlerMap.set(type, timeEstimationHandler);\n  }\n\n  removeDurationEstimateHandler(type:string) {\n    if (!this.durationEstimateHandlerMap.has(type)) {\n      throw new Error(`Time estimation handler for type \"${type}\" does not exist`);\n    }\n    this.durationEstimateHandlerMap.delete(type);\n  }\n\n  addDurationEstimate(queueId:string, jobId:number, duration:number, pending:number) {\n    const queueDurationEstimateMap = this.durationEstimateMap.get(queueId);\n    if (typeof queueDurationEstimateMap === 'undefined') {\n      this.durationEstimateMap.set(queueId, new Map([[jobId, [duration, pending]]]));\n      this.emitDurationEstimate(queueId);\n      return;\n    }\n    queueDurationEstimateMap.set(jobId, [duration, pending]);\n    this.emitDurationEstimate(queueId);\n  }\n\n  removeDurationEstimate(queueId:string, jobId?:number) {\n    if (typeof jobId !== 'number') {\n      this.durationEstimateMap.delete(queueId);\n      this.emitDurationEstimate(queueId);\n      return;\n    }\n    const queueDurationEstimateMap = this.durationEstimateMap.get(queueId);\n    if (typeof queueDurationEstimateMap === 'undefined') {\n      this.emitDurationEstimate(queueId);\n      return;\n    }\n    queueDurationEstimateMap.delete(jobId);\n    this.emitDurationEstimate(queueId);\n  }\n\n  updateDurationEstimates() {\n    for (const updateDurationEstimate of this.durationEstimateUpdaterMap.values()) {\n      updateDurationEstimate();\n    }\n  }\n\n  getDurationEstimate(queueId:string) {\n    const queueDurationEstimateMap = this.durationEstimateMap.get(queueId);\n    let totalDuration = 0;\n    let totalPending = 0;\n    if (typeof queueDurationEstimateMap === 'undefined') {\n      return [totalDuration, totalPending];\n    }\n    for (const [duration, pending] of queueDurationEstimateMap.values()) {\n      totalDuration += duration;\n      totalPending += pending;\n    }\n    return [totalDuration, totalPending];\n  }\n\n  emitDurationEstimate(queueId:string) {\n    const [totalDuration, totalPending] = this.getDurationEstimate(queueId);\n    this.emit('queueDuration', queueId, totalDuration, totalPending);\n  }\n\n  setCurrentJobType(queueId:string, type?:void | string) {\n    if (typeof type === 'string') {\n      this.queueCurrentJobTypeMap.set(queueId, type);\n    } else {\n      this.queueCurrentJobTypeMap.delete(queueId);\n    }\n    this.emit('queueJobType', queueId, type);\n  }\n\n  getCurrentJobType(queueId:string) {\n    return this.queueCurrentJobTypeMap.get(queueId);\n  }\n\n  async clear() {\n    this.isClearing = true;\n    await this.onIdle();\n    this.emit('clearing');\n    await clearDatabase();\n    this.dequeueQueue.start();\n    this.isClearing = false;\n  }\n\n  addToQueue(queueId:string, priority: number, autoStart: boolean, func: () => Promise<void>) {\n    if (this.stopped) {\n      return;\n    }\n    const queue = this.queueMap.get(queueId);\n    if (typeof queue !== 'undefined') {\n      queue.add(func, { priority });\n      return;\n    }\n    const newQueue = new PQueue({ concurrency: 1, autoStart });\n    this.queueMap.set(queueId, newQueue);\n    newQueue.add(func, { priority });\n    newQueue.on('idle', async () => {\n      this.setCurrentJobType(queueId, undefined);\n      if (!this.isClearing) {\n        await new Promise((resolve) => {\n          const timeout = setTimeout(() => {\n            this.removeListener('clearing', handleClearing);\n            newQueue.removeListener('active', handleActive);\n            resolve();\n          }, 5000);\n          const handleClearing = () => {\n            clearTimeout(timeout);\n            this.removeListener('clearing', handleClearing);\n            newQueue.removeListener('active', handleActive);\n            resolve();\n          };\n          const handleActive = () => {\n            clearTimeout(timeout);\n            this.removeListener('clearing', handleClearing);\n            newQueue.removeListener('active', handleActive);\n            resolve();\n          };\n          this.addListener('clearing', handleClearing);\n          newQueue.addListener('active', handleActive);\n        });\n      }\n      if (newQueue.pending > 0 || newQueue.size > 0) {\n        return;\n      }\n      this.queueMap.delete(queueId);\n      this.emit('queueInactive', queueId);\n    });\n    this.emit('queueActive', queueId);\n  }\n\n  async abortQueue(queueId: string) {\n    this.logger.info(`Aborting queue ${queueId}`);\n    this.removeDurationEstimate(queueId);\n    // Abort active jobs\n    const queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap !== 'undefined') {\n      for (const abortController of queueAbortControllerMap.values()) {\n        abortController.abort();\n      }\n    }\n    // Changes:\n    // * JOB_ERROR_STATUS -> JOB_CLEANUP_STATUS\n    // * JOB_COMPLETE_STATUS -> JOB_CLEANUP_STATUS\n    // * JOB_CLEANUP_AND_REMOVE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_PENDING_STATUS -> JOB_ABORTED_STATUS\n    const jobs = await markQueueForCleanupInDatabase(queueId);\n    await this.startJobs(jobs);\n  }\n\n  async retryQueue(queueId: string) {\n    this.logger.info(`Retrying queue ${queueId}`);\n    const lastJobId = await getGreatestJobIdFromQueueInDatabase(queueId);\n    const priority = BASE_PRIORITY - lastJobId - 0.5;\n    this.addToQueue(queueId, priority, true, async () => {\n      // Resets job attempts. Changes:\n      // * JOB_ABORTED_STATUS -> JOB_PENDING_STATUS\n      // * JOB_ERROR_STATUS -> JOB_ERROR_STATUS\n      // * JOB_CLEANUP_STATUS -> JOB_CLEANUP_STATUS\n      // * JOB_COMPLETE_STATUS -> JOB_COMPLETE_STATUS\n      // * JOB_CLEANUP_AND_REMOVE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n      const jobs = await markQueuePendingInDatabase(queueId);\n      await this.startJobs(jobs);\n    });\n  }\n\n  async abortAndRemoveQueue(queueId: string) {\n    this.logger.info(`Aborting and removing queue ${queueId}`);\n    this.removeDurationEstimate(queueId);\n    // Abort active jobs\n    const queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap !== 'undefined') {\n      for (const abortController of queueAbortControllerMap.values()) {\n        abortController.abort();\n      }\n    }\n    // Changes:\n    // * JOB_ERROR_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_COMPLETE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_CLEANUP_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_CLEANUP_AND_REMOVE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * Removes other statuses\n    const jobs = await markQueueForCleanupAndRemoveInDatabase(queueId);\n    await this.startJobs(jobs);\n    this.emit('abortAndRemoveQueue', queueId);\n  }\n\n  async abortAndRemoveQueueJobsGreaterThanId(queueId: string, id: number) {\n    this.logger.info(`Aborting and removing jobs with ID greater than ${id} in queue ${queueId}`);\n    // Abort active jobs\n    const queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap !== 'undefined') {\n      for (const [jobId, abortController] of queueAbortControllerMap) {\n        if (jobId > id) {\n          this.removeDurationEstimate(queueId, jobId);\n          abortController.abort();\n        }\n      }\n    }\n    // Changes:\n    // * JOB_ERROR_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_COMPLETE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_CLEANUP_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * JOB_CLEANUP_AND_REMOVE_STATUS -> JOB_CLEANUP_AND_REMOVE_STATUS\n    // * Removes other statuses\n    const jobs = await markQueueJobsGreaterThanIdCleanupAndRemoveInDatabase(queueId, id);\n    await this.startJobs(jobs);\n    this.emit('abortAndRemoveQueueJobs', queueId, id);\n  }\n\n  async dequeue():Promise<void> {\n    if (this.stopped) {\n      return;\n    }\n    if (this.dequeueQueue.size === 0) {\n      // Add a subsequent dequeue\n      this.dequeueQueue.add(this.startJobs.bind(this));\n    }\n    await this.dequeueQueue.onIdle();\n  }\n\n  async startJobs(newJobs?:Array<Job>) { // eslint-disable-line consistent-return\n    const jobs = Array.isArray(newJobs) ? newJobs : await dequeueFromDatabaseNotIn([...this.jobIds.keys()]);\n    const queueIds = new Set();\n    for (const { id, queueId, args, type, status, attempt, startAfter, prioritize } of jobs) {\n      if (this.jobIds.has(id)) {\n        continue;\n      }\n      // Pause queues before adding items into them to avoid starting things out of priority\n      if (!queueIds.has(queueId)) {\n        const queue = this.queueMap.get(queueId);\n        if (typeof queue !== 'undefined') {\n          queue.pause();\n        }\n        queueIds.add(queueId);\n      }\n      if (status === JOB_PENDING_STATUS) {\n        this.startJob(id, queueId, args, type, attempt + 1, startAfter, false, prioritize);\n      } else if (status === JOB_ERROR_STATUS) {\n        this.startErrorHandler(id, queueId, args, type, attempt, startAfter, false, prioritize);\n      } else if (status === JOB_CLEANUP_STATUS) {\n        this.startCleanup(id, queueId, args, type, false, prioritize);\n      } else if (status === JOB_CLEANUP_AND_REMOVE_STATUS) {\n        this.startCleanup(id, queueId, args, type, false, prioritize);\n      } else {\n        throw new Error(`Unknown job status ${status} in job ${id} of queue ${queueId}`);\n      }\n    }\n\n    for (const queueId of queueIds) {\n      const queue = this.queueMap.get(queueId);\n      if (typeof queue !== 'undefined') {\n        queue.start();\n      } else {\n        this.logger.error(`Unable to start queue ${queueId} after dequeue; queue does not exist`);\n      }\n    }\n  }\n\n  async stop() {\n    if (typeof this.stopPromise === 'undefined') {\n      this.stopped = true;\n      this.stopPromise = (async () => {\n        await this.dequeueQueue.onIdle();\n        const idlePromises = [];\n        for (const [queueId, queue] of this.queueMap) {\n          const interval = setInterval(() => {\n            this.logger.info(`Waiting on queue ${queueId} stop() request. Queue ${queue.isPaused ? 'is paused' : 'is not paused'}, with ${queue.pending} ${queue.pending === 1 ? 'job' : 'jobs'} pending and ${queue.size} ${queue.size === 1 ? 'job' : 'jobs'} remaining.`);\n          }, 250);\n          queue.clear();\n          idlePromises.push(queue.onIdle().finally(() => {\n            clearInterval(interval);\n          }));\n        }\n        await Promise.all(idlePromises);\n        this.jobIds.clear();\n        this.abortControllerMap.clear();\n        delete this.stopPromise;\n        this.emit('stop');\n        this.stopped = false;\n      })();\n    }\n    await this.stopPromise;\n  }\n\n  async onIdle(maxDuration?: number) {\n    if (typeof this.onIdlePromise === 'undefined') {\n      this.onIdlePromise = (async () => {\n        const timeout = typeof maxDuration === 'number' ? Date.now() + maxDuration : -1;\n        const start = Date.now();\n        while (true) { // eslint-disable-line no-constant-condition\n          if (timeout !== -1 && Date.now() > timeout) {\n            this.logger.warn(`Idle timeout after ${Date.now() - start}ms`);\n            break;\n          }\n          await this.dequeueQueue.onIdle();\n          for (const [queueId, queue] of this.queueMap) {\n            const interval = setInterval(() => {\n              this.logger.info(`Waiting on queue ${queueId} onIdle() request. Queue ${queue.isPaused ? 'is paused' : 'is not paused'}, with ${queue.pending} ${queue.pending === 1 ? 'job' : 'jobs'} pending and ${queue.size} ${queue.size === 1 ? 'job' : 'jobs'} remaining.`);\n            }, 250);\n            await queue.onIdle();\n            clearInterval(interval);\n          }\n          const jobsInterval = setInterval(() => {\n            this.logger.info('Waiting on jobs');\n          }, 250);\n          const jobs = await dequeueFromDatabase();\n          clearInterval(jobsInterval);\n          if (jobs.length > 0) {\n            const interval = setInterval(() => {\n              this.logger.info('Waiting on dequeue');\n            }, 250);\n            await this.dequeue();\n            clearInterval(interval);\n            continue;\n          }\n          break;\n        }\n        delete this.onIdlePromise;\n        this.emit('idle');\n      })();\n    }\n    await this.onIdlePromise;\n  }\n\n  getAbortController(id:number, queueId:string) {\n    let queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap === 'undefined') {\n      queueAbortControllerMap = new Map();\n      this.abortControllerMap.set(queueId, queueAbortControllerMap);\n    }\n    const abortController = queueAbortControllerMap.get(id);\n    if (typeof abortController !== 'undefined') {\n      return abortController;\n    }\n    const newAbortController = new AbortController();\n    queueAbortControllerMap.set(id, newAbortController);\n    return newAbortController;\n  }\n\n  removeAbortController(id:number, queueId:string) {\n    const queueAbortControllerMap = this.abortControllerMap.get(queueId);\n    if (typeof queueAbortControllerMap === 'undefined') {\n      this.logger.warn(`Abort controller map for ${id} in queue ${queueId} does not exist`);\n      return;\n    }\n    const abortController = queueAbortControllerMap.get(id);\n    if (typeof abortController === 'undefined') {\n      this.logger.warn(`Abort controller for ${id} in queue ${queueId} does not exist`);\n      return;\n    }\n    queueAbortControllerMap.delete(id);\n    if (queueAbortControllerMap.size === 0) {\n      this.abortControllerMap.delete(queueId);\n    }\n  }\n\n  async runCleanup(id:number, queueId:string, args:Array<any>, type:string) {\n    this.emit('cleanupStart', { id });\n    const cleanup = this.cleanupMap.get(type);\n    if (typeof cleanup !== 'function') {\n      this.logger.warn(`No cleanup for job type ${type}`);\n      await removeCleanupFromDatabase(id);\n      this.emit('cleanup', { id });\n      return;\n    }\n    const cleanupJob = await getCleanupFromDatabase(id);\n    const { data, startAfter } = typeof cleanupJob === 'undefined' ? { data: undefined, startAfter: 0 } : cleanupJob;\n    const delay = startAfter - Date.now();\n    if (delay > 0) {\n      this.logger.info(`Delaying retry of ${type} job #${id} cleanup in queue ${queueId} by ${delay}ms to ${new Date(startAfter).toLocaleString()}`);\n      await new Promise((resolve) => setTimeout(resolve, delay));\n    }\n    try {\n      await cleanup(data, args, (path:Array<string>) => removePathFromCleanupDataInDatabase(id, path));\n    } catch (error) {\n      const attempt = await incrementCleanupAttemptInDatabase(id, queueId);\n      if (error.name === 'FatalError') {\n        this.logger.error(`Fatal error in ${type} job #${id} cleanup in queue ${queueId} attempt ${attempt}`);\n        this.emit('error', error);\n        await removeCleanupFromDatabase(id);\n        this.emit('fatalCleanupError', { id, queueId });\n        return;\n      }\n      const retryCleanupDelay = await this.getRetryCleanupDelay(type, attempt, error);\n      if (retryCleanupDelay === false) {\n        this.logger.error(`Error in ${type} job #${id} cleanup in queue ${queueId} attempt ${attempt} with no additional attempts requested`);\n        this.emit('error', error);\n        await removeCleanupFromDatabase(id);\n        this.emit('fatalCleanupError', { id, queueId });\n        return;\n      }\n      this.logger.error(`Error in ${type} job #${id} cleanup in queue ${queueId} attempt ${attempt}, retrying ${retryCleanupDelay > 0 ? `in ${retryCleanupDelay}ms` : 'immediately'}`);\n      this.emit('error', error);\n      if (retryCleanupDelay > 0) {\n        this.emit('retryCleanupDelay', { id, queueId, retryCleanupDelay });\n        const newStartAfter = Date.now() + retryCleanupDelay;\n        await markCleanupStartAfterInDatabase(id, newStartAfter);\n      }\n      await this.runCleanup(id, queueId, args, type);\n      return;\n    }\n    await removeCleanupFromDatabase(id);\n    this.emit('cleanup', { id });\n  }\n\n  startCleanup(id:number, queueId:string, args:Array<any>, type:string, autoStart:boolean, prioritize: boolean) {\n    this.logger.info(`Adding ${type} cleanup job #${id} to queue ${queueId}`);\n    this.jobIds.add(id);\n    this.removeDurationEstimate(queueId, id);\n    const priority = BASE_PRIORITY + id - (prioritize ? HIGH_PRIORITY_OFFSET : 0);\n    const run = async () => {\n      this.setCurrentJobType(queueId, CLEANUP_JOB_TYPE);\n      this.logger.info(`Starting ${type} cleanup #${id} in queue ${queueId}`);\n      await this.runCleanup(id, queueId, args, type);\n      // Job could be marked for removal while cleanup is running\n      await markJobAsAbortedOrRemoveFromDatabase(id);\n      this.jobIds.delete(id);\n      this.logger.info(`Completed ${type} cleanup #${id} in queue ${queueId}`);\n    };\n    this.addToQueue(queueId, priority, autoStart, run);\n  }\n\n  startErrorHandler(id:number, queueId:string, args:Array<any>, type:string, attempt: number, startAfter: number, autoStart:boolean, prioritize: boolean) {\n    this.logger.info(`Adding ${type} error handler job #${id} to queue ${queueId}`);\n    this.jobIds.add(id);\n    const priority = BASE_PRIORITY + id - (prioritize ? HIGH_PRIORITY_OFFSET : 0);\n    const abortController = this.getAbortController(id, queueId);\n    const run = async () => {\n      this.setCurrentJobType(queueId, CLEANUP_JOB_TYPE);\n      this.logger.info(`Starting ${type} error handler #${id} in queue ${queueId}`);\n      await this.runCleanup(id, queueId, args, type);\n      if (abortController.signal.aborted) {\n        // Job could be marked for removal while error handler is running\n        await markJobAsAbortedOrRemoveFromDatabase(id);\n        this.removeAbortController(id, queueId);\n        this.jobIds.delete(id);\n      } else {\n        await markJobPendingInDatabase(id);\n        this.logger.info(`Retrying ${type} job #${id} in queue ${queueId}`);\n        this.emit('retry', { id });\n        this.startJob(id, queueId, args, type, attempt + 1, startAfter, true, prioritize);\n      }\n      this.logger.info(`Completed ${type} error handler #${id} in queue ${queueId}`);\n    };\n    this.addToQueue(queueId, priority, autoStart, run);\n  }\n\n  async delayJobStart(id:number, queueId:string, type:string, signal: AbortSignal, startAfter: number) {\n    if (signal.aborted) {\n      throw new AbortError(`Queue ${queueId} was aborted`);\n    }\n    const duration = startAfter - Date.now();\n    if (duration > 0) {\n      this.logger.info(`Delaying start of ${type} job #${id} in queue ${queueId} by ${duration}ms`);\n      await new Promise((resolve, reject) => {\n        const timeout = setTimeout(() => {\n          signal.removeEventListener('abort', handleAbort);\n          resolve();\n        }, duration);\n        const handleAbort = () => {\n          clearTimeout(timeout);\n          signal.removeEventListener('abort', handleAbort);\n          reject(new AbortError(`Queue ${queueId} was aborted`));\n        };\n        signal.addEventListener('abort', handleAbort);\n      });\n    }\n  }\n\n  startJob(id:number, queueId:string, args:Array<any>, type:string, attempt:number, startAfter: number, autoStart:boolean, prioritize: boolean) {\n    this.logger.info(`Adding ${type} job #${id} to queue ${queueId}`);\n    this.jobIds.add(id);\n    const priority = BASE_PRIORITY - id + (prioritize ? HIGH_PRIORITY_OFFSET : 0);\n    const updateCleanupData = (data:Object) => updateCleanupValuesInDatabase(id, queueId, data);\n    const updateDuration = (duration:number, pending:number) => {\n      this.addDurationEstimate(queueId, id, duration, pending);\n    };\n    const updateDurationEstimate = () => {\n      const durationEstimateHandler = this.durationEstimateHandlerMap.get(type);\n      if (typeof durationEstimateHandler === 'function') {\n        try {\n          const durationEstimate = durationEstimateHandler(args);\n          this.addDurationEstimate(queueId, id, durationEstimate, durationEstimate);\n          return durationEstimate;\n        } catch (error) {\n          this.logger.error(`Unable to estimate duration of ${type} job #${id} in queue ${queueId}`);\n          this.logger.errorStack(error);\n        }\n      }\n      return 0;\n    };\n    updateDurationEstimate();\n    this.durationEstimateUpdaterMap.set(id, updateDurationEstimate);\n    const abortController = this.getAbortController(id, queueId);\n    const run = async () => {\n      const start = Date.now();\n      const durationEstimate = updateDurationEstimate();\n      this.durationEstimateUpdaterMap.delete(id);\n      if (abortController.signal.aborted) {\n        this.emit('fatalError', { id, queueId, error: new AbortError(`Queue ${queueId} was aborted`) });\n        this.removeAbortController(id, queueId);\n        this.jobIds.delete(id);\n        this.removeDurationEstimate(queueId, id);\n        return;\n      }\n      const handler = this.handlerMap.get(type);\n      if (typeof handler !== 'function') {\n        this.logger.warn(`No handler for job type ${type}`);\n        await markJobCompleteInDatabase(id);\n        this.removeAbortController(id, queueId);\n        this.jobIds.delete(id);\n        this.addDurationEstimate(queueId, id, Date.now() - start, 0);\n        return;\n      }\n      this.setCurrentJobType(queueId, type);\n      let handlerDidRun = false;\n      try {\n        // Mark as error in database so the job is cleaned up and retried if execution\n        // stops before job completion or error.\n        await markJobErrorInDatabase(id);\n        await this.delayJobStart(id, queueId, type, abortController.signal, startAfter);\n        this.logger.info(`Starting ${type} job #${id} in queue ${queueId} attempt ${attempt}`);\n        handlerDidRun = true;\n        const shouldKeepJobInDatabase = await handler(args, abortController.signal, updateCleanupData, updateDuration);\n        if (abortController.signal.aborted) {\n          throw new AbortError(`Queue ${queueId} was aborted`);\n        }\n        if (shouldKeepJobInDatabase === false) {\n          await markJobCompleteThenRemoveFromDatabase(id);\n        } else {\n          await markJobCompleteInDatabase(id);\n        }\n        this.removeAbortController(id, queueId);\n        this.jobIds.delete(id);\n        const duration = Date.now() - start;\n        if (typeof durationEstimate === 'number') {\n          const estimatedToActualRatio = durationEstimate / duration;\n          if (duration > 250 && (estimatedToActualRatio < 0.8 || estimatedToActualRatio > 1.25)) {\n            this.logger.warn(`Duration estimate of ${type} job #${id} (${durationEstimate}ms) was ${Math.round(100 * estimatedToActualRatio)}% of actual value (${duration}ms)`);\n          }\n        }\n        this.addDurationEstimate(queueId, id, duration, 0);\n        this.logger.info(`Completed ${type} job #${id} in queue ${queueId} attempt ${attempt} in ${duration}ms`);\n        return;\n      } catch (error) {\n        if (error.name === 'JobDoesNotExistError') {\n          this.logger.error(`Job does not exist error for ${type} job #${id} in queue ${queueId} attempt ${attempt}`);\n          if (handlerDidRun) {\n            this.emit('fatalError', { id, queueId, error });\n            await restoreJobToDatabaseForCleanupAndRemove(id, queueId, type, args, { prioritize });\n            this.jobIds.delete(id);\n            this.removeAbortController(id, queueId);\n            this.startCleanup(id, queueId, args, type, true, prioritize);\n          } else {\n            this.emit('fatalError', { id, queueId, error });\n            this.jobIds.delete(id);\n            this.removeAbortController(id, queueId);\n            this.removeDurationEstimate(queueId, id);\n          }\n          return;\n        }\n        if (abortController.signal.aborted) {\n          if (error.name !== 'AbortError') {\n            this.logger.error(`Abort signal following error in ${type} job #${id} in queue ${queueId} attempt ${attempt}`);\n            this.emit('error', error);\n          } else {\n            this.logger.warn(`Received abort signal for ${type} job #${id} in queue ${queueId} attempt ${attempt}`);\n          }\n          if (handlerDidRun) {\n            this.emit('fatalError', { id, queueId, error });\n            this.jobIds.delete(id);\n            this.removeAbortController(id, queueId);\n            this.startCleanup(id, queueId, args, type, true, prioritize);\n          } else {\n            this.emit('fatalError', { id, queueId, error });\n            await markJobAsAbortedOrRemoveFromDatabase(id);\n            this.jobIds.delete(id);\n            this.removeAbortController(id, queueId);\n            this.removeDurationEstimate(queueId, id);\n          }\n          return;\n        }\n        await incrementJobAttemptInDatabase(id);\n        if (error.name === 'FatalError') {\n          this.logger.error(`Fatal error in ${type} job #${id} in queue ${queueId} attempt ${attempt}`);\n          this.emit('error', error);\n          this.emit('fatalError', { id, queueId, error });\n          this.jobIds.delete(id);\n          this.removeAbortController(id, queueId);\n          await this.abortQueue(queueId);\n          return;\n        }\n        const retryDelay = await this.getRetryJobDelay(type, attempt, error);\n        if (retryDelay === false) {\n          this.logger.error(`Error in ${type} job #${id} in queue ${queueId} attempt ${attempt} with no additional attempts requested`);\n          this.emit('error', error);\n          this.emit('fatalError', { id, queueId, error });\n          this.jobIds.delete(id);\n          this.removeAbortController(id, queueId);\n          await this.abortQueue(queueId);\n          return;\n        }\n        this.logger.error(`Error in ${type} job #${id} in queue ${queueId} attempt ${attempt}, retrying ${retryDelay > 0 ? `in ${retryDelay}ms` : 'immediately'}`);\n        this.emit('error', error);\n        if (retryDelay > 0) {\n          this.emit('retryDelay', { id, queueId, retryDelay });\n          const newStartAfter = Date.now() + retryDelay;\n          await markJobStartAfterInDatabase(id, newStartAfter);\n          this.jobIds.delete(id);\n          this.startErrorHandler(id, queueId, args, type, attempt, newStartAfter, true, prioritize);\n        } else {\n          this.jobIds.delete(id);\n          this.startErrorHandler(id, queueId, args, type, attempt, startAfter, true, prioritize);\n        }\n      }\n    };\n    this.addToQueue(queueId, priority, autoStart, run);\n    this.emit('dequeue', { id });\n  }\n\n  async handlePortMessage(port: MessagePort, event:MessageEvent) {\n    if (!(event instanceof MessageEvent)) {\n      return;\n    }\n\n    const portHandlers = this.ports.get(port);\n\n    if (typeof portHandlers !== 'object') {\n      this.logger.warn('Port handlers do not exist');\n      this.logger.warnObject(event);\n      return;\n    }\n\n    const { data } = event;\n    if (!data || typeof data !== 'object') {\n      this.logger.warn('Invalid message data');\n      this.logger.warnObject(event);\n      return;\n    }\n    const { type, args } = data;\n    if (typeof type !== 'string') {\n      this.logger.warn('Unknown message type');\n      this.logger.warnObject(event);\n      return;\n    }\n    if (!Array.isArray(args)) {\n      this.logger.warn('Unknown arguments type');\n      this.logger.warnObject(event);\n      return;\n    }\n    const emit = (t:string, ...messageArgs:Array<any>) => {\n      port.postMessage({ type: t, args: messageArgs });\n    };\n    switch (type) {\n      case 'heartbeat':\n        try {\n          const [interval] = args;\n          if (typeof interval !== 'number') {\n            throw new Error(`Invalid \"interval\" argument with type ${typeof interval}, should be type number`);\n          }\n          clearTimeout(portHandlers.heartbeatExpiresTimeout);\n          this.heartbeatExpiresTimestamp = Date.now() + Math.round(interval * 2.5);\n          portHandlers.heartbeatExpiresTimeout = setTimeout(async () => {\n            this.logger.warn(`Heartbeat timeout after ${Math.round(interval * 2.1)}ms`);\n            await this.unloadClient();\n            this.removePort(port);\n          }, Math.round(interval * 2.1));\n          emit('heartbeat', ...args);\n          super.emit('heartbeat', ...args);\n        } catch (error) {\n          this.logger.error('Heartbeat error');\n          this.logger.errorStack(error);\n        }\n        return;\n      case 'jobAdd':\n        jobEmitter.emit('jobAdd', ...args);\n        return;\n      case 'jobDelete':\n        jobEmitter.emit('jobDelete', ...args);\n        return;\n      case 'jobUpdate':\n        jobEmitter.emit('jobUpdate', ...args);\n        return;\n      case 'jobsClear':\n        jobEmitter.emit('jobsClear', ...args);\n        return;\n      default:\n        break;\n    }\n    const [requestId, ...requestArgs] = args;\n    if (typeof requestId !== 'number') {\n      throw new Error('Request arguments should start with a requestId number');\n    }\n    switch (type) {\n      case 'unlink':\n        this.logger.warn('Unlinking worker interface');\n        try {\n          if (this.ports.size === 1) {\n            await this.stop();\n          }\n          emit('unlinkComplete', requestId);\n          this.removePort(port);\n        } catch (error) {\n          emit('unlinkError', requestId, error);\n          this.logger.error('Unable to handle unlink message');\n          this.emit('error', error);\n        }\n        break;\n      case 'clear':\n        try {\n          await this.clear();\n          emit('clearComplete', requestId);\n        } catch (error) {\n          emit('clearError', requestId, error);\n          this.logger.error('Unable to handle clear message');\n          this.emit('error', error);\n        }\n        break;\n      case 'abortAndRemoveQueueJobsGreaterThanId':\n        try {\n          const [queueId, id] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          if (typeof id !== 'number') {\n            throw new Error(`Invalid \"id\" argument with type ${typeof id}, should be type number`);\n          }\n          await this.abortAndRemoveQueueJobsGreaterThanId(queueId, id);\n          emit('abortAndRemoveQueueJobsGreaterThanIdComplete', requestId);\n        } catch (error) {\n          emit('abortAndRemoveQueueJobsGreaterThanIdError', requestId, error);\n          this.logger.error('Unable to handle abort and remove queue jobs greater than ID message');\n          this.emit('error', error);\n        }\n        break;\n      case 'abortAndRemoveQueue':\n        try {\n          const [queueId] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          await this.abortAndRemoveQueue(queueId);\n          emit('abortAndRemoveQueueComplete', requestId);\n        } catch (error) {\n          emit('abortAndRemoveQueueError', requestId, error);\n          this.logger.error('Unable to handle abort and remove queue message');\n          this.emit('error', error);\n        }\n        break;\n      case 'updateDurationEstimates':\n        try {\n          await this.updateDurationEstimates();\n          emit('updateDurationEstimatesComplete', requestId);\n        } catch (error) {\n          emit('updateDurationEstimatesError', requestId, error);\n          this.logger.error('Unable to handle update duration estimates message');\n          this.emit('error', error);\n        }\n        break;\n      case 'abortQueue':\n        try {\n          const [queueId] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          await this.abortQueue(queueId);\n          emit('abortQueueComplete', requestId);\n        } catch (error) {\n          emit('abortQueueError', requestId, error);\n          this.logger.error('Unable to handle abort queue message');\n          this.emit('error', error);\n        }\n        break;\n      case 'retryQueue':\n        try {\n          const [queueId] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          await this.retryQueue(queueId);\n          emit('retryQueueComplete', requestId);\n        } catch (error) {\n          emit('retryQueueError', requestId, error);\n          this.logger.error('Unable to handle retry queue message');\n          this.emit('error', error);\n        }\n        break;\n      case 'dequeue':\n        try {\n          await this.dequeue();\n          emit('dequeueComplete', requestId);\n        } catch (error) {\n          emit('dequeueError', requestId, error);\n          this.logger.error('Unable to handle dequeue message');\n          this.emit('error', error);\n        }\n        break;\n      case 'enableStartOnJob':\n        try {\n          this.enableStartOnJob();\n          emit('enableStartOnJobComplete', requestId);\n        } catch (error) {\n          emit('enableStartOnJobError', requestId, error);\n          this.logger.error('Unable to handle enableStartOnJob message');\n          this.emit('error', error);\n        }\n        break;\n      case 'disableStartOnJob':\n        try {\n          this.disableStartOnJob();\n          emit('disableStartOnJobComplete', requestId);\n        } catch (error) {\n          emit('disableStartOnJobError', requestId, error);\n          this.logger.error('Unable to handle disableStartOnJob message');\n          this.emit('error', error);\n        }\n        break;\n      case 'getQueueIds':\n        try {\n          const queueIds = await this.getQueueIds();\n          emit('getQueuesComplete', requestId, [...queueIds]);\n        } catch (error) {\n          emit('getQueuesError', requestId, error);\n          this.logger.error('Unable to handle getQueueIds message');\n          this.emit('error', error);\n        }\n        break;\n      case 'getDurationEstimate':\n        try {\n          const [queueId] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          const values = await this.getDurationEstimate(queueId);\n          emit('getDurationEstimateComplete', requestId, values);\n        } catch (error) {\n          emit('getDurationEstimateError', requestId, error);\n          this.logger.error('Unable to handle get duration estimate message');\n          this.emit('error', error);\n        }\n        break;\n      case 'getCurrentJobType':\n        try {\n          const [queueId] = requestArgs;\n          if (typeof queueId !== 'string') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof queueId}, should be type string`);\n          }\n          const currentJobType = this.getCurrentJobType(queueId);\n          emit('getCurrentJobTypeComplete', requestId, currentJobType);\n        } catch (error) {\n          emit('getCurrentJobTypeError', requestId, error);\n          this.logger.error('Unable to handle get current job type message');\n          this.emit('error', error);\n        }\n        break;\n      case 'runUnloadHandlers':\n        try {\n          await this.runUnloadHandlers();\n          emit('runUnloadHandlersComplete', requestId);\n        } catch (error) {\n          emit('runUnloadHandlersError', requestId, error);\n          this.logger.error('Unable to run unload handlers message');\n          this.emit('error', error);\n        }\n        break;\n      case 'idle':\n        try {\n          const [maxDuration, start] = requestArgs;\n          if (typeof maxDuration !== 'number') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof maxDuration}, should be type number`);\n          }\n          if (typeof start !== 'number') {\n            throw new Error(`Invalid \"queueId\" argument with type ${typeof start}, should be type number`);\n          }\n          await this.onIdle(maxDuration - (Date.now() - start));\n          emit('idleComplete', requestId);\n        } catch (error) {\n          emit('idleError', requestId, error);\n          this.logger.error('Unable to handle idle message');\n          this.emit('error', error);\n        }\n        break;\n      default:\n        this.logger.warn(`Unknown worker interface message type ${type}`);\n    }\n  }\n\n  async unloadClient() {\n    this.logger.info('Detected client unload');\n    if (this.isUnloading) {\n      this.logger.warn('Unload already in progress');\n      return;\n    }\n    try {\n      for (const { heartbeatExpiresTimeout } of this.ports.values()) {\n        clearTimeout(heartbeatExpiresTimeout);\n      }\n      const heartbeatExpiresTimestamp = this.heartbeatExpiresTimestamp;\n      if (typeof heartbeatExpiresTimestamp !== 'number') {\n        this.logger.warn('Heartbeat expires timestamp does not exist');\n        return;\n      }\n      this.isUnloading = true;\n      delete this.heartbeatExpiresTimestamp;\n      const delay = heartbeatExpiresTimestamp - Date.now();\n      if (delay > 0) {\n        await new Promise((resolve) => {\n          const timeout = setTimeout(() => {\n            clearTimeout(timeout);\n            this.removeListener('heartbeat', handleHeartbeat);\n            resolve();\n          }, delay);\n          const handleHeartbeat = () => {\n            clearTimeout(timeout);\n            this.removeListener('heartbeat', handleHeartbeat);\n            resolve();\n          };\n          this.addListener('heartbeat', handleHeartbeat);\n        });\n      }\n      if (typeof this.heartbeatExpiresTimestamp === 'number') {\n        this.logger.info('Cancelling client unload, heartbeat detected');\n        return;\n      }\n      this.logger.info('Unloading');\n      await this.runUnloadHandlers();\n      for (const port of this.ports.keys()) {\n        port.postMessage({ type: 'unloadClient', args: [] });\n      }\n      await this.onIdle();\n    } finally {\n      this.isUnloading = false;\n    }\n  }\n\n  runUnloadHandlers() {\n    return this.unloadQueue.add(async () => {\n      const handleUnload = this.handleUnload;\n      if (typeof handleUnload === 'function') {\n        try {\n          const unloadData = await getUnloadDataFromDatabase();\n          await handleUnload(unloadData);\n          await clearUnloadDataInDatabase();\n        } catch (error) {\n          this.logger.error('Error in unload handler');\n          this.logger.errorStack(error);\n        }\n      }\n    });\n  }\n\n  removePort(port:MessagePort) {\n    const portHandlers = this.ports.get(port);\n    if (typeof portHandlers === 'undefined') {\n      this.logger.info('Unable to remove port, port handler map does not exist');\n      return;\n    }\n    const {\n      handleJobAdd,\n      handleJobDelete,\n      handleJobUpdate,\n      handleJobsClear,\n      heartbeatExpiresTimeout,\n    } = portHandlers;\n\n    localJobEmitter.removeListener('jobAdd', handleJobAdd);\n    localJobEmitter.removeListener('jobDelete', handleJobDelete);\n    localJobEmitter.removeListener('jobUpdate', handleJobUpdate);\n    localJobEmitter.removeListener('jobsClear', handleJobsClear);\n    clearTimeout(heartbeatExpiresTimeout);\n\n    port.postMessage({ type: 'closed', args: [] });\n\n    port.onmessage = null; // eslint-disable-line no-param-reassign\n    port.onmessageerror = null; // eslint-disable-line no-param-reassign\n    port.close();\n\n    this.ports.delete(port);\n  }\n\n  listenForServiceWorkerInterface() {\n    self.addEventListener('sync', (event) => {\n      this.logger.info(`SyncManager event ${event.tag}${event.lastChance ? ', last chance' : ''}`);\n      if (event.tag === 'syncManagerOnIdle') {\n        this.logger.info('Starting SyncManager idle handler');\n        this.emit('syncManagerOnIdle');\n        event.waitUntil(this.onIdle().catch((error) => {\n          this.logger.error(`SyncManager event handler failed${event.lastChance ? ' on last chance' : ''}`);\n          this.logger.errorStack(error);\n        }));\n      } else if (event.tag === 'unload') {\n        this.logger.info('Starting SyncManager unload client handler');\n        event.waitUntil(this.unloadClient().catch((error) => {\n          this.logger.error(`SyncManager event handler failed${event.lastChance ? ' on last chance' : ''}`);\n          this.logger.errorStack(error);\n        }));\n      } else {\n        this.logger.warn(`Received unknown SyncManager event tag ${event.tag}`);\n      }\n    });\n\n    self.addEventListener('message', (event:ExtendableMessageEvent) => {\n      if (!(event instanceof ExtendableMessageEvent)) {\n        return;\n      }\n      const { data } = event;\n      if (!data || typeof data !== 'object') {\n        return;\n      }\n      const { type } = data;\n      if (type !== 'BATTERY_QUEUE_WORKER_INITIALIZATION') {\n        return;\n      }\n      if (!Array.isArray(event.ports)) {\n        return;\n      }\n      const port = event.ports[0];\n      if (!(port instanceof MessagePort)) {\n        return;\n      }\n      if (this.ports.has(port)) {\n        return;\n      }\n\n      port.onmessage = (_event:MessageEvent) => this.handlePortMessage(port, _event); // eslint-disable-line no-param-reassign\n\n      port.onmessageerror = (_event:MessageEvent) => {\n        this.logger.error('MessagePort unable to deserialize message');\n        this.logger.errorObject(_event);\n      };\n\n      const handleJobAdd = (...args:Array<any>) => {\n        port.postMessage({ type: 'jobAdd', args });\n      };\n      const handleJobDelete = (...args:Array<any>) => {\n        port.postMessage({ type: 'jobDelete', args });\n      };\n      const handleJobUpdate = (...args:Array<any>) => {\n        port.postMessage({ type: 'jobUpdate', args });\n      };\n      const handleJobsClear = (...args:Array<any>) => {\n        port.postMessage({ type: 'jobsClear', args });\n      };\n\n      localJobEmitter.addListener('jobAdd', handleJobAdd);\n      localJobEmitter.addListener('jobDelete', handleJobDelete);\n      localJobEmitter.addListener('jobUpdate', handleJobUpdate);\n      localJobEmitter.addListener('jobsClear', handleJobsClear);\n\n\n      const portHandlers = {\n        handleJobAdd,\n        handleJobDelete,\n        handleJobUpdate,\n        handleJobsClear,\n      };\n\n      this.ports.set(port, portHandlers);\n\n      port.postMessage({ type: 'BATTERY_QUEUE_WORKER_CONFIRMATION' });\n\n      this.logger.info('Linked to worker interface');\n    });\n    self.addEventListener('messageerror', (event:MessageEvent) => {\n      this.logger.error('Service worker interface message error');\n      this.logger.errorObject(event);\n    });\n  }\n}\n\n"]}