websocket-as-promised
Advanced tools
Comparing version 0.3.2 to 0.4.0
194
lib/index.js
@@ -18,13 +18,7 @@ 'use strict'; | ||
var Channel = require('chnl'); | ||
var Pendings = require('pendings'); | ||
var ControlledPromise = require('controlled-promise'); | ||
var Requests = require('./requests'); | ||
var utils = require('./utils'); | ||
var defaultOptions = require('./options'); | ||
var DEFAULT_OPTIONS = { | ||
createWebSocket: function createWebSocket(url) { | ||
return new WebSocket(url); | ||
}, | ||
idProp: 'id', | ||
timeout: 0 | ||
}; | ||
// see: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants | ||
@@ -47,6 +41,8 @@ var STATE = { | ||
* | ||
* // todo: use options.js | ||
* @param {String} url WebSocket URL | ||
* @param {Object} [options] | ||
* @param {Function} [options.createWebSocket=url => new Websocket(url)] custom WebSocket creation method | ||
* @param {String} [options.idProp="id"] id property name attached to each message | ||
* @param {Function} [options.createWebSocket=url => new Websocket(url)] custom WebSocket creation function | ||
* @param {Function} [options.packMessage] custom packing message function | ||
* @param {Function} [options.packMessage] custom unpacking message function | ||
* @param {Number} [options.timeout=0] default timeout for requests | ||
@@ -58,9 +54,10 @@ */ | ||
this._url = url; | ||
this._options = Object.assign({}, DEFAULT_OPTIONS, utils.removeUndefined(options)); | ||
this._opening = new Pendings.Pending(); | ||
this._closing = new Pendings.Pending(); | ||
this._pendingRequests = new Pendings({ timeout: this._options.timeout }); | ||
this._options = utils.mergeDefaults(options, defaultOptions); | ||
this._opening = new ControlledPromise(); | ||
this._closing = new ControlledPromise(); | ||
this._requests = new Requests(); | ||
this._onMessage = new Channel(); | ||
this._onClose = new Channel(); | ||
this._ws = null; | ||
this._wsSubscription = null; | ||
} | ||
@@ -88,21 +85,25 @@ | ||
if (this.isClosing) { | ||
return Promise.reject('Can not open closing WebSocket'); | ||
} else { | ||
var _options = this._options, | ||
timeout = _options.timeout, | ||
createWebSocket = _options.createWebSocket; | ||
return Promise.reject(new Error('Can not open closing WebSocket connection')); | ||
} | ||
if (this.isOpened) { | ||
return this._opening.promise; | ||
} | ||
return this._opening.call(function () { | ||
var timeout = _this._options.timeout; | ||
return this._opening.call(function () { | ||
_this._closing.reset(); | ||
_this._ws = createWebSocket(_this._url); | ||
_this._addWsListeners(); | ||
}, timeout); | ||
} | ||
_this._opening.timeout(timeout, 'Can\'t open WebSocket connection within allowed timeout: ' + timeout + ' ms'); | ||
_this._opening.promise.catch(function (e) { | ||
return _this._cleanupForClose(e); | ||
}); | ||
_this._createWS(); | ||
}); | ||
} | ||
/** | ||
* Performs JSON request and waits for response. | ||
* Performs request and waits for response. | ||
* | ||
* @param {Object} data | ||
* @param {Object} [options] | ||
* @param {String} [options.requestId] | ||
* @param {String} [options.requestIdPrefix] | ||
* @param {Number} [options.timeout] | ||
@@ -114,35 +115,21 @@ * @returns {Promise} | ||
key: 'request', | ||
value: function request(data, options) { | ||
value: function request(data) { | ||
var _this2 = this; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (!data || (typeof data === 'undefined' ? 'undefined' : _typeof(data)) !== 'object') { | ||
return Promise.reject(new Error('WebSocket request data should be a plain object, got ' + data)); | ||
} | ||
var idProp = this._options.idProp; | ||
var fn = function fn(id) { | ||
data[idProp] = id; | ||
_this2.sendJson(data); | ||
}; | ||
var id = data[idProp]; | ||
var promise = id === undefined ? this._pendingRequests.add(fn, options) : this._pendingRequests.set(id, fn, options); | ||
return promise.catch(handleTimeoutError); | ||
var requestId = options.requestId || utils.generateId(options.requestIdPrefix); | ||
var message = this._options.packMessage(requestId, data); | ||
var timeout = options.timeout !== undefined ? options.timeout : this._options.timeout; | ||
return this._requests.create(requestId, function () { | ||
return _this2.send(message); | ||
}, timeout); | ||
} | ||
/** | ||
* Sends JSON data and does not wait for response. | ||
* Sends any data by WebSocket. | ||
* | ||
* @param {Object} data | ||
*/ | ||
}, { | ||
key: 'sendJson', | ||
value: function sendJson(data) { | ||
var dataStr = JSON.stringify(data); | ||
this.send(dataStr); | ||
} | ||
/** | ||
* Sends any WebSocket compatible data. | ||
* | ||
* @param {String|ArrayBuffer|Blob} data | ||
@@ -172,28 +159,44 @@ */ | ||
this._opening.reset(new Error('Connection closing by client')); | ||
if (this.isClosed) { | ||
return Promise.resolve(this._closing.value); | ||
} | ||
return this._closing.call(function () { | ||
if (_this3._ws) { | ||
_this3._ws.close(); | ||
} else { | ||
// case: close without open | ||
_this3._closing.resolve(); | ||
} | ||
}, this._options.timeout); | ||
var timeout = _this3._options.timeout; | ||
_this3._closing.timeout(timeout, 'Can\'t close WebSocket connection within allowed timeout: ' + timeout + ' ms'); | ||
_this3._ws.close(); | ||
}); | ||
} | ||
}, { | ||
key: '_addWsListeners', | ||
value: function _addWsListeners() { | ||
key: '_createWS', | ||
value: function _createWS() { | ||
var _this4 = this; | ||
this._ws = this._options.createWebSocket(this._url); | ||
this._wsSubscription = new Channel.Subscription([{ channel: this._ws, event: 'open', listener: function listener(e) { | ||
return _this4._handleOpen(e); | ||
} }, { channel: this._ws, event: 'message', listener: function listener(e) { | ||
return _this4._handleMessage(e); | ||
} }, { channel: this._ws, event: 'error', listener: function listener(e) { | ||
return _this4._handleError(e); | ||
} }, { channel: this._ws, event: 'close', listener: function listener(e) { | ||
return _this4._handleClose(e); | ||
} }]).on(); | ||
} | ||
}, { | ||
key: '_addWSListeners', | ||
value: function _addWSListeners() { | ||
var _this5 = this; | ||
this._ws.addEventListener('open', function (event) { | ||
return _this4._handleOpen(event); | ||
return _this5._handleOpen(event); | ||
}); | ||
this._ws.addEventListener('message', function (event) { | ||
return _this4._handleMessage(event); | ||
return _this5._handleMessage(event); | ||
}); | ||
this._ws.addEventListener('error', function (event) { | ||
return _this4._handleError(event); | ||
return _this5._handleError(event); | ||
}); | ||
this._ws.addEventListener('close', function (event) { | ||
return _this4._handleClose(event); | ||
return _this5._handleClose(event); | ||
}); | ||
@@ -208,14 +211,15 @@ } | ||
key: '_handleMessage', | ||
value: function _handleMessage(_ref) { | ||
var data = _ref.data; | ||
var jsonData = void 0; | ||
value: function _handleMessage(event) { | ||
var message = event.data; | ||
var requestId = void 0, | ||
data = void 0; | ||
try { | ||
jsonData = JSON.parse(data); | ||
var id = jsonData && jsonData[this._options.idProp]; | ||
this._pendingRequests.tryResolve(id, jsonData); | ||
var result = this._options.unpackMessage(message); | ||
requestId = result.requestId; | ||
data = result.data; | ||
} catch (e) { | ||
// do nothing if can not parse data | ||
// do nothing if can not unpack message | ||
} | ||
this._onMessage.dispatch(jsonData, data); | ||
this._onMessage.dispatchAsync(message, data); | ||
this._requests.resolve(requestId, data); | ||
} | ||
@@ -225,19 +229,31 @@ }, { | ||
value: function _handleError() { | ||
// todo: when this event comes? | ||
// currently no specific handling of this event | ||
} | ||
}, { | ||
key: '_handleClose', | ||
value: function _handleClose(_ref2) { | ||
var reason = _ref2.reason, | ||
code = _ref2.code; | ||
var error = new Error('Connection closed with reason: ' + reason + ' (' + code + ')'); | ||
// todo: removeWsListeners | ||
value: function _handleClose(event) { | ||
this._onClose.dispatchAsync(event); | ||
this._closing.resolve(event); | ||
var error = new Error('WebSocket connection closed with reason: ' + event.reason + ' (' + event.code + ')'); | ||
if (this._opening.isPending) { | ||
this._opening.reject(error); | ||
} | ||
this._cleanupForClose(error); | ||
} | ||
}, { | ||
key: '_cleanupWS', | ||
value: function _cleanupWS() { | ||
if (this._wsSubscription) { | ||
this._wsSubscription.off(); | ||
this._wsSubscription = null; | ||
} | ||
this._ws = null; | ||
this._closing.resolve({ reason: reason, code: code }); | ||
this._pendingRequests.rejectAll(error); | ||
this._opening.reset(error); | ||
this._onClose.dispatchAsync({ reason: reason, code: code }); | ||
} | ||
}, { | ||
key: '_cleanupForClose', | ||
value: function _cleanupForClose(error) { | ||
this._cleanupWS(); | ||
this._requests.rejectAll(error); | ||
} | ||
}, { | ||
key: 'ws', | ||
@@ -334,10 +350,2 @@ get: function get() { | ||
function handleTimeoutError(e) { | ||
// inheritance from built-in classes does not work after babel transpile :( | ||
// does not work: e instanceof Pendings.TimeoutError --> always false | ||
// see: https://stackoverflow.com/questions/42064466/instanceof-using-es6-class-inheritance-chain-doesnt-work | ||
var error = e && e.timeout !== undefined ? new Error('Request rejected by timeout (' + e.timeout + ' ms)') : e; | ||
return Promise.reject(error); | ||
} | ||
module.exports = WebSocketAsPromised; |
@@ -7,5 +7,8 @@ 'use strict'; | ||
* Utils | ||
* @private | ||
*/ | ||
exports.mergeDefaults = function (options, defaultOptions) { | ||
return Object.assign({}, defaultOptions, exports.removeUndefined(options)); | ||
}; | ||
exports.removeUndefined = function (obj) { | ||
@@ -18,2 +21,6 @@ if (obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') { | ||
return obj; | ||
}; | ||
exports.generateId = function (prefix) { | ||
return '' + (prefix || '') + Date.now() + '-' + Math.random(); | ||
}; |
{ | ||
"name": "websocket-as-promised", | ||
"version": "0.3.2", | ||
"version": "0.4.0", | ||
"description": "Promise-based WebSocket wrapper", | ||
@@ -21,12 +21,11 @@ "author": { | ||
"babel": "babel src --out-dir lib", | ||
"test": "mocha test/index.test.js", | ||
"test": "mocha test/specs --require=test/globals.js", | ||
"test-lib": "TEST_LIB=1 npm t", | ||
"ci": "npm run code && npm run babel && npm run test-lib", | ||
"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", | ||
"docs": "jsdoc2md --template README_TEMPLATE.md --files src/index.js > README.md", | ||
"release": "npm run code && npm run babel && npm run test-lib && npm version $VER && npm publish && git push --follow-tags --no-verify", | ||
"release-patch": "VER=patch npm run release", | ||
"release-minor": "VER=minor npm run release", | ||
"precommit": "npm run lint-staged && npm t", | ||
"prepush": "npm run code && npm t", | ||
"prepublish": "npm run babel && npm run test-lib" | ||
"prepush": "npm run code && npm t" | ||
}, | ||
@@ -44,3 +43,4 @@ "lint-staged": { | ||
"chnl": "^0.4.0", | ||
"pendings": "^0.2.3" | ||
"controlled-promise": "^0.1.2", | ||
"promise.prototype.finally": "^3.0.1" | ||
}, | ||
@@ -47,0 +47,0 @@ "devDependencies": { |
@@ -79,3 +79,2 @@ # websocket-as-promised | ||
* [.request(data, [options])](#WebSocketAsPromised+request) ⇒ <code>Promise</code> | ||
* [.sendJson(data)](#WebSocketAsPromised+sendJson) | ||
* [.send(data)](#WebSocketAsPromised+send) | ||
@@ -90,3 +89,5 @@ * [.close()](#WebSocketAsPromised+close) ⇒ <code>Promise</code> | ||
// todo: use options.js | ||
| Param | Type | Default | Description | | ||
@@ -96,4 +97,5 @@ | --- | --- | --- | --- | | ||
| [options] | <code>Object</code> | | | | ||
| [options.createWebSocket] | <code>function</code> | <code>url => new Websocket(url)</code> | custom WebSocket creation method | | ||
| [options.idProp] | <code>String</code> | <code>"id"</code> | id property name attached to each message | | ||
| [options.createWebSocket] | <code>function</code> | <code>url => new Websocket(url)</code> | custom WebSocket creation function | | ||
| [options.packMessage] | <code>function</code> | | custom packing message function | | ||
| [options.packMessage] | <code>function</code> | | custom unpacking message function | | ||
| [options.timeout] | <code>Number</code> | <code>0</code> | default timeout for requests | | ||
@@ -136,4 +138,4 @@ | ||
Listener accepts two arguments: | ||
1. original `event.data` | ||
2. `jsonData` if JSON parse succeeded | ||
1. `jsonData` if JSON parse succeeded | ||
2. original `event.data` | ||
@@ -163,3 +165,3 @@ **Kind**: instance property of [<code>WebSocketAsPromised</code>](#WebSocketAsPromised) | ||
### wsp.request(data, [options]) ⇒ <code>Promise</code> | ||
Performs JSON request and waits for response. | ||
Performs request and waits for response. | ||
@@ -172,19 +174,10 @@ **Kind**: instance method of [<code>WebSocketAsPromised</code>](#WebSocketAsPromised) | ||
| [options] | <code>Object</code> | | ||
| [options.requestId] | <code>String</code> | | ||
| [options.requestIdPrefix] | <code>String</code> | | ||
| [options.timeout] | <code>Number</code> | | ||
<a name="WebSocketAsPromised+sendJson"></a> | ||
### wsp.sendJson(data) | ||
Sends JSON data and does not wait for response. | ||
**Kind**: instance method of [<code>WebSocketAsPromised</code>](#WebSocketAsPromised) | ||
| Param | Type | | ||
| --- | --- | | ||
| data | <code>Object</code> | | ||
<a name="WebSocketAsPromised+send"></a> | ||
### wsp.send(data) | ||
Sends any WebSocket compatible data. | ||
Sends any data by WebSocket. | ||
@@ -191,0 +184,0 @@ **Kind**: instance method of [<code>WebSocketAsPromised</code>](#WebSocketAsPromised) |
153
src/index.js
@@ -10,11 +10,7 @@ /** | ||
const Channel = require('chnl'); | ||
const Pendings = require('pendings'); | ||
const ControlledPromise = require('controlled-promise'); | ||
const Requests = require('./requests'); | ||
const utils = require('./utils'); | ||
const defaultOptions = require('./options'); | ||
const DEFAULT_OPTIONS = { | ||
createWebSocket: url => new WebSocket(url), | ||
idProp: 'id', | ||
timeout: 0, | ||
}; | ||
// see: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants | ||
@@ -36,6 +32,8 @@ const STATE = { | ||
* | ||
* // todo: use options.js | ||
* @param {String} url WebSocket URL | ||
* @param {Object} [options] | ||
* @param {Function} [options.createWebSocket=url => new Websocket(url)] custom WebSocket creation method | ||
* @param {String} [options.idProp="id"] id property name attached to each message | ||
* @param {Function} [options.createWebSocket=url => new Websocket(url)] custom WebSocket creation function | ||
* @param {Function} [options.packMessage] custom packing message function | ||
* @param {Function} [options.packMessage] custom unpacking message function | ||
* @param {Number} [options.timeout=0] default timeout for requests | ||
@@ -45,9 +43,10 @@ */ | ||
this._url = url; | ||
this._options = Object.assign({}, DEFAULT_OPTIONS, utils.removeUndefined(options)); | ||
this._opening = new Pendings.Pending(); | ||
this._closing = new Pendings.Pending(); | ||
this._pendingRequests = new Pendings({timeout: this._options.timeout}); | ||
this._options = utils.mergeDefaults(options, defaultOptions); | ||
this._opening = new ControlledPromise(); | ||
this._closing = new ControlledPromise(); | ||
this._requests = new Requests(); | ||
this._onMessage = new Channel(); | ||
this._onClose = new Channel(); | ||
this._ws = null; | ||
this._wsSubscription = null; | ||
} | ||
@@ -135,50 +134,38 @@ | ||
if (this.isClosing) { | ||
return Promise.reject(`Can not open closing WebSocket`); | ||
} else { | ||
const {timeout, createWebSocket} = this._options; | ||
return this._opening.call(() => { | ||
this._closing.reset(); | ||
this._ws = createWebSocket(this._url); | ||
this._addWsListeners(); | ||
}, timeout); | ||
return Promise.reject(new Error(`Can not open closing WebSocket connection`)); | ||
} | ||
if (this.isOpened) { | ||
return this._opening.promise; | ||
} | ||
return this._opening.call(() => { | ||
const {timeout} = this._options; | ||
this._opening.timeout(timeout, `Can't open WebSocket connection within allowed timeout: ${timeout} ms`); | ||
this._opening.promise.catch(e => this._cleanupForClose(e)); | ||
this._createWS(); | ||
}); | ||
} | ||
/** | ||
* Performs JSON request and waits for response. | ||
* Performs request and waits for response. | ||
* | ||
* @param {Object} data | ||
* @param {Object} [options] | ||
* @param {String} [options.requestId] | ||
* @param {String} [options.requestIdPrefix] | ||
* @param {Number} [options.timeout] | ||
* @returns {Promise} | ||
*/ | ||
request(data, options) { | ||
request(data, options = {}) { | ||
if (!data || typeof data !== 'object') { | ||
return Promise.reject(new Error(`WebSocket request data should be a plain object, got ${data}`)); | ||
} | ||
const {idProp} = this._options; | ||
const fn = id => { | ||
data[idProp] = id; | ||
this.sendJson(data); | ||
}; | ||
const id = data[idProp]; | ||
const promise = id === undefined | ||
? this._pendingRequests.add(fn, options) | ||
: this._pendingRequests.set(id, fn, options); | ||
return promise.catch(handleTimeoutError); | ||
const requestId = options.requestId || utils.generateId(options.requestIdPrefix); | ||
const message = this._options.packMessage(requestId, data); | ||
const timeout = options.timeout !== undefined ? options.timeout : this._options.timeout; | ||
return this._requests.create(requestId, () => this.send(message), timeout); | ||
} | ||
/** | ||
* Sends JSON data and does not wait for response. | ||
* Sends any data by WebSocket. | ||
* | ||
* @param {Object} data | ||
*/ | ||
sendJson(data) { | ||
const dataStr = JSON.stringify(data); | ||
this.send(dataStr); | ||
} | ||
/** | ||
* Sends any WebSocket compatible data. | ||
* | ||
* @param {String|ArrayBuffer|Blob} data | ||
@@ -200,14 +187,23 @@ */ | ||
close() { | ||
this._opening.reset(new Error('Connection closing by client')); | ||
if (this.isClosed) { | ||
return Promise.resolve(this._closing.value); | ||
} | ||
return this._closing.call(() => { | ||
if (this._ws) { | ||
this._ws.close(); | ||
} else { | ||
// case: close without open | ||
this._closing.resolve(); | ||
} | ||
}, this._options.timeout); | ||
const {timeout} = this._options; | ||
this._closing.timeout(timeout, `Can't close WebSocket connection within allowed timeout: ${timeout} ms`); | ||
this._ws.close(); | ||
}); | ||
} | ||
_addWsListeners() { | ||
_createWS() { | ||
this._ws = this._options.createWebSocket(this._url); | ||
this._wsSubscription = new Channel.Subscription([ | ||
{channel: this._ws, event: 'open', listener: e => this._handleOpen(e)}, | ||
{channel: this._ws, event: 'message', listener: e => this._handleMessage(e)}, | ||
{channel: this._ws, event: 'error', listener: e => this._handleError(e)}, | ||
{channel: this._ws, event: 'close', listener: e => this._handleClose(e)}, | ||
]).on(); | ||
} | ||
_addWSListeners() { | ||
this._ws.addEventListener('open', event => this._handleOpen(event)); | ||
@@ -223,37 +219,44 @@ this._ws.addEventListener('message', event => this._handleMessage(event)); | ||
_handleMessage({data}) { | ||
let jsonData; | ||
_handleMessage(event) { | ||
const message = event.data; | ||
let requestId, data; | ||
try { | ||
jsonData = JSON.parse(data); | ||
const id = jsonData && jsonData[this._options.idProp]; | ||
this._pendingRequests.tryResolve(id, jsonData); | ||
const result = this._options.unpackMessage(message); | ||
requestId = result.requestId; | ||
data = result.data; | ||
} catch(e) { | ||
// do nothing if can not parse data | ||
// do nothing if can not unpack message | ||
} | ||
this._onMessage.dispatch(jsonData, data); | ||
this._onMessage.dispatchAsync(message, data); | ||
this._requests.resolve(requestId, data); | ||
} | ||
_handleError() { | ||
// todo: when this event comes? | ||
// currently no specific handling of this event | ||
} | ||
_handleClose({reason, code}) { | ||
const error = new Error(`Connection closed with reason: ${reason} (${code})`); | ||
// todo: removeWsListeners | ||
_handleClose(event) { | ||
this._onClose.dispatchAsync(event); | ||
this._closing.resolve(event); | ||
const error = new Error(`WebSocket connection closed with reason: ${event.reason} (${event.code})`); | ||
if (this._opening.isPending) { | ||
this._opening.reject(error); | ||
} | ||
this._cleanupForClose(error); | ||
} | ||
_cleanupWS() { | ||
if (this._wsSubscription) { | ||
this._wsSubscription.off(); | ||
this._wsSubscription = null; | ||
} | ||
this._ws = null; | ||
this._closing.resolve({reason, code}); | ||
this._pendingRequests.rejectAll(error); | ||
this._opening.reset(error); | ||
this._onClose.dispatchAsync({reason, code}); | ||
} | ||
} | ||
function handleTimeoutError(e) { | ||
// inheritance from built-in classes does not work after babel transpile :( | ||
// does not work: e instanceof Pendings.TimeoutError --> always false | ||
// see: https://stackoverflow.com/questions/42064466/instanceof-using-es6-class-inheritance-chain-doesnt-work | ||
const error = e && e.timeout !== undefined ? new Error(`Request rejected by timeout (${e.timeout} ms)`) : e; | ||
return Promise.reject(error); | ||
_cleanupForClose(error) { | ||
this._cleanupWS(); | ||
this._requests.rejectAll(error); | ||
} | ||
} | ||
module.exports = WebSocketAsPromised; |
/** | ||
* Utils | ||
* @private | ||
*/ | ||
exports.mergeDefaults = function (options, defaultOptions) { | ||
return Object.assign({}, defaultOptions, exports.removeUndefined(options)); | ||
}; | ||
exports.removeUndefined = function (obj) { | ||
@@ -12,1 +15,5 @@ if (obj && typeof obj === 'object') { | ||
}; | ||
exports.generateId = function (prefix) { | ||
return `${prefix || ''}${Date.now()}-${Math.random()}`; | ||
}; |
@@ -56,2 +56,4 @@ // todo: make this a separate project! | ||
connection.sendUTF(JSON.stringify(data)); | ||
} else if (data.noResponse) { | ||
// nothing | ||
} else if (data.delay) { | ||
@@ -58,0 +60,0 @@ setTimeout(() => connection.sendUTF(message.utf8Data), data.delay); |
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
53607
28
1228
3
196
2
+ Addedcontrolled-promise@^0.1.2
+ Addedarray-buffer-byte-length@1.0.2(transitive)
+ Addedarraybuffer.prototype.slice@1.0.4(transitive)
+ Addedasync-function@1.0.0(transitive)
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedcall-bind@1.0.8(transitive)
+ Addedcall-bind-apply-helpers@1.0.2(transitive)
+ Addedcall-bound@1.0.3(transitive)
+ Addedcontrolled-promise@0.1.2(transitive)
+ Addeddata-view-buffer@1.0.2(transitive)
+ Addeddata-view-byte-length@1.0.2(transitive)
+ Addeddata-view-byte-offset@1.0.1(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddefine-properties@1.2.1(transitive)
+ Addeddunder-proto@1.0.1(transitive)
+ Addedes-abstract@1.23.9(transitive)
+ Addedes-define-property@1.0.1(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedes-object-atoms@1.1.1(transitive)
+ Addedes-set-tostringtag@2.1.0(transitive)
+ Addedes-to-primitive@1.3.0(transitive)
+ Addedfor-each@0.3.5(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedfunction.prototype.name@1.1.8(transitive)
+ Addedfunctions-have-names@1.2.3(transitive)
+ Addedget-intrinsic@1.2.7(transitive)
+ Addedget-proto@1.0.1(transitive)
+ Addedget-symbol-description@1.1.0(transitive)
+ Addedglobalthis@1.0.4(transitive)
+ Addedgopd@1.2.0(transitive)
+ Addedhas-bigints@1.1.0(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.2.0(transitive)
+ Addedhas-symbols@1.1.0(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedinternal-slot@1.1.0(transitive)
+ Addedis-array-buffer@3.0.5(transitive)
+ Addedis-async-function@2.1.1(transitive)
+ Addedis-bigint@1.1.0(transitive)
+ Addedis-boolean-object@1.2.2(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-data-view@1.0.2(transitive)
+ Addedis-date-object@1.1.0(transitive)
+ Addedis-finalizationregistry@1.1.1(transitive)
+ Addedis-generator-function@1.1.0(transitive)
+ Addedis-map@2.0.3(transitive)
+ Addedis-number-object@1.1.1(transitive)
+ Addedis-regex@1.2.1(transitive)
+ Addedis-set@2.0.3(transitive)
+ Addedis-shared-array-buffer@1.0.4(transitive)
+ Addedis-string@1.1.1(transitive)
+ Addedis-symbol@1.1.1(transitive)
+ Addedis-typed-array@1.1.15(transitive)
+ Addedis-weakmap@2.0.2(transitive)
+ Addedis-weakref@1.1.1(transitive)
+ Addedis-weakset@2.0.4(transitive)
+ Addedisarray@2.0.5(transitive)
+ Addedmath-intrinsics@1.1.0(transitive)
+ Addedobject-inspect@1.13.4(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedobject.assign@4.1.7(transitive)
+ Addedown-keys@1.0.1(transitive)
+ Addedpossible-typed-array-names@1.1.0(transitive)
+ Addedpromise.prototype.finally@3.1.8(transitive)
+ Addedreflect.getprototypeof@1.0.10(transitive)
+ Addedregexp.prototype.flags@1.5.4(transitive)
+ Addedsafe-array-concat@1.1.3(transitive)
+ Addedsafe-push-apply@1.0.0(transitive)
+ Addedsafe-regex-test@1.1.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedset-function-name@2.0.2(transitive)
+ Addedset-proto@1.0.0(transitive)
+ Addedside-channel@1.1.0(transitive)
+ Addedside-channel-list@1.0.0(transitive)
+ Addedside-channel-map@1.0.1(transitive)
+ Addedside-channel-weakmap@1.0.2(transitive)
+ Addedstring.prototype.trim@1.2.10(transitive)
+ Addedstring.prototype.trimend@1.0.9(transitive)
+ Addedstring.prototype.trimstart@1.0.8(transitive)
+ Addedtyped-array-buffer@1.0.3(transitive)
+ Addedtyped-array-byte-length@1.0.3(transitive)
+ Addedtyped-array-byte-offset@1.0.4(transitive)
+ Addedtyped-array-length@1.0.7(transitive)
+ Addedunbox-primitive@1.1.0(transitive)
+ Addedwhich-boxed-primitive@1.1.1(transitive)
+ Addedwhich-builtin-type@1.2.1(transitive)
+ Addedwhich-collection@1.0.2(transitive)
+ Addedwhich-typed-array@1.1.18(transitive)
- Removedpendings@^0.2.3
- Removedpendings@0.2.7(transitive)