@depup/fastq 1.20.1-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +31 -0
- package/SECURITY.md +15 -0
- package/bench.js +66 -0
- package/changes.json +10 -0
- package/eslint.config.js +11 -0
- package/example.js +14 -0
- package/example.mjs +9 -0
- package/index.d.ts +59 -0
- package/package.json +66 -0
- package/queue.js +346 -0
- package/test/example.ts +83 -0
- package/test/promise.js +325 -0
- package/test/test.js +733 -0
- package/test/tsconfig.json +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright (c) 2015-2020, Matteo Collina <matteo.collina@gmail.com>
|
|
2
|
+
|
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
8
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
9
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
10
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
11
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
12
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
13
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @depup/fastq
|
|
2
|
+
|
|
3
|
+
> Dependency-bumped version of [fastq](https://www.npmjs.com/package/fastq)
|
|
4
|
+
|
|
5
|
+
Generated by [DepUp](https://github.com/depup/npm) -- all production
|
|
6
|
+
dependencies bumped to latest versions.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @depup/fastq
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Field | Value |
|
|
15
|
+
|-------|-------|
|
|
16
|
+
| Original | [fastq](https://www.npmjs.com/package/fastq) @ 1.20.1 |
|
|
17
|
+
| Processed | 2026-03-17 |
|
|
18
|
+
| Smoke test | passed |
|
|
19
|
+
| Deps updated | 1 |
|
|
20
|
+
|
|
21
|
+
## Dependency Changes
|
|
22
|
+
|
|
23
|
+
| Dependency | From | To |
|
|
24
|
+
|------------|------|-----|
|
|
25
|
+
| reusify | ^1.0.4 | ^1.1.0 |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
Source: https://github.com/depup/npm | Original: https://www.npmjs.com/package/fastq
|
|
30
|
+
|
|
31
|
+
License inherited from the original package.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Use this section to tell people about which versions of your project are
|
|
6
|
+
currently being supported with security updates.
|
|
7
|
+
|
|
8
|
+
| Version | Supported |
|
|
9
|
+
| ------- | ------------------ |
|
|
10
|
+
| 1.x | :white_check_mark: |
|
|
11
|
+
| < 1.0 | :x: |
|
|
12
|
+
|
|
13
|
+
## Reporting a Vulnerability
|
|
14
|
+
|
|
15
|
+
Please report all vulnerabilities at [https://github.com/mcollina/fastq/security](https://github.com/mcollina/fastq/security).
|
package/bench.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const max = 1000000
|
|
4
|
+
const fastqueue = require('./')(worker, 1)
|
|
5
|
+
const { promisify } = require('util')
|
|
6
|
+
const immediate = promisify(setImmediate)
|
|
7
|
+
const qPromise = require('./').promise(immediate, 1)
|
|
8
|
+
const async = require('async')
|
|
9
|
+
const neo = require('neo-async')
|
|
10
|
+
const asyncqueue = async.queue(worker, 1)
|
|
11
|
+
const neoqueue = neo.queue(worker, 1)
|
|
12
|
+
|
|
13
|
+
function bench (func, done) {
|
|
14
|
+
const key = max + '*' + func.name
|
|
15
|
+
let count = -1
|
|
16
|
+
|
|
17
|
+
console.time(key)
|
|
18
|
+
end()
|
|
19
|
+
|
|
20
|
+
function end () {
|
|
21
|
+
if (++count < max) {
|
|
22
|
+
func(end)
|
|
23
|
+
} else {
|
|
24
|
+
console.timeEnd(key)
|
|
25
|
+
if (done) {
|
|
26
|
+
done()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function benchFastQ (done) {
|
|
33
|
+
fastqueue.push(42, done)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function benchAsyncQueue (done) {
|
|
37
|
+
asyncqueue.push(42, done)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function benchNeoQueue (done) {
|
|
41
|
+
neoqueue.push(42, done)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function worker (arg, cb) {
|
|
45
|
+
setImmediate(cb)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function benchSetImmediate (cb) {
|
|
49
|
+
worker(42, cb)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function benchFastQPromise (done) {
|
|
53
|
+
qPromise.push(42).then(function () { done() }, done)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function runBench (done) {
|
|
57
|
+
async.eachSeries([
|
|
58
|
+
benchSetImmediate,
|
|
59
|
+
benchFastQ,
|
|
60
|
+
benchNeoQueue,
|
|
61
|
+
benchAsyncQueue,
|
|
62
|
+
benchFastQPromise
|
|
63
|
+
], bench, done)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
runBench(runBench)
|
package/changes.json
ADDED
package/eslint.config.js
ADDED
package/example.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-var */
|
|
4
|
+
|
|
5
|
+
var queue = require('./')(worker, 1)
|
|
6
|
+
|
|
7
|
+
queue.push(42, function (err, result) {
|
|
8
|
+
if (err) { throw err }
|
|
9
|
+
console.log('the result is', result)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
function worker (arg, cb) {
|
|
13
|
+
cb(null, 42 * 2)
|
|
14
|
+
}
|
package/example.mjs
ADDED
package/index.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
declare function fastq<C, T = any, R = any>(context: C, worker: fastq.worker<C, T, R>, concurrency: number): fastq.queue<T, R>
|
|
2
|
+
declare function fastq<C, T = any, R = any>(worker: fastq.worker<C, T, R>, concurrency: number): fastq.queue<T, R>
|
|
3
|
+
|
|
4
|
+
declare namespace fastq {
|
|
5
|
+
type worker<C, T = any, R = any> = (this: C, task: T, cb: fastq.done<R>) => void
|
|
6
|
+
type asyncWorker<C, T = any, R = any> = (this: C, task: T) => Promise<R>
|
|
7
|
+
type done<R = any> = (err: Error | null, result?: R) => void
|
|
8
|
+
type errorHandler<T = any> = (err: Error, task: T) => void
|
|
9
|
+
|
|
10
|
+
interface queue<T = any, R = any> {
|
|
11
|
+
/** Add a task at the end of the queue. `done(err, result)` will be called when the task was processed. */
|
|
12
|
+
push(task: T, done?: done<R>): void
|
|
13
|
+
/** Add a task at the beginning of the queue. `done(err, result)` will be called when the task was processed. */
|
|
14
|
+
unshift(task: T, done?: done<R>): void
|
|
15
|
+
/** Pause the processing of tasks. Currently worked tasks are not stopped. */
|
|
16
|
+
pause(): any
|
|
17
|
+
/** Resume the processing of tasks. */
|
|
18
|
+
resume(): any
|
|
19
|
+
running(): number
|
|
20
|
+
/** Returns `false` if there are tasks being processed or waiting to be processed. `true` otherwise. */
|
|
21
|
+
idle(): boolean
|
|
22
|
+
/** Returns the number of tasks waiting to be processed (in the queue). */
|
|
23
|
+
length(): number
|
|
24
|
+
/** Returns all the tasks be processed (in the queue). Returns empty array when there are no tasks */
|
|
25
|
+
getQueue(): T[]
|
|
26
|
+
/** Removes all tasks waiting to be processed, and reset `drain` to an empty function. */
|
|
27
|
+
kill(): any
|
|
28
|
+
/** Same than `kill` but the `drain` function will be called before reset to empty. */
|
|
29
|
+
killAndDrain(): any
|
|
30
|
+
/** Removes all tasks waiting to be processed, calls each task's callback with an abort error (rejects promises for promise-based queues), and resets `drain` to an empty function. */
|
|
31
|
+
abort(): any
|
|
32
|
+
/** Set a global error handler. `handler(err, task)` will be called each time a task is completed, `err` will be not null if the task has thrown an error. */
|
|
33
|
+
error(handler: errorHandler<T>): void
|
|
34
|
+
/** Property that returns the number of concurrent tasks that could be executed in parallel. It can be altered at runtime. */
|
|
35
|
+
concurrency: number
|
|
36
|
+
/** Property (Read-Only) that returns `true` when the queue is in a paused state. */
|
|
37
|
+
readonly paused: boolean
|
|
38
|
+
/** Function that will be called when the last item from the queue has been processed by a worker. It can be altered at runtime. */
|
|
39
|
+
drain(): any
|
|
40
|
+
/** Function that will be called when the last item from the queue has been assigned to a worker. It can be altered at runtime. */
|
|
41
|
+
empty: () => void
|
|
42
|
+
/** Function that will be called when the queue hits the concurrency limit. It can be altered at runtime. */
|
|
43
|
+
saturated: () => void
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface queueAsPromised<T = any, R = any> extends queue<T, R> {
|
|
47
|
+
/** Add a task at the end of the queue. The returned `Promise` will be fulfilled (rejected) when the task is completed successfully (unsuccessfully). */
|
|
48
|
+
push(task: T): Promise<R>
|
|
49
|
+
/** Add a task at the beginning of the queue. The returned `Promise` will be fulfilled (rejected) when the task is completed successfully (unsuccessfully). */
|
|
50
|
+
unshift(task: T): Promise<R>
|
|
51
|
+
/** Wait for the queue to be drained. The returned `Promise` will be resolved when all tasks in the queue have been processed by a worker. */
|
|
52
|
+
drained(): Promise<void>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function promise<C, T = any, R = any>(context: C, worker: fastq.asyncWorker<C, T, R>, concurrency: number): fastq.queueAsPromised<T, R>
|
|
56
|
+
function promise<C, T = any, R = any>(worker: fastq.asyncWorker<C, T, R>, concurrency: number): fastq.queueAsPromised<T, R>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export = fastq
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@depup/fastq",
|
|
3
|
+
"version": "1.20.1-depup.0",
|
|
4
|
+
"description": "[DepUp] Fast, in memory work queue",
|
|
5
|
+
"main": "queue.js",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"unit": "nyc --lines 100 --branches 100 --functions 100 --check-coverage --reporter=text tape test/test.js test/promise.js",
|
|
10
|
+
"coverage": "nyc --reporter=html --reporter=cobertura --reporter=text tape test/test.js test/promise.js",
|
|
11
|
+
"test:report": "npm run lint && npm run unit:report",
|
|
12
|
+
"test": "npm run lint && npm run unit",
|
|
13
|
+
"typescript": "tsc --project ./test/tsconfig.json",
|
|
14
|
+
"legacy": "tape test/test.js"
|
|
15
|
+
},
|
|
16
|
+
"pre-commit": [
|
|
17
|
+
"test",
|
|
18
|
+
"typescript"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/mcollina/fastq.git"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"depup",
|
|
26
|
+
"dependency-bumped",
|
|
27
|
+
"updated-deps",
|
|
28
|
+
"fastq",
|
|
29
|
+
"fast",
|
|
30
|
+
"queue",
|
|
31
|
+
"async",
|
|
32
|
+
"worker"
|
|
33
|
+
],
|
|
34
|
+
"author": "Matteo Collina <hello@matteocollina.com>",
|
|
35
|
+
"license": "ISC",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/mcollina/fastq/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/mcollina/fastq#readme",
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"async": "^3.1.0",
|
|
42
|
+
"eslint": "^9.36.0",
|
|
43
|
+
"neo-async": "^2.6.1",
|
|
44
|
+
"neostandard": "^0.12.2",
|
|
45
|
+
"nyc": "^17.0.0",
|
|
46
|
+
"pre-commit": "^1.2.2",
|
|
47
|
+
"tape": "^5.0.0",
|
|
48
|
+
"typescript": "^5.0.4"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"reusify": "^1.1.0"
|
|
52
|
+
},
|
|
53
|
+
"depup": {
|
|
54
|
+
"changes": {
|
|
55
|
+
"reusify": {
|
|
56
|
+
"from": "^1.0.4",
|
|
57
|
+
"to": "^1.1.0"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"depsUpdated": 1,
|
|
61
|
+
"originalPackage": "fastq",
|
|
62
|
+
"originalVersion": "1.20.1",
|
|
63
|
+
"processedAt": "2026-03-17T16:36:07.818Z",
|
|
64
|
+
"smokeTest": "passed"
|
|
65
|
+
}
|
|
66
|
+
}
|
package/queue.js
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-var */
|
|
4
|
+
|
|
5
|
+
var reusify = require('reusify')
|
|
6
|
+
|
|
7
|
+
function fastqueue (context, worker, _concurrency) {
|
|
8
|
+
if (typeof context === 'function') {
|
|
9
|
+
_concurrency = worker
|
|
10
|
+
worker = context
|
|
11
|
+
context = null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!(_concurrency >= 1)) {
|
|
15
|
+
throw new Error('fastqueue concurrency must be equal to or greater than 1')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var cache = reusify(Task)
|
|
19
|
+
var queueHead = null
|
|
20
|
+
var queueTail = null
|
|
21
|
+
var _running = 0
|
|
22
|
+
var errorHandler = null
|
|
23
|
+
|
|
24
|
+
var self = {
|
|
25
|
+
push: push,
|
|
26
|
+
drain: noop,
|
|
27
|
+
saturated: noop,
|
|
28
|
+
pause: pause,
|
|
29
|
+
paused: false,
|
|
30
|
+
|
|
31
|
+
get concurrency () {
|
|
32
|
+
return _concurrency
|
|
33
|
+
},
|
|
34
|
+
set concurrency (value) {
|
|
35
|
+
if (!(value >= 1)) {
|
|
36
|
+
throw new Error('fastqueue concurrency must be equal to or greater than 1')
|
|
37
|
+
}
|
|
38
|
+
_concurrency = value
|
|
39
|
+
|
|
40
|
+
if (self.paused) return
|
|
41
|
+
for (; queueHead && _running < _concurrency;) {
|
|
42
|
+
_running++
|
|
43
|
+
release()
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
running: running,
|
|
48
|
+
resume: resume,
|
|
49
|
+
idle: idle,
|
|
50
|
+
length: length,
|
|
51
|
+
getQueue: getQueue,
|
|
52
|
+
unshift: unshift,
|
|
53
|
+
empty: noop,
|
|
54
|
+
kill: kill,
|
|
55
|
+
killAndDrain: killAndDrain,
|
|
56
|
+
error: error,
|
|
57
|
+
abort: abort
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
function running () {
|
|
63
|
+
return _running
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function pause () {
|
|
67
|
+
self.paused = true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function length () {
|
|
71
|
+
var current = queueHead
|
|
72
|
+
var counter = 0
|
|
73
|
+
|
|
74
|
+
while (current) {
|
|
75
|
+
current = current.next
|
|
76
|
+
counter++
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return counter
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getQueue () {
|
|
83
|
+
var current = queueHead
|
|
84
|
+
var tasks = []
|
|
85
|
+
|
|
86
|
+
while (current) {
|
|
87
|
+
tasks.push(current.value)
|
|
88
|
+
current = current.next
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return tasks
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function resume () {
|
|
95
|
+
if (!self.paused) return
|
|
96
|
+
self.paused = false
|
|
97
|
+
if (queueHead === null) {
|
|
98
|
+
_running++
|
|
99
|
+
release()
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
for (; queueHead && _running < _concurrency;) {
|
|
103
|
+
_running++
|
|
104
|
+
release()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function idle () {
|
|
109
|
+
return _running === 0 && self.length() === 0
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function push (value, done) {
|
|
113
|
+
var current = cache.get()
|
|
114
|
+
|
|
115
|
+
current.context = context
|
|
116
|
+
current.release = release
|
|
117
|
+
current.value = value
|
|
118
|
+
current.callback = done || noop
|
|
119
|
+
current.errorHandler = errorHandler
|
|
120
|
+
|
|
121
|
+
if (_running >= _concurrency || self.paused) {
|
|
122
|
+
if (queueTail) {
|
|
123
|
+
queueTail.next = current
|
|
124
|
+
queueTail = current
|
|
125
|
+
} else {
|
|
126
|
+
queueHead = current
|
|
127
|
+
queueTail = current
|
|
128
|
+
self.saturated()
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
_running++
|
|
132
|
+
worker.call(context, current.value, current.worked)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function unshift (value, done) {
|
|
137
|
+
var current = cache.get()
|
|
138
|
+
|
|
139
|
+
current.context = context
|
|
140
|
+
current.release = release
|
|
141
|
+
current.value = value
|
|
142
|
+
current.callback = done || noop
|
|
143
|
+
current.errorHandler = errorHandler
|
|
144
|
+
|
|
145
|
+
if (_running >= _concurrency || self.paused) {
|
|
146
|
+
if (queueHead) {
|
|
147
|
+
current.next = queueHead
|
|
148
|
+
queueHead = current
|
|
149
|
+
} else {
|
|
150
|
+
queueHead = current
|
|
151
|
+
queueTail = current
|
|
152
|
+
self.saturated()
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
_running++
|
|
156
|
+
worker.call(context, current.value, current.worked)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function release (holder) {
|
|
161
|
+
if (holder) {
|
|
162
|
+
cache.release(holder)
|
|
163
|
+
}
|
|
164
|
+
var next = queueHead
|
|
165
|
+
if (next && _running <= _concurrency) {
|
|
166
|
+
if (!self.paused) {
|
|
167
|
+
if (queueTail === queueHead) {
|
|
168
|
+
queueTail = null
|
|
169
|
+
}
|
|
170
|
+
queueHead = next.next
|
|
171
|
+
next.next = null
|
|
172
|
+
worker.call(context, next.value, next.worked)
|
|
173
|
+
if (queueTail === null) {
|
|
174
|
+
self.empty()
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
_running--
|
|
178
|
+
}
|
|
179
|
+
} else if (--_running === 0) {
|
|
180
|
+
self.drain()
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function kill () {
|
|
185
|
+
queueHead = null
|
|
186
|
+
queueTail = null
|
|
187
|
+
self.drain = noop
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function killAndDrain () {
|
|
191
|
+
queueHead = null
|
|
192
|
+
queueTail = null
|
|
193
|
+
self.drain()
|
|
194
|
+
self.drain = noop
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function abort () {
|
|
198
|
+
var current = queueHead
|
|
199
|
+
queueHead = null
|
|
200
|
+
queueTail = null
|
|
201
|
+
|
|
202
|
+
while (current) {
|
|
203
|
+
var next = current.next
|
|
204
|
+
var callback = current.callback
|
|
205
|
+
var errorHandler = current.errorHandler
|
|
206
|
+
var val = current.value
|
|
207
|
+
var context = current.context
|
|
208
|
+
|
|
209
|
+
// Reset the task state
|
|
210
|
+
current.value = null
|
|
211
|
+
current.callback = noop
|
|
212
|
+
current.errorHandler = null
|
|
213
|
+
|
|
214
|
+
// Call error handler if present
|
|
215
|
+
if (errorHandler) {
|
|
216
|
+
errorHandler(new Error('abort'), val)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Call callback with error
|
|
220
|
+
callback.call(context, new Error('abort'))
|
|
221
|
+
|
|
222
|
+
// Release the task back to the pool
|
|
223
|
+
current.release(current)
|
|
224
|
+
|
|
225
|
+
current = next
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
self.drain = noop
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function error (handler) {
|
|
232
|
+
errorHandler = handler
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function noop () {}
|
|
237
|
+
|
|
238
|
+
function Task () {
|
|
239
|
+
this.value = null
|
|
240
|
+
this.callback = noop
|
|
241
|
+
this.next = null
|
|
242
|
+
this.release = noop
|
|
243
|
+
this.context = null
|
|
244
|
+
this.errorHandler = null
|
|
245
|
+
|
|
246
|
+
var self = this
|
|
247
|
+
|
|
248
|
+
this.worked = function worked (err, result) {
|
|
249
|
+
var callback = self.callback
|
|
250
|
+
var errorHandler = self.errorHandler
|
|
251
|
+
var val = self.value
|
|
252
|
+
self.value = null
|
|
253
|
+
self.callback = noop
|
|
254
|
+
if (self.errorHandler) {
|
|
255
|
+
errorHandler(err, val)
|
|
256
|
+
}
|
|
257
|
+
callback.call(self.context, err, result)
|
|
258
|
+
self.release(self)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function queueAsPromised (context, worker, _concurrency) {
|
|
263
|
+
if (typeof context === 'function') {
|
|
264
|
+
_concurrency = worker
|
|
265
|
+
worker = context
|
|
266
|
+
context = null
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function asyncWrapper (arg, cb) {
|
|
270
|
+
worker.call(this, arg)
|
|
271
|
+
.then(function (res) {
|
|
272
|
+
cb(null, res)
|
|
273
|
+
}, cb)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
var queue = fastqueue(context, asyncWrapper, _concurrency)
|
|
277
|
+
|
|
278
|
+
var pushCb = queue.push
|
|
279
|
+
var unshiftCb = queue.unshift
|
|
280
|
+
|
|
281
|
+
queue.push = push
|
|
282
|
+
queue.unshift = unshift
|
|
283
|
+
queue.drained = drained
|
|
284
|
+
|
|
285
|
+
return queue
|
|
286
|
+
|
|
287
|
+
function push (value) {
|
|
288
|
+
var p = new Promise(function (resolve, reject) {
|
|
289
|
+
pushCb(value, function (err, result) {
|
|
290
|
+
if (err) {
|
|
291
|
+
reject(err)
|
|
292
|
+
return
|
|
293
|
+
}
|
|
294
|
+
resolve(result)
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
// Let's fork the promise chain to
|
|
299
|
+
// make the error bubble up to the user but
|
|
300
|
+
// not lead to a unhandledRejection
|
|
301
|
+
p.catch(noop)
|
|
302
|
+
|
|
303
|
+
return p
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function unshift (value) {
|
|
307
|
+
var p = new Promise(function (resolve, reject) {
|
|
308
|
+
unshiftCb(value, function (err, result) {
|
|
309
|
+
if (err) {
|
|
310
|
+
reject(err)
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
resolve(result)
|
|
314
|
+
})
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
// Let's fork the promise chain to
|
|
318
|
+
// make the error bubble up to the user but
|
|
319
|
+
// not lead to a unhandledRejection
|
|
320
|
+
p.catch(noop)
|
|
321
|
+
|
|
322
|
+
return p
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function drained () {
|
|
326
|
+
var p = new Promise(function (resolve) {
|
|
327
|
+
process.nextTick(function () {
|
|
328
|
+
if (queue.idle()) {
|
|
329
|
+
resolve()
|
|
330
|
+
} else {
|
|
331
|
+
var previousDrain = queue.drain
|
|
332
|
+
queue.drain = function () {
|
|
333
|
+
if (typeof previousDrain === 'function') previousDrain()
|
|
334
|
+
resolve()
|
|
335
|
+
queue.drain = previousDrain
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
return p
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
module.exports = fastqueue
|
|
346
|
+
module.exports.promise = queueAsPromised
|