UNPKG

queue-tea

Version:

A simple, robust, persistable job & task queue written in typescript. Full type safety included.

155 lines (147 loc) 4.36 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; // src/index.ts __export(exports, { default: () => src_default }); // src/TaskQueue.ts var import_nanoevents = __toModule(require("nanoevents")); // src/Queue.ts var Queue = class { constructor(elements) { this.tasks = []; this.enqueue = (e) => { this.tasks = [...this.tasks, e]; }; this.dequeue = () => { const task = this.peek(); this.tasks = this.tasks.slice(1); return task; }; this.isEmpty = () => { return this.tasks.length === 0; }; this.peek = () => { return !this.isEmpty() ? this.tasks[0] : void 0; }; this.length = () => { return this.tasks.length; }; this.tasks = elements; } }; // src/utils/sleep.ts var sleep = (delay) => new Promise((res) => setTimeout(res, delay)); // src/utils/uuid.ts var uuid = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = Math.random() * 16 | 0; return (c === "x" ? r : r & 3 | 8).toString(16); }); // src/TaskQueue.ts var defaultCalculateBackoff = (retryCount) => { const noise = Math.random() * 100; return Math.min(retryCount * 1e3, 5e3) + noise; }; var TaskQueue = ({ initialState = [], tasks, onChange, retryDelay = defaultCalculateBackoff }) => { const events = (0, import_nanoevents.createNanoEvents)(); const queuedTasks = new Queue(initialState); let state = "paused"; const queueTask = (name, ...options) => { const id = uuid(); queuedTasks.enqueue({ id, name, retries: 0, options: options[0], createdAt: Date.now() }); if (state === "idle") { run(); } const task = new Promise((res, rej) => { events.on("success", (task2) => { if (task2.id === id) { res(); } events.on("fail", (task3, error) => { if (task3.id === id) { rej(error); } }); }); }); return { id, task }; }; const pause = () => { state = "paused"; }; const isPaused = () => state === "paused"; const run = async () => { state = "running"; while (!queuedTasks.isEmpty()) { if (isPaused()) { break; } const task = queuedTasks.peek(); if (!task) { break; } try { await tasks[task.name](task.options, { createdAt: task.createdAt, retries: task.retries }); queuedTasks.dequeue(); onChange == null ? void 0 : onChange(queuedTasks.tasks); events.emit("success", task); } catch (e) { events.emit("fail", task, e); await sleep(retryDelay(++task.retries)); } finally { events.emit("change", { tasks: [...queuedTasks.tasks], remainingTasks: queuedTasks.length() }); } } state = "idle"; }; return { run, getState: () => state, pause, getQueueItems: () => [...queuedTasks.tasks], addEventListener: (event, callback) => events.on(event, callback), queueTask }; }; // src/index.ts var src_default = TaskQueue; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = {});