aboutsummaryrefslogtreecommitdiff
path: root/node_modules/throat
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/throat')
-rw-r--r--node_modules/throat/LICENSE19
-rw-r--r--node_modules/throat/README.md55
-rw-r--r--node_modules/throat/index.d.ts32
-rw-r--r--node_modules/throat/index.js145
-rw-r--r--node_modules/throat/index.js.flow7
-rw-r--r--node_modules/throat/package.json47
6 files changed, 305 insertions, 0 deletions
diff --git a/node_modules/throat/LICENSE b/node_modules/throat/LICENSE
new file mode 100644
index 0000000..35cc606
--- /dev/null
+++ b/node_modules/throat/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Forbes Lindesay
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE. \ No newline at end of file
diff --git a/node_modules/throat/README.md b/node_modules/throat/README.md
new file mode 100644
index 0000000..ab69ac8
--- /dev/null
+++ b/node_modules/throat/README.md
@@ -0,0 +1,55 @@
+# throat
+
+Throttle the parallelism of an asynchronous, promise returning, function / functions. This has special utility when you set the concurrency to `1`. That way you get a mutually exclusive lock.
+
+[Professionally supported throat is now available](https://tidelift.com/subscription/pkg/npm-throat?utm_source=npm-throat&utm_medium=referral&utm_campaign=readme)
+
+[![Build Status](https://img.shields.io/github/workflow/status/ForbesLindesay/throat/Test/master?style=for-the-badge)](https://github.com/ForbesLindesay/throat/actions?query=workflow%3ATest+branch%3Amaster)
+[![Coveralls github branch](https://img.shields.io/coveralls/github/ForbesLindesay/throat/master?color=brightgreen&style=for-the-badge)](https://coveralls.io/github/ForbesLindesay/throat)
+[![Rolling Versions](https://img.shields.io/badge/Rolling%20Versions-Enabled-brightgreen?style=for-the-badge)](https://rollingversions.com/ForbesLindesay/throat)
+[![NPM version](https://img.shields.io/npm/v/throat?style=for-the-badge)](https://www.npmjs.com/package/throat)
+
+## Installation
+
+ npm install throat
+
+## API
+
+### throat(concurrency)
+
+This returns a function that acts a bit like a lock (exactly as a lock if concurrency is 1).
+
+Example, only 2 of the following functions will execute at any one time:
+
+```js
+const throat = require('throat')(2);
+
+const resA = throat(async () => { /* async stuff... */ });
+const resB = throat(async () => { /* async stuff... */ });
+const resC = throat(async () => { /* async stuff... */ });
+const resD = throat(async () => { /* async stuff... */ });
+const resE = throat(async () => { /* async stuff... */ });
+```
+
+### throat(concurrency, worker)
+
+This returns a function that is an exact copy of `worker` except that it will only execute up to `concurrency` times in parallel before further requests are queued:
+
+```js
+const throat = require('throat');
+
+const input = ['fileA.txt', 'fileB.txt', 'fileC.txt', 'fileD.txt'];
+const data = Promise.all(
+ input.map(throat(2, (fileName) => readFile(fileName)))
+);
+```
+
+Only 2 files will be read at a time, sometimes limiting parallelism in this way can improve scalability.
+
+## Security contact information
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
+
+## License
+
+MIT
diff --git a/node_modules/throat/index.d.ts b/node_modules/throat/index.d.ts
new file mode 100644
index 0000000..038ca51
--- /dev/null
+++ b/node_modules/throat/index.d.ts
@@ -0,0 +1,32 @@
+/**
+ * Throttle the given function to only run `size` times in parallel.
+ * Extra calls will be queued until one of the earlier calls completes.
+ */
+declare function throat<TResult, TArgs extends any[]>(
+ size: number,
+ fn: (...args: TArgs) => Promise<TResult>
+): (...args: TArgs) => Promise<TResult>;
+
+/**
+ * Throttle the given function to only run `size` times in parallel.
+ * Extra calls will be queued until one of the earlier calls completes.
+ */
+declare function throat<TResult, TArgs extends any[]>(
+ fn: (...args: TArgs) => Promise<TResult>,
+ size: number
+): (...args: TArgs) => Promise<TResult>;
+
+/**
+ * Create a throttle that only allows `size` calls in parallel.
+ * Extra calls will be queued until one of the earlier calls completes.
+ *
+ * To create an exclusive lock, just use a `size` of `1`.
+ */
+declare function throat(
+ size: number
+): <TResult, TArgs extends any[] = []>(
+ fn: (...args: TArgs) => Promise<TResult>,
+ ...args: TArgs
+) => Promise<TResult>;
+export default throat;
+
diff --git a/node_modules/throat/index.js b/node_modules/throat/index.js
new file mode 100644
index 0000000..0a589ea
--- /dev/null
+++ b/node_modules/throat/index.js
@@ -0,0 +1,145 @@
+'use strict';
+
+function throatInternal(size) {
+ var queue = new Queue();
+ var s = size | 0;
+
+ function run(fn, self, args) {
+ if ((s | 0) !== 0) {
+ s = (s | 0) - 1;
+ return new Promise(function (resolve) {
+ resolve(fn.apply(self, args));
+ }).then(onFulfill, onReject);
+ }
+ return new Promise(function (resolve) {
+ queue.push(new Delayed(resolve, fn, self, args));
+ }).then(runDelayed);
+ }
+ function runDelayed(d) {
+ try {
+ return Promise.resolve(d.fn.apply(d.self, d.args)).then(
+ onFulfill,
+ onReject
+ );
+ } catch (ex) {
+ onReject(ex);
+ }
+ }
+ function onFulfill(result) {
+ release();
+ return result;
+ }
+ function onReject(error) {
+ release();
+ throw error;
+ }
+ function release() {
+ var next = queue.shift();
+ if (next) {
+ next.resolve(next);
+ } else {
+ s = (s | 0) + 1;
+ }
+ }
+
+ return run;
+}
+
+function earlyBound(size, fn) {
+ const run = throatInternal(size | 0);
+ return function () {
+ var args = new Array(arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ args[i] = arguments[i];
+ }
+ return run(fn, this, args);
+ };
+}
+function lateBound(size) {
+ const run = throatInternal(size | 0);
+ return function (fn) {
+ if (typeof fn !== 'function') {
+ throw new TypeError(
+ 'Expected throat fn to be a function but got ' + typeof fn
+ );
+ }
+ var args = new Array(arguments.length - 1);
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ return run(fn, this, args);
+ };
+}
+module.exports = function throat(size, fn) {
+ if (typeof size === 'function') {
+ var temp = fn;
+ fn = size;
+ size = temp;
+ }
+ if (typeof size !== 'number') {
+ throw new TypeError(
+ 'Expected throat size to be a number but got ' + typeof size
+ );
+ }
+ if (fn !== undefined && typeof fn !== 'function') {
+ throw new TypeError(
+ 'Expected throat fn to be a function but got ' + typeof fn
+ );
+ }
+ if (typeof fn === 'function') {
+ return earlyBound(size | 0, fn);
+ } else {
+ return lateBound(size | 0);
+ }
+};
+
+module.exports.default = module.exports;
+
+function Delayed(resolve, fn, self, args) {
+ this.resolve = resolve;
+ this.fn = fn;
+ this.self = self || null;
+ this.args = args;
+}
+
+var blockSize = 64;
+function Queue() {
+ this._s1 = [];
+ this._s2 = [];
+ this._shiftBlock = this._pushBlock = new Array(blockSize);
+ this._pushIndex = 0;
+ this._shiftIndex = 0;
+}
+
+Queue.prototype.push = function (value) {
+ if (this._pushIndex === blockSize) {
+ this._pushIndex = 0;
+ this._s1[this._s1.length] = this._pushBlock = new Array(blockSize);
+ }
+ this._pushBlock[this._pushIndex++] = value;
+};
+
+Queue.prototype.shift = function () {
+ if (this._shiftIndex === blockSize) {
+ this._shiftIndex = 0;
+ var s2 = this._s2;
+ if (s2.length === 0) {
+ var s1 = this._s1;
+ if (s1.length === 0) {
+ return undefined;
+ }
+ this._s1 = s2;
+ s2 = this._s2 = s1.reverse();
+ }
+ this._shiftBlock = s2.pop();
+ }
+ if (
+ this._pushBlock === this._shiftBlock &&
+ this._pushIndex === this._shiftIndex
+ ) {
+ return undefined;
+ }
+ var result = this._shiftBlock[this._shiftIndex];
+ this._shiftBlock[this._shiftIndex++] = null;
+ return result;
+};
diff --git a/node_modules/throat/index.js.flow b/node_modules/throat/index.js.flow
new file mode 100644
index 0000000..4036f83
--- /dev/null
+++ b/node_modules/throat/index.js.flow
@@ -0,0 +1,7 @@
+// @flow
+
+declare function throat<TResult, TFn: (...args: Array<any>) => Promise<TResult>>(size: number, fn: TFn): TFn;
+declare function throat<TResult, TFn: (...args: Array<any>) => Promise<TResult>>(fn: TFn, size: number): TFn;
+declare function throat(size: number): <TResult>(fn: () => Promise<TResult>) => Promise<TResult>;
+
+module.exports = throat;
diff --git a/node_modules/throat/package.json b/node_modules/throat/package.json
new file mode 100644
index 0000000..9101b08
--- /dev/null
+++ b/node_modules/throat/package.json
@@ -0,0 +1,47 @@
+{
+ "name": "throat",
+ "version": "6.0.1",
+ "description": "Throttle the parallelism of an asynchronous (promise returning) function / functions",
+ "keywords": [
+ "promise",
+ "aplus",
+ "then",
+ "throttle",
+ "concurrency",
+ "parallelism",
+ "limit"
+ ],
+ "files": [
+ "index.d.ts",
+ "index.js",
+ "index.js.flow"
+ ],
+ "devDependencies": {
+ "coveralls": "^3.0.0",
+ "flow-bin": "^0.73.0",
+ "istanbul": "^0.4.5",
+ "jest": "^22.1.4",
+ "promise": "^8.0.0",
+ "sauce-test": "^1.0.0",
+ "test-result": "^2.0.0",
+ "testit": "^3.1.0",
+ "typescript": "^3.4.5"
+ },
+ "jest": {
+ "testEnvironment": "node"
+ },
+ "scripts": {
+ "tsc": "tsc --noEmit",
+ "flow": "flow",
+ "test": "node test/index.js && npm run test:types",
+ "test:types": "jest",
+ "coverage": "istanbul cover test/index.js",
+ "coveralls": "npm run coverage && cat ./coverage/lcov.info | coveralls"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ForbesLindesay/throat.git"
+ },
+ "author": "ForbesLindesay",
+ "license": "MIT"
+}