UNPKG

power-tasks

Version:

Powerful task management for JavaScript

97 lines (96 loc) 3.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskQueue = void 0; const tslib_1 = require("tslib"); const doublylinked_1 = tslib_1.__importDefault(require("doublylinked")); const strict_typed_events_1 = require("strict-typed-events"); const task_js_1 = require("./task.js"); class TaskQueue extends strict_typed_events_1.AsyncEventEmitter { constructor(options) { super(); this._queue = new doublylinked_1.default(); this._running = new Set(); this.maxQueue = options?.maxQueue; this.concurrency = options?.concurrency; this._paused = !!options?.paused; } get size() { return this._queue.length + this._running.size; } get running() { return this._running.size; } get queued() { return this._queue.length; } get paused() { return this._paused; } pause() { this._paused = true; } resume() { this._paused = false; setImmediate(() => this._pulse()); } clearQueue() { this._queue.forEach((task) => task.abort()); this._queue = new doublylinked_1.default(); } abortAll() { if (!this.size) return; this.clearQueue(); this._running.forEach((task) => task.abort()); } async wait() { if (!this.size) return Promise.resolve(); return new Promise((resolve) => { this.once("finish", resolve); }); } enqueuePrepend(task) { return this._enqueue(task, true); } enqueue(task) { return this._enqueue(task, false); } _enqueue(task, prepend) { if (this.maxQueue && this.size >= this.maxQueue) throw new Error(`Queue limit (${this.maxQueue}) exceeded`); const taskInstance = task instanceof task_js_1.Task ? task : new task_js_1.Task(task); Object.defineProperty(taskInstance, "_isManaged", { configurable: false, writable: false, enumerable: false, value: true, }); taskInstance.once("error", (...args) => this.emitAsync("error", ...args)); this.emit("enqueue", taskInstance); if (prepend) this._queue.unshift(taskInstance); else this._queue.push(taskInstance); this._pulse(); return taskInstance; } _pulse() { if (this.paused) return; while (!this.concurrency || this._running.size < this.concurrency) { const task = this._queue.shift(); if (!task) return; this._running.add(task); task.prependOnceListener("finish", () => { this._running.delete(task); if (!(this._running.size || this._queue.length)) return this.emit("finish"); this._pulse(); }); task.start(); } } } exports.TaskQueue = TaskQueue;