import PQueue from 'p-queue' ; export const noop = ( ) => { } ; export type Task < TaskResultType > = ( ) => Promise < TaskResultType > ; /**
 * TaskQueue aspect.
 */ export interface TaskQueueLike { param task param onFinally add ( task , onFinally ? ) : void ; /**
     * Add task to the queue. Return its result in Promise.
     * The point of `run` (as opposed to `add`) is to pass an error to the caller if it is throw inside a task.
     * Note "fire-and-forget" comment for the `add` method.
     */ run < T > ( task ) : Promise < T > ; } /**
 * PQueue with synchronous `add` and a common error-handler.
 */ export class TaskQueue implements TaskQueueLike { #pq = new PQueue ( { concurrency : 1 } ) ; param onError constructor ( private readonly onError = noop ) { } /**
     * Size of the queue. Counts both deferred and currently running tasks.
     */ get size ( ) : number { return this . #pq . size + this . #pq . pending ; } /**
     * Add task to queue. Fire-and-forget semantics.
     */ add ( task , onFinally ? ) { this . run ( task ) . catch ( ( error ) => { const retry = ( ) => this . add ( task , onFinally ) ; this . onError ( error , retry ) ; } ) . finally ( ( ) => onFinally ?. ( ) ) ; } /**
     * Add task and wait till it is completed.
     * The point of `run` (as opposed to `add`) is to pass an error to the caller if it is throw inside a task.
     * Note "fire-and-forget" comment for the `add` method.
     */ run < T > ( task ) { return this . #pq . add ( task ) ; } /**
     * Wait till all the tasks are completed.
     */ onIdle ( ) { return this . #pq . onIdle ( ) ; } /**
     * Clear the queue.
     */ clear ( ) { this . #pq . clear ( ) ; } pause ( ) { this . #pq . pause ( ) ; } }