| /// <reference types="node" /> | ||
| declare const EventEmitter: any; | ||
| declare namespace TimeQueue { | ||
| type Worker = (...args: any[]) => void | Promise<any>; | ||
| interface Options { | ||
| concurrency?: number; | ||
| every?: number; | ||
| maxQueued?: number; | ||
| timeout?: number; | ||
| } | ||
| interface TaskError extends Error { | ||
| args: any[]; | ||
| } | ||
| } | ||
| declare class TimeQueue extends EventEmitter { | ||
| worker: TimeQueue.Worker; | ||
| concurrency: number; | ||
| every: number; | ||
| maxQueued: number; | ||
| timeout: number; | ||
| private _workerAsync; | ||
| private _queue; | ||
| private _timers; | ||
| active: number; | ||
| intransit: number; | ||
| queued: number; | ||
| finished: number; | ||
| static TaskError: { | ||
| new (message?: string): { | ||
| args: any[]; | ||
| name: string; | ||
| message: string; | ||
| stack?: string; | ||
| }; | ||
| captureStackTrace(targetObject: Object, constructorOpt?: Function): void; | ||
| prepareStackTrace?: (err: Error, stackTraces: NodeJS.CallSite[]) => any; | ||
| stackTraceLimit: number; | ||
| }; | ||
| /** | ||
| * @constructor | ||
| * @extends {EventEmitter} | ||
| * @param {Function(..., Function(!Error, ...)} worker | ||
| * @param {Object?} options | ||
| * @param {number?} options.concurrency | ||
| * @param {number?} options.every | ||
| * @param {number?} options.maxQueued | ||
| * @param {number?} options.timeout | ||
| */ | ||
| constructor(worker: TimeQueue.Worker, options?: TimeQueue.Options); | ||
| /** | ||
| * Pushes a task onto the queue. | ||
| * | ||
| * @param {Object} ...args | ||
| * @param {Function(!Error, ...)} callback | ||
| * @return {Promise?} | ||
| */ | ||
| push(...args: any[]): Promise<unknown>; | ||
| /** | ||
| * Returns true if queue is full. | ||
| * | ||
| * @return {boolean} | ||
| */ | ||
| isFull(): boolean; | ||
| /** | ||
| * Starts a task | ||
| * | ||
| * @param {Array.<Object>} args | ||
| */ | ||
| _process(args: any[]): Promise<void>; | ||
| /** | ||
| * Called when a task finishes. Looks at the queue and processes the next | ||
| * waiting task. | ||
| */ | ||
| _next(): void; | ||
| /** | ||
| * Empties the queue and kills the timers. | ||
| * Active tasks will still be completed. | ||
| */ | ||
| die(): void; | ||
| } | ||
| export = TimeQueue; |
+196
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| const EventEmitter = require('events').EventEmitter; | ||
| class TimeQueue extends EventEmitter { | ||
| /** | ||
| * @constructor | ||
| * @extends {EventEmitter} | ||
| * @param {Function(..., Function(!Error, ...)} worker | ||
| * @param {Object?} options | ||
| * @param {number?} options.concurrency | ||
| * @param {number?} options.every | ||
| * @param {number?} options.maxQueued | ||
| * @param {number?} options.timeout | ||
| */ | ||
| constructor(worker, options = {}) { | ||
| super(); | ||
| this.worker = worker; | ||
| this._workerAsync = worker.constructor.name == 'AsyncFunction'; | ||
| this.concurrency = options.concurrency || 1; | ||
| this.every = options.every || 0; | ||
| this.maxQueued = options.maxQueued || Infinity; | ||
| this.timeout = options.timeout || 0; | ||
| this._queue = []; | ||
| this._timers = []; | ||
| this.active = 0; | ||
| this.intransit = 0; | ||
| this.queued = 0; | ||
| this.finished = 0; | ||
| } | ||
| /** | ||
| * Pushes a task onto the queue. | ||
| * | ||
| * @param {Object} ...args | ||
| * @param {Function(!Error, ...)} callback | ||
| * @return {Promise?} | ||
| */ | ||
| push(...args) { | ||
| // Returns a promise no `callback` is given. | ||
| if (this._workerAsync && args.length === this.worker.length || | ||
| !this._workerAsync && args.length < this.worker.length) { | ||
| return new Promise((resolve, reject) => { | ||
| // Add any missing arguments. | ||
| if (!this._workerAsync) { | ||
| while (args.length < this.worker.length - 1) { | ||
| args.push(undefined); | ||
| } | ||
| } | ||
| this.push(...args, (err, results) => { | ||
| if (err) | ||
| return reject(err); | ||
| resolve(results); | ||
| }); | ||
| }); | ||
| } | ||
| if (this.isFull()) { | ||
| return; | ||
| } | ||
| if (this.intransit < this.concurrency) { | ||
| this.intransit++; | ||
| this.active++; | ||
| if (this.intransit === this.concurrency) { | ||
| this.emit('full'); | ||
| } | ||
| this._process(args); | ||
| } | ||
| else { | ||
| this._queue.push(args); | ||
| this.queued++; | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if queue is full. | ||
| * | ||
| * @return {boolean} | ||
| */ | ||
| isFull() { | ||
| return this.maxQueued === this.queued; | ||
| } | ||
| /** | ||
| * Starts a task | ||
| * | ||
| * @param {Array.<Object>} args | ||
| */ | ||
| _process(args) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const callback = args.pop(); | ||
| let finished = false; | ||
| let every = ~~this.every; | ||
| let timedOut; | ||
| if (every) { | ||
| timedOut = false; | ||
| this._timers.push(setTimeout(() => { | ||
| timedOut = true; | ||
| this._timers.shift(); | ||
| if (finished) { | ||
| this._next(); | ||
| } | ||
| }, every)); | ||
| } | ||
| else { | ||
| timedOut = true; | ||
| } | ||
| // If `timeout` option is set, set a timeout to check the task doesn't lag. | ||
| let taskTimedOut = false; | ||
| let callbackCalled = false; | ||
| let timeout = ~~this.timeout; | ||
| let tid; | ||
| const taskCallback = (err, result) => { | ||
| // If this task has timed out, and the callback is called again | ||
| // from the worker, ignore it. | ||
| if (!taskTimedOut) { | ||
| clearTimeout(tid); | ||
| } | ||
| else { | ||
| return; | ||
| } | ||
| // Check that this callback is only called once. | ||
| if (callbackCalled && !taskTimedOut) { | ||
| throw Error('Callback from worker should only be called once'); | ||
| } | ||
| callbackCalled = true; | ||
| this.finished++; | ||
| this.active--; | ||
| callback(err, result); | ||
| finished = true; | ||
| if (timedOut) { | ||
| this._next(); | ||
| } | ||
| }; | ||
| if (timeout) { | ||
| tid = setTimeout(() => { | ||
| const err = new TimeQueue.TaskError('Task timed out'); | ||
| err.args = args; | ||
| taskCallback(err); | ||
| taskTimedOut = true; | ||
| }, timeout); | ||
| } | ||
| // Call the worker. | ||
| if (this._workerAsync) { | ||
| try { | ||
| taskCallback(null, yield this.worker(...args)); | ||
| } | ||
| catch (err) { | ||
| taskCallback(err); | ||
| } | ||
| } | ||
| else { | ||
| // Add custom callback to args. | ||
| const args2 = args.slice(); | ||
| args2.push(taskCallback); | ||
| this.worker(...args2); | ||
| } | ||
| }); | ||
| } | ||
| /** | ||
| * Called when a task finishes. Looks at the queue and processes the next | ||
| * waiting task. | ||
| */ | ||
| _next() { | ||
| if (this.intransit <= this.concurrency && this._queue.length) { | ||
| this.queued--; | ||
| this.active++; | ||
| this._process(this._queue.shift()); | ||
| if (this._queue.length === 0) { | ||
| this.emit('empty'); | ||
| } | ||
| } | ||
| else if (--this.intransit === 0) { | ||
| this.emit('drain'); | ||
| } | ||
| } | ||
| /** | ||
| * Empties the queue and kills the timers. | ||
| * Active tasks will still be completed. | ||
| */ | ||
| die() { | ||
| this._queue = []; | ||
| this._timers.forEach(clearTimeout); | ||
| this._timers = []; | ||
| this.intransit = 0; | ||
| this.active = 0; | ||
| this.queued = 0; | ||
| } | ||
| } | ||
| TimeQueue.TaskError = class TaskError extends Error { | ||
| }; | ||
| module.exports = TimeQueue; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} |
+14
-7
@@ -9,3 +9,3 @@ { | ||
| ], | ||
| "version": "2.0.0", | ||
| "version": "2.0.1", | ||
| "repository": { | ||
@@ -16,8 +16,10 @@ "type": "git", | ||
| "author": "fent (https://github.com/fent)", | ||
| "main": "./lib/index.js", | ||
| "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "files": [ | ||
| "lib" | ||
| "dist" | ||
| ], | ||
| "scripts": { | ||
| "test": "nyc --reporter=lcov --reporter=text-summary mocha test/*-test.js" | ||
| "build": "tsc -p tsconfig.build.json", | ||
| "test": "nyc --extension .ts --reporter=lcov --reporter=text-summary mocha -- --require ts-node/register test/*-test.ts" | ||
| }, | ||
@@ -28,10 +30,15 @@ "directories": { | ||
| "devDependencies": { | ||
| "@types/mocha": "^5.2.7", | ||
| "@types/node": "^12.12.16", | ||
| "@types/sinon": "^7.5.1", | ||
| "mocha": "^6.2.0", | ||
| "nyc": "^14.1.1", | ||
| "sinon": "^7.2.3" | ||
| "nyc": "^15.0.0", | ||
| "sinon": "^8.0.0", | ||
| "ts-node": "^8.5.4", | ||
| "typescript": "^3.7.3" | ||
| }, | ||
| "engines": { | ||
| "node": ">=6" | ||
| "node": ">=10" | ||
| }, | ||
| "license": "MIT" | ||
| } |
+1
-1
| # timequeue.js | ||
| A queue with custom concurrency and time limits. Inspired by [caolan/async#queue](https://github.com/caolan/async#queue), but also with variable number of arguments in the worker, events, and with optional time limits. | ||
| A queue with custom concurrency and time limits. Inspired by [async/queue](https://caolan.github.io/async/v3/docs.html#queue), but also with variable number of arguments in the worker, events, and with optional time limits. | ||
@@ -5,0 +5,0 @@ [](https://david-dm.org/fent/timequeue.js) |
-207
| const EventEmitter = require('events').EventEmitter; | ||
| module.exports = class TimeQueue extends EventEmitter { | ||
| /** | ||
| * @constructor | ||
| * @extends {EventEmitter} | ||
| * @param {Function(..., Function(!Error, ...)} worker | ||
| * @param {Object} options | ||
| * @param {number} options.concurrency | ||
| * @param {number} options.time | ||
| */ | ||
| constructor(worker, options) { | ||
| super(); | ||
| this.worker = worker; | ||
| this._workerAsync = worker.constructor.name == 'AsyncFunction'; | ||
| options = options || {}; | ||
| this.concurrency = options.concurrency || 1; | ||
| this.every = options.every || 0; | ||
| this.maxQueued = options.maxQueued || Infinity; | ||
| this.timeout = options.timeout || 0; | ||
| this._queue = []; | ||
| this._timers = []; | ||
| // How many tasks are currently active. | ||
| TimeQueue.prototype.active = 0; | ||
| // How many tasks are still being waited on, | ||
| // in case the `every` option was used. | ||
| TimeQueue.prototype.intransit = 0; | ||
| // How many tasks are in the queue. | ||
| TimeQueue.prototype.queued = 0; | ||
| // How many tasks have finished. | ||
| TimeQueue.prototype.finished = 0; | ||
| } | ||
| /** | ||
| * Pushes a task onto the queue. | ||
| * | ||
| * @param {Object} ...args | ||
| * @param {Function(!Error, ...)} callback | ||
| * @return {Promise?} | ||
| */ | ||
| push(...args) { | ||
| // Returns a promise no `callback` is given. | ||
| if (this._workerAsync && args.length === this.worker.length || | ||
| !this._workerAsync && args.length < this.worker.length) { | ||
| return new Promise((resolve, reject) => { | ||
| // Add any missing arguments. | ||
| if (!this._workerAsync) { | ||
| while (args.length < this.worker.length - 1) { | ||
| args.push(undefined); | ||
| } | ||
| } | ||
| this.push(...args, (err, results) => { | ||
| if (err) return reject(err); | ||
| resolve(results); | ||
| }); | ||
| }); | ||
| } | ||
| if (this.isFull()) { | ||
| return; | ||
| } | ||
| if (this.intransit < this.concurrency) { | ||
| this.intransit++; | ||
| this.active++; | ||
| if (this.intransit === this.concurrency) { | ||
| this.emit('full'); | ||
| } | ||
| this._process(args); | ||
| } else { | ||
| this._queue.push(args); | ||
| this.queued++; | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if queue is full. | ||
| * | ||
| * @return {boolean} | ||
| */ | ||
| isFull() { | ||
| return this.maxQueued === this.queued; | ||
| } | ||
| /** | ||
| * Starts a task | ||
| * | ||
| * @param {Array.<Object>} args | ||
| */ | ||
| async _process(args) { | ||
| const callback = args.pop(); | ||
| let finished = false; | ||
| let every = ~~this.every; | ||
| let timedOut; | ||
| if (every) { | ||
| timedOut = false; | ||
| this._timers.push(setTimeout(() => { | ||
| timedOut = true; | ||
| this._timers.shift(); | ||
| if (finished) { | ||
| this._next(); | ||
| } | ||
| }, every)); | ||
| } else { | ||
| timedOut = true; | ||
| } | ||
| // If `timeout` option is set, set a timeout to check the task doesn't lag. | ||
| let taskTimedOut = false; | ||
| let callbackCalled = false; | ||
| let timeout = ~~this.timeout; | ||
| let tid; | ||
| const taskCallback = (err, result) => { | ||
| // If this task has timed out, and the callback is called again | ||
| // from the worker, ignore it. | ||
| if (!taskTimedOut) { | ||
| clearTimeout(tid); | ||
| } else { | ||
| return; | ||
| } | ||
| // Check that this callback is only called once. | ||
| if (callbackCalled && !taskTimedOut) { | ||
| throw Error('Callback from worker should only be called once'); | ||
| } | ||
| callbackCalled = true; | ||
| this.finished++; | ||
| this.active--; | ||
| callback(err, result); | ||
| finished = true; | ||
| if (timedOut) { | ||
| this._next(); | ||
| } | ||
| }; | ||
| if (timeout) { | ||
| tid = setTimeout(() => { | ||
| const err = Error('Task timed out'); | ||
| err.args = args; | ||
| taskCallback(err); | ||
| taskTimedOut = true; | ||
| }, timeout); | ||
| } | ||
| // Call the worker. | ||
| if (this._workerAsync) { | ||
| try { | ||
| taskCallback(null, await this.worker(...args)); | ||
| } catch (err) { | ||
| taskCallback(err); | ||
| } | ||
| } else { | ||
| // Add custom callback to args. | ||
| const args2 = args.slice(); | ||
| args2.push(taskCallback); | ||
| this.worker(...args2); | ||
| } | ||
| } | ||
| /** | ||
| * Called when a task finishes. Looks at the queue and processes the next | ||
| * waiting task. | ||
| */ | ||
| _next() { | ||
| if (this.intransit <= this.concurrency && this._queue.length) { | ||
| this.queued--; | ||
| this.active++; | ||
| this._process(this._queue.shift()); | ||
| if (this._queue.length === 0) { | ||
| this.emit('empty'); | ||
| } | ||
| } else if (--this.intransit === 0) { | ||
| this.emit('drain'); | ||
| } | ||
| } | ||
| /** | ||
| * Empties the queue and kills the timers. | ||
| * Active tasks will still be completed. | ||
| */ | ||
| die() { | ||
| this._queue = []; | ||
| this._timers.forEach(clearTimeout); | ||
| this._timers = []; | ||
| this.intransit = 0; | ||
| this.active = 0; | ||
| this.queued = 0; | ||
| } | ||
| }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
18679
87.58%6
50%276
55.93%8
166.67%1
Infinity%7
133.33%