New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

pendings

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pendings - npm Package Compare versions

Comparing version 0.1.8 to 0.1.9

README_TEMPLATE.md

90

lib/index.js

@@ -11,2 +11,3 @@ /**

var promiseFinally = require('promise.prototype.finally');
var Pending = require('./pending');

@@ -19,3 +20,3 @@

* @param {Object} [options]
* @param {Number} [options.timeout] default timeout
* @param {Number} [options.timeout] default timeout for all promises
*/

@@ -35,3 +36,3 @@ function Pendings(options) {

* @param {Object} [options]
* @param {Number} [options.timeout]
* @param {Number} [options.timeout] custom timeout for particular promise
* @returns {Promise}

@@ -54,3 +55,3 @@ */

* @param {Object} [options]
* @param {Number} [options.timeout]
* @param {Number} [options.timeout] custom timeout for particular promise
* @returns {Promise}

@@ -62,8 +63,15 @@ */

value: function set(id, fn, options) {
options = options || {};
var timeout = options.timeout !== undefined ? options.timeout : this._timeout;
var mainPromise = this._createPromise(id, fn);
var finalPromise = timeout ? this._wrapWithTimeout(mainPromise, id, timeout) : mainPromise;
this._setPromise(id, finalPromise);
return finalPromise;
var _this = this;
if (!this.has(id)) {
var pending = this._map[id] = new Pending();
var timeout = this._getTimeout(options);
var promise = pending.call(function () {
return fn(id);
}, timeout);
pending.finalPromise = promiseFinally(promise, function () {
return delete _this._map[id];
});
}
return this.getPromise(id);
}

@@ -94,3 +102,3 @@

value: function resolve(id, value) {
var pending = this._extract(id);
var pending = this._map[id];
if (pending) {

@@ -111,3 +119,3 @@ pending.resolve(value);

value: function reject(id, reason) {
var pending = this._extract(id);
var pending = this._map[id];
if (pending) {

@@ -127,6 +135,6 @@ pending.reject(reason);

value: function rejectAll(reason) {
var _this = this;
var _this2 = this;
Object.keys(this._map).forEach(function (id) {
return _this.reject(id, reason);
return _this2.reject(id, reason);
});

@@ -146,3 +154,3 @@ }

value: function fulfill(id, value, reason) {
var pending = this._extract(id);
var pending = this._map[id];
if (pending) {

@@ -178,53 +186,7 @@ pending.fulfill(value, reason);

}, {
key: '_extract',
value: function _extract(id) {
var pending = this._map[id];
if (pending) {
delete this._map[id];
return pending;
}
key: '_getTimeout',
value: function _getTimeout(options) {
options = options || {};
return options.timeout !== undefined ? options.timeout : this._timeout;
}
}, {
key: '_createPromise',
value: function _createPromise(id, fn) {
var _this2 = this;
var pending = new Pending();
return pending.call(function () {
if (_this2._map[id]) {
throw new Error('Promise with id ' + id + ' is already pending');
}
_this2._map[id] = pending;
try {
fn(id);
} catch (e) {
_this2.reject(id, e);
}
});
}
}, {
key: '_createTimeoutPromise',
value: function _createTimeoutPromise(id, timeout) {
var _this3 = this;
return new Promise(function (resolve) {
return setTimeout(resolve, timeout);
}).then(function () {
var error = new Error('Promise rejected by timeout (' + timeout + ' ms)');
_this3.reject(id, error);
});
}
}, {
key: '_wrapWithTimeout',
value: function _wrapWithTimeout(promise, id, timeout) {
var timeoutPromise = this._createTimeoutPromise(id, timeout);
return Promise.race([promise, timeoutPromise]);
}
}, {
key: '_setPromise',
value: function _setPromise(id, promise) {
if (this._map[id]) {
this._map[id].finalPromise = promise;
}
}
}]);

@@ -231,0 +193,0 @@

@@ -11,3 +11,5 @@ /**

module.exports = function () {
var promiseFinally = require('promise.prototype.finally');
var Pending = function () {
/**

@@ -40,15 +42,12 @@ * Constructor.

* @param {Function} fn
* @param {Number} [timeout=0]
* @returns {Promise}
*/
value: function call(fn) {
var _this = this;
value: function call(fn, timeout) {
this._isFulfilled = false;
this._promise = new Promise(function (resolve, reject) {
_this._resolve = resolve;
_this._reject = reject;
if (fn) {
fn();
}
});
this._createPromise(fn);
if (timeout) {
this._wrapWithTimeout(timeout);
}
this._wrapWithFinally();
return this._promise;

@@ -66,3 +65,2 @@ }

value: function resolve(value) {
this._isFulfilled = true;
this._resolve(value);

@@ -80,3 +78,2 @@ }

value: function reject(reason) {
this._isFulfilled = true;
this._reject(reason);

@@ -102,2 +99,34 @@ }

}, {
key: '_createPromise',
value: function _createPromise(fn) {
var _this = this;
this._promise = new Promise(function (resolve, reject) {
_this._resolve = resolve;
_this._reject = reject;
if (fn) {
fn();
}
});
}
}, {
key: '_wrapWithTimeout',
value: function _wrapWithTimeout(timeout) {
var timeoutPromise = new Promise(function (resolve, reject) {
return setTimeout(function () {
reject(new Error('Promise rejected by timeout (' + timeout + ' ms)'));
}, timeout);
});
this._promise = Promise.race([this._promise, timeoutPromise]);
}
}, {
key: '_wrapWithFinally',
value: function _wrapWithFinally() {
var _this2 = this;
this._promise = promiseFinally(this._promise, function () {
return _this2._isFulfilled = true;
});
}
}, {
key: 'promise',

@@ -122,2 +151,4 @@ get: function get() {

return Pending;
}();
}();
module.exports = Pending;
{
"name": "pendings",
"version": "0.1.8",
"version": "0.1.9",
"description": "Better control of pending promises",

@@ -22,2 +22,3 @@ "author": {

"ci": "npm run code && npm test",
"docs": "jsdoc2md --template README_TEMPLATE.md --files src/*.js > README.md",
"release": "npm run code && npm test && npm version $VER && npm publish && git push --follow-tags --no-verify",

@@ -46,2 +47,3 @@ "release-patch": "VER=patch npm run release",

"husky": "^0.13.4",
"jsdoc-to-markdown": "^3.0.0",
"lint-staged": "^4.0.0",

@@ -60,3 +62,6 @@ "mocha": "^3.4.2"

],
"license": "MIT"
"license": "MIT",
"dependencies": {
"promise.prototype.finally": "^2.0.1"
}
}

@@ -92,172 +92,221 @@ # Pendings

### new Pendings(options)
Controls list of pending promises.
```js
/**
* Constructor.
*
* @param {Object} [options]
* @param {Number} [options.timeout] default timeout
*/
```
## Classes
#### .add(fn, options)
```js
/**
* Calls `fn` and returns new promise. `fn` gets generated unique `id` as parameter.
*
* @param {Function} fn
* @param {Object} [options]
* @param {Number} [options.timeout]
* @returns {Promise}
*/
```
<dl>
<dt><a href="#Pendings">Pendings</a></dt>
<dd></dd>
<dt><a href="#Pending">Pending</a></dt>
<dd></dd>
</dl>
#### .set(id, fn, options)
```js
/**
* Calls `fn` and returns new promise with specified `id`.
*
* @param {String|Number} id
* @param {Function} fn
* @param {Object} [options]
* @param {Number} [options.timeout]
* @returns {Promise}
*/
```
<a name="Pendings"></a>
#### .has(id)
```js
/**
* Checks if pending promise with specified `id` exists.
*
* @param {String|Number} id
* @returns {Boolean}
*/
```
#### .resolve(id, value)
```js
/**
* Resolves pending promise by `id` with specified `value`.
*
* @param {String|Number} id
* @param {*} [value]
*/
```
## Pendings
**Kind**: global class
#### .reject(id, reason)
```js
/**
* Rejects pending promise by `id` with specified `reason`.
*
* @param {String|Number} id
* @param {*} [reason]
*/
```
* [Pendings](#Pendings)
* [new Pendings([options])](#new_Pendings_new)
* [.add(fn, [options])](#Pendings+add) ⇒ <code>Promise</code>
* [.set(id, fn, [options])](#Pendings+set) ⇒ <code>Promise</code>
* [.has(id)](#Pendings+has) ⇒ <code>Boolean</code>
* [.resolve(id, [value])](#Pendings+resolve)
* [.reject(id, [reason])](#Pendings+reject)
* [.rejectAll([reason])](#Pendings+rejectAll)
* [.fulfill(id, [value], [reason])](#Pendings+fulfill)
* [.getPromise(id)](#Pendings+getPromise) ⇒ <code>Promise</code> \| <code>undefined</code>
* [.generateId()](#Pendings+generateId) ⇒ <code>String</code>
#### .rejectAll(reason)
```js
/**
* Rejects all pending promises with specified `reason`. Useful for cleanup.
*
* @param {*} [reason]
*/
```
<a name="new_Pendings_new"></a>
#### .fulfill(id, value, reason)
```js
/**
* Rejects if `reason` is truthy, otherwise resolves with `value`.
*
* @param {String|Number} id
* @param {*} [value]
* @param {*} [reason]
*/
```
### new Pendings([options])
Constructor.
#### .getPromise(id)
```js
/**
* Returns promise of pending object with specified `id`.
*
* @param {String|Number} id
* @returns {Promise|undefined}
*/
```
#### .generateId()
```js
/**
* Generates unique ID. Can be overwritten.
*
* @returns {String}
*/
```
| Param | Type | Description |
| --- | --- | --- |
| [options] | <code>Object</code> | |
| [options.timeout] | <code>Number</code> | default timeout for all promises |
<a name="Pendings+add"></a>
### pendings.add(fn, [options]) ⇒ <code>Promise</code>
Calls `fn` and returns new promise. `fn` gets generated unique `id` as parameter.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type | Description |
| --- | --- | --- |
| fn | <code>function</code> | |
| [options] | <code>Object</code> | |
| [options.timeout] | <code>Number</code> | custom timeout for particular promise |
<a name="Pendings+set"></a>
### pendings.set(id, fn, [options]) ⇒ <code>Promise</code>
Calls `fn` and returns new promise with specified `id`.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type | Description |
| --- | --- | --- |
| id | <code>String</code> \| <code>Number</code> | |
| fn | <code>function</code> | |
| [options] | <code>Object</code> | |
| [options.timeout] | <code>Number</code> | custom timeout for particular promise |
<a name="Pendings+has"></a>
### pendings.has(id) ⇒ <code>Boolean</code>
Checks if pending promise with specified `id` exists.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| id | <code>String</code> \| <code>Number</code> |
<a name="Pendings+resolve"></a>
### pendings.resolve(id, [value])
Resolves pending promise by `id` with specified `value`.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| id | <code>String</code> \| <code>Number</code> |
| [value] | <code>\*</code> |
<a name="Pendings+reject"></a>
### pendings.reject(id, [reason])
Rejects pending promise by `id` with specified `reason`.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| id | <code>String</code> \| <code>Number</code> |
| [reason] | <code>\*</code> |
<a name="Pendings+rejectAll"></a>
### pendings.rejectAll([reason])
Rejects all pending promises with specified `reason`. Useful for cleanup.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| [reason] | <code>\*</code> |
<a name="Pendings+fulfill"></a>
### pendings.fulfill(id, [value], [reason])
Rejects if `reason` is truthy, otherwise resolves with `value`.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| id | <code>String</code> \| <code>Number</code> |
| [value] | <code>\*</code> |
| [reason] | <code>\*</code> |
<a name="Pendings+getPromise"></a>
### pendings.getPromise(id) ⇒ <code>Promise</code> \| <code>undefined</code>
Returns promise of pending object with specified `id`.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
| Param | Type |
| --- | --- |
| id | <code>String</code> \| <code>Number</code> |
<a name="Pendings+generateId"></a>
### pendings.generateId() ⇒ <code>String</code>
Generates unique ID. Can be overwritten.
**Kind**: instance method of [<code>Pendings</code>](#Pendings)
<a name="Pending"></a>
## Pending
**Kind**: global class
* [Pending](#Pending)
* [new Pending()](#new_Pending_new)
* [.promise](#Pending+promise) ⇒ <code>Promise</code>
* [.isFulfilled](#Pending+isFulfilled) ⇒ <code>Boolean</code>
* [.call(fn, [timeout])](#Pending+call) ⇒ <code>Promise</code>
* [.resolve([value])](#Pending+resolve)
* [.reject([reason])](#Pending+reject)
* [.fulfill([value], [reason])](#Pending+fulfill)
<a name="new_Pending_new"></a>
### new Pending()
Controls single pending promise.
```js
/**
* Constructor.
*/
```
Constructor.
#### .call(fn)
```js
/**
* Calls `fn`, returns new promise and holds `resolve` / `reject` callbacks.
*
* @param {Function} fn
* @returns {Promise}
*/
```
<a name="Pending+promise"></a>
#### .resolve(value)
```js
/**
* Resolves pending promise with specified `value`.
*
* @param {*} [value]
*/
```
### pending.promise ⇒ <code>Promise</code>
Returns promise itself.
#### .reject(reason)
```js
/**
* Rejects pending promise with specified `reason`.
*
* @param {*} [reason]
*/
```
**Kind**: instance property of [<code>Pending</code>](#Pending)
<a name="Pending+isFulfilled"></a>
#### .fulfill(value, reason)
```js
/**
* Rejects if `reason` is truthy, otherwise resolves with `value`.
*
* @param {*} [value]
* @param {*} [reason]
*/
```
### pending.isFulfilled ⇒ <code>Boolean</code>
Returns is promise fulfilled or not.
#### .isFulfilled
```js
/**
* Returns is promise fulfilled or not.
*
* @returns {Boolean}
*/
```
**Kind**: instance property of [<code>Pending</code>](#Pending)
<a name="Pending+call"></a>
#### .promise
```js
/**
* Returns promise itself.
*
* @returns {Promise}
*/
```
### pending.call(fn, [timeout]) ⇒ <code>Promise</code>
Calls `fn`, returns new promise and holds `resolve` / `reject` callbacks.
**Kind**: instance method of [<code>Pending</code>](#Pending)
| Param | Type | Default |
| --- | --- | --- |
| fn | <code>function</code> | |
| [timeout] | <code>Number</code> | <code>0</code> |
<a name="Pending+resolve"></a>
### pending.resolve([value])
Resolves pending promise with specified `value`.
**Kind**: instance method of [<code>Pending</code>](#Pending)
| Param | Type |
| --- | --- |
| [value] | <code>\*</code> |
<a name="Pending+reject"></a>
### pending.reject([reason])
Rejects pending promise with specified `reason`.
**Kind**: instance method of [<code>Pending</code>](#Pending)
| Param | Type |
| --- | --- |
| [reason] | <code>\*</code> |
<a name="Pending+fulfill"></a>
### pending.fulfill([value], [reason])
Rejects if `reason` is truthy, otherwise resolves with `value`.
**Kind**: instance method of [<code>Pending</code>](#Pending)
| Param | Type |
| --- | --- |
| [value] | <code>\*</code> |
| [reason] | <code>\*</code> |
## License
MIT @ [Vitaliy Potapov](https://github.com/vitalets)

@@ -7,2 +7,3 @@ /**

const promiseFinally = require('promise.prototype.finally');
const Pending = require('./pending');

@@ -15,3 +16,3 @@

* @param {Object} [options]
* @param {Number} [options.timeout] default timeout
* @param {Number} [options.timeout] default timeout for all promises
*/

@@ -29,3 +30,3 @@ constructor(options) {

* @param {Object} [options]
* @param {Number} [options.timeout]
* @param {Number} [options.timeout] custom timeout for particular promise
* @returns {Promise}

@@ -44,12 +45,13 @@ */

* @param {Object} [options]
* @param {Number} [options.timeout]
* @param {Number} [options.timeout] custom timeout for particular promise
* @returns {Promise}
*/
set(id, fn, options) {
options = options || {};
const timeout = options.timeout !== undefined ? options.timeout : this._timeout;
const mainPromise = this._createPromise(id, fn);
const finalPromise = timeout ? this._wrapWithTimeout(mainPromise, id, timeout) : mainPromise;
this._setPromise(id, finalPromise);
return finalPromise;
if (!this.has(id)) {
const pending = this._map[id] = new Pending();
const timeout = this._getTimeout(options);
const promise = pending.call(() => fn(id), timeout);
pending.finalPromise = promiseFinally(promise, () => delete this._map[id]);
}
return this.getPromise(id);
}

@@ -74,3 +76,3 @@

resolve(id, value) {
const pending = this._extract(id);
const pending = this._map[id];
if (pending) {

@@ -88,3 +90,3 @@ pending.resolve(value);

reject(id, reason) {
const pending = this._extract(id);
const pending = this._map[id];
if (pending) {

@@ -112,3 +114,3 @@ pending.reject(reason);

fulfill(id, value, reason) {
const pending = this._extract(id);
const pending = this._map[id];
if (pending) {

@@ -138,43 +140,6 @@ pending.fulfill(value, reason);

_extract(id) {
const pending = this._map[id];
if (pending) {
delete this._map[id];
return pending;
}
_getTimeout(options) {
options = options || {};
return options.timeout !== undefined ? options.timeout : this._timeout;
}
_createPromise(id, fn) {
const pending = new Pending();
return pending.call(() => {
if (this._map[id]) {
throw new Error(`Promise with id ${id} is already pending`);
}
this._map[id] = pending;
try {
fn(id);
} catch (e) {
this.reject(id, e);
}
});
}
_createTimeoutPromise(id, timeout) {
return new Promise(resolve => setTimeout(resolve, timeout))
.then(() => {
const error = new Error(`Promise rejected by timeout (${timeout} ms)`);
this.reject(id, error);
});
}
_wrapWithTimeout(promise, id, timeout) {
const timeoutPromise = this._createTimeoutPromise(id, timeout);
return Promise.race([promise, timeoutPromise]);
}
_setPromise(id, promise) {
if (this._map[id]) {
this._map[id].finalPromise = promise;
}
}
}

@@ -181,0 +146,0 @@

@@ -7,3 +7,5 @@ /**

module.exports = class Pending {
const promiseFinally = require('promise.prototype.finally');
class Pending {
/**

@@ -41,13 +43,12 @@ * Constructor.

* @param {Function} fn
* @param {Number} [timeout=0]
* @returns {Promise}
*/
call(fn) {
call(fn, timeout) {
this._isFulfilled = false;
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
if (fn) {
fn();
}
});
this._createPromise(fn);
if (timeout) {
this._wrapWithTimeout(timeout);
}
this._wrapWithFinally();
return this._promise;

@@ -62,3 +63,2 @@ }

resolve(value) {
this._isFulfilled = true;
this._resolve(value);

@@ -73,3 +73,2 @@ }

reject(reason) {
this._isFulfilled = true;
this._reject(reason);

@@ -91,2 +90,25 @@ }

}
};
_createPromise(fn) {
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
if (fn) {
fn();
}
});
}
_wrapWithTimeout(timeout) {
const timeoutPromise = new Promise((resolve, reject) => setTimeout(() => {
reject(new Error(`Promise rejected by timeout (${timeout} ms)`));
}, timeout));
this._promise = Promise.race([this._promise, timeoutPromise]);
}
_wrapWithFinally() {
this._promise = promiseFinally(this._promise, () => this._isFulfilled = true);
}
}
module.exports = Pending;

@@ -84,2 +84,22 @@ 'use strict';

});
it('should set isFulfilled after reject (by error in fn)', function () {
assert.ok(this.pending.isFulfilled);
const res = this.pending.call(() => { throw new Error('err'); });
assert.notOk(this.pending.isFulfilled);
return assert.isRejected(res, 'err')
.then(() => assert.ok(this.pending.isFulfilled));
});
it('should resolve before timeout', function () {
const res = this.pending.call(() => {}, 10);
setTimeout(() => this.pending.resolve('foo'), 5);
return assert.eventually.equal(res, 'foo');
});
it('should reject after timeout', function () {
const res = this.pending.call(() => {}, 10);
setTimeout(() => this.pending.resolve('foo'), 20);
return assert.isRejected(res, 'Promise rejected by timeout (10 ms)');
});
});

@@ -57,5 +57,6 @@ 'use strict';

let id;
this.pendings.add(pid => id = pid);
const p = this.pendings.add(pid => id = pid);
this.pendings.resolve(id, 'foo');
assert.notOk(this.pendings.has(id));
return assert.isFulfilled(p)
.then(() => assert.notOk(this.pendings.has(id)));
});

@@ -120,11 +121,12 @@

it('should delete promise after resolve', function () {
this.pendings.set(1, () => {});
const p = this.pendings.set(1, () => {});
this.pendings.resolve(1, 1);
assert.notOk(this.pendings.has(1));
return assert.isFulfilled(p)
.then(() => assert.notOk(this.pendings.has(1)));
});
it('should throw if called with the same id', function () {
this.pendings.set(1, () => {});
const res = this.pendings.set(1, () => {});
return assert.isRejected(res, 'Promise with id 1 is already pending');
it('should return the same promise for second call with the same id', function () {
const p1 = this.pendings.set(1, () => {});
const p2 = this.pendings.set(1, () => {});
assert.equal(p1, p2);
});

@@ -170,12 +172,13 @@

it('should return false for resolved promise', function () {
this.pendings.set(1, () => {});
const p = this.pendings.set(1, () => {});
this.pendings.resolve(1);
assert.notOk(this.pendings.has(1));
return assert.isFulfilled(p)
.then(() => assert.notOk(this.pendings.has(1)));
});
it('should return false for rejected promise', function () {
const res = this.pendings.set(1, () => {});
const p = this.pendings.set(1, () => {});
this.pendings.reject(1);
assert.notOk(this.pendings.has(1));
return assert.isRejected(res);
return assert.isRejected(p)
.then(() => assert.notOk(this.pendings.has(1)));
});

@@ -182,0 +185,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc