diff --git a/README.md b/README.md
index 03a2e11..82a0bd1 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,14 @@
![David](https://img.shields.io/david/DigitalBrainJS/c-promise)
## SYNOPSIS :sparkles:
-A Promise class built on top of the native that supports some additional features such as cancellation, timeouts, progress capturing and concurrency limit.
+
+This library provides an advanced version of the built-in Promise by subclassing.
+You might be interested in using it if you need the following features:
+- promise cancellation (including nested)
+- progress capturing
+- promise suspending
+- timeouts
+- concurrent limit for `all` and `allSettled` methods with `mapper` reducer
In terms of the library **the cancellation means rejection with a special error subclass**.
@@ -79,6 +86,8 @@ has lost its relevance to you.
- `CPromise.all` supports concurrency limit
- `CPromise.all` and `CPromise.race` methods have cancellation support, so the others nested pending promises will be canceled
when the result promise settled
+ - promise suspending (using `pause` and `resume` methods)
+ - custom signals (`emitSignal`)
- `delay` method to return promise that will be resolved with the value after timeout
- ability to set the `weight` for each promise in the chain to manage the impact on chain progress
- ability to attach meta info on each setting of the progress
@@ -222,7 +231,7 @@ const promise= CPromise.from(function*(){
yield [[CPromise.delay(1000), CPromise.delay(1500)]] // resolve chains using CPromise.race([...chains]);
yield new CPromise(resolve=> resolve(true)); // any thenable object will be resolved
return "It works!";
-}, [1, 2, 3])
+})
.progress(value=> console.log(`Progress: ${value}`))
.then(message=> console.log(`Done: ${message}`));
````
@@ -237,185 +246,201 @@ Cancellable Promise with extra features
* [CPromise](#module_CPromise)
- * [~CPromiseScope](#module_CPromise..CPromiseScope) ⇐ TinyEventEmitter
- * [new CPromiseScope(resolve, reject, options)](#new_module_CPromise..CPromiseScope_new)
- * _instance_
- * [.signal](#module_CPromise..CPromiseScope+signal) : AbortSignal
- * [.isPending](#module_CPromise..CPromiseScope+isPending) ⇒ Boolean
- * [.isCanceled](#module_CPromise..CPromiseScope+isCanceled) ⇒ Boolean
- * [.isCaptured](#module_CPromise..CPromiseScope+isCaptured) ⇒ boolean
- * [.onCancel(listener)](#module_CPromise..CPromiseScope+onCancel) ⇒ CPromiseScope
- * [.totalWeight([weight])](#module_CPromise..CPromiseScope+totalWeight) ⇒ Number
\| CPromiseScope
- * [.innerWeight([weight])](#module_CPromise..CPromiseScope+innerWeight) ⇒ Number
\| CPromiseScope
- * [.progress(value, [data])](#module_CPromise..CPromiseScope+progress)
- * [.propagate(type, data)](#module_CPromise..CPromiseScope+propagate) ⇒ CPromiseScope
- * [.captureProgress([options])](#module_CPromise..CPromiseScope+captureProgress) ⇒ CPromiseScope
- * [.scopes()](#module_CPromise..CPromiseScope+scopes) ⇒ Array.<CPromiseScope>
- * [.timeout(ms)](#module_CPromise..CPromiseScope+timeout) ⇒ Number
\| CPromiseScope
- * [.weight(weight)](#module_CPromise..CPromiseScope+weight) ⇒ Number
\| CPromiseScope
- * [.label(label)](#module_CPromise..CPromiseScope+label) ⇒ Number
\| CPromiseScope
- * [.resolve(value)](#module_CPromise..CPromiseScope+resolve)
- * [.reject(err)](#module_CPromise..CPromiseScope+reject)
- * [.done(err, value)](#module_CPromise..CPromiseScope+done)
- * [.cancel([reason])](#module_CPromise..CPromiseScope+cancel)
- * _static_
- * [.execute(executor, resolve, reject, options)](#module_CPromise..CPromiseScope.execute) ⇒ CPromiseScope
* [~CPromise](#module_CPromise..CPromise) ⇐ Promise
* [new CPromise(executor, [options])](#new_module_CPromise..CPromise_new)
* _instance_
+ * [.signal](#module_CPromise..CPromise+signal) : AbortSignal
* [.isPending](#module_CPromise..CPromise+isPending) ⇒ Boolean
* [.isCanceled](#module_CPromise..CPromise+isCanceled) ⇒ Boolean
- * [.progress(listener)](#module_CPromise..CPromise+progress) ⇒ Number
\| CPromise
- * [.captureProgress(options)](#module_CPromise..CPromise+captureProgress) ⇒ CPromise
- * [.cancel(reason)](#module_CPromise..CPromise+cancel) ⇒ Boolean
+ * [.isCaptured](#module_CPromise..CPromise+isCaptured) ⇒ Boolean
+ * [.isPaused](#module_CPromise..CPromise+isPaused) ⇒ Boolean
+ * [.parent](#module_CPromise..CPromise+parent) ⇒ CPromise
\| null
+ * [.totalWeight([weight])](#module_CPromise..CPromise+totalWeight) ⇒ Number
\| CPromise
+ * [.innerWeight([weight])](#module_CPromise..CPromise+innerWeight) ⇒ Number
\| CPromise
+ * [.progress(value, [data])](#module_CPromise..CPromise+progress) ⇒ Number
\| CPromise
+ * [.propagate(type, data)](#module_CPromise..CPromise+propagate) ⇒ CPromise
+ * [.captureProgress([options])](#module_CPromise..CPromise+captureProgress) ⇒ CPromise
+ * [.scopes()](#module_CPromise..CPromise+scopes) ⇒ Array.<CPromise>
+ * [.timeout([ms])](#module_CPromise..CPromise+timeout) ⇒ Number
\| CPromise
+ * [.weight([weight])](#module_CPromise..CPromise+weight) ⇒ Number
\| CPromise
+ * [.label([label])](#module_CPromise..CPromise+label) ⇒ Number
\| CPromise
+ * [.resolve(value)](#module_CPromise..CPromise+resolve) ⇒ CPromise
+ * [.reject(err)](#module_CPromise..CPromise+reject) ⇒ CPromise
+ * [.pause()](#module_CPromise..CPromise+pause) ⇒ Boolean
+ * [.resume()](#module_CPromise..CPromise+resume) ⇒ Boolean
+ * [.cancel([reason])](#module_CPromise..CPromise+cancel)
+ * [.emitSignal(type, data)](#module_CPromise..CPromise+emitSignal) ⇒ Boolean
* [.delay(ms)](#module_CPromise..CPromise+delay) ⇒ CPromise
* [.then(onFulfilled, [onRejected])](#module_CPromise..CPromise+then) ⇒ CPromise
* [.catch(onRejected, [filter])](#module_CPromise..CPromise+catch) ⇒ CPromise
+ * [.listenersCount(type)](#module_CPromise..CPromise+listenersCount) ⇒ Number
+ * [.hasListeners(type)](#module_CPromise..CPromise+hasListeners) ⇒ Boolean
+ * [.once(type, listener)](#module_CPromise..CPromise+once) ⇒ CPromise
+ * [.emit(type, ...args)](#module_CPromise..CPromise+emit) ⇒ CPromise
+ * [.emitHook(type, ...args)](#module_CPromise..CPromise+emitHook) ⇒ Boolean
* _static_
* [.isCanceledError(thing)](#module_CPromise..CPromise.isCanceledError) ⇒ boolean
* [.delay(ms, value)](#module_CPromise..CPromise.delay) ⇒ CPromise
* [.all(iterable, options)](#module_CPromise..CPromise.all) ⇒ CPromise
* [.race(thenables)](#module_CPromise..CPromise.race) ⇒ CPromise
+ * [.allSettled(iterable, options)](#module_CPromise..CPromise.allSettled) ⇒ CPromise
* [.from(thing, [resolveSignatures])](#module_CPromise..CPromise.from) ⇒ CPromise
- * [~PromiseScopeOptions](#module_CPromise..PromiseScopeOptions) : Object
- * [~onFulfilled](#module_CPromise..onFulfilled) : function
- * [~onRejected](#module_CPromise..onRejected) : function
- * [~OnCancelListener](#module_CPromise..OnCancelListener) : function
+ * [~EventType](#module_CPromise..EventType) : String
\| Symbol
* [~CPromiseExecutorFn](#module_CPromise..CPromiseExecutorFn) : function
- * [~CPromiseOptions](#module_CPromise..CPromiseOptions) : PromiseScopeOptions
\| String
\| Number
+ * [~PromiseOptionsObject](#module_CPromise..PromiseOptionsObject) : Object
+ * [~CPromiseOptions](#module_CPromise..CPromiseOptions) : PromiseOptionsObject
\| String
\| Number
+ * [~OnCancelListener](#module_CPromise..OnCancelListener) : function
+ * [~OnPauseListener](#module_CPromise..OnPauseListener) : function
+ * [~OnResumeListener](#module_CPromise..OnResumeListener) : function
* [~AllOptions](#module_CPromise..AllOptions) : object
-
+
-### CPromise~CPromiseScope ⇐ TinyEventEmitter
-Scope for CPromises instances
+### CPromise~CPromise ⇐ Promise
+CPromise class
**Kind**: inner class of [CPromise
](#module_CPromise)
-**Extends**: TinyEventEmitter
+**Extends**: Promise
-* [~CPromiseScope](#module_CPromise..CPromiseScope) ⇐ TinyEventEmitter
- * [new CPromiseScope(resolve, reject, options)](#new_module_CPromise..CPromiseScope_new)
+* [~CPromise](#module_CPromise..CPromise) ⇐ Promise
+ * [new CPromise(executor, [options])](#new_module_CPromise..CPromise_new)
* _instance_
- * [.signal](#module_CPromise..CPromiseScope+signal) : AbortSignal
- * [.isPending](#module_CPromise..CPromiseScope+isPending) ⇒ Boolean
- * [.isCanceled](#module_CPromise..CPromiseScope+isCanceled) ⇒ Boolean
- * [.isCaptured](#module_CPromise..CPromiseScope+isCaptured) ⇒ boolean
- * [.onCancel(listener)](#module_CPromise..CPromiseScope+onCancel) ⇒ CPromiseScope
- * [.totalWeight([weight])](#module_CPromise..CPromiseScope+totalWeight) ⇒ Number
\| CPromiseScope
- * [.innerWeight([weight])](#module_CPromise..CPromiseScope+innerWeight) ⇒ Number
\| CPromiseScope
- * [.progress(value, [data])](#module_CPromise..CPromiseScope+progress)
- * [.propagate(type, data)](#module_CPromise..CPromiseScope+propagate) ⇒ CPromiseScope
- * [.captureProgress([options])](#module_CPromise..CPromiseScope+captureProgress) ⇒ CPromiseScope
- * [.scopes()](#module_CPromise..CPromiseScope+scopes) ⇒ Array.<CPromiseScope>
- * [.timeout(ms)](#module_CPromise..CPromiseScope+timeout) ⇒ Number
\| CPromiseScope
- * [.weight(weight)](#module_CPromise..CPromiseScope+weight) ⇒ Number
\| CPromiseScope
- * [.label(label)](#module_CPromise..CPromiseScope+label) ⇒ Number
\| CPromiseScope
- * [.resolve(value)](#module_CPromise..CPromiseScope+resolve)
- * [.reject(err)](#module_CPromise..CPromiseScope+reject)
- * [.done(err, value)](#module_CPromise..CPromiseScope+done)
- * [.cancel([reason])](#module_CPromise..CPromiseScope+cancel)
+ * [.signal](#module_CPromise..CPromise+signal) : AbortSignal
+ * [.isPending](#module_CPromise..CPromise+isPending) ⇒ Boolean
+ * [.isCanceled](#module_CPromise..CPromise+isCanceled) ⇒ Boolean
+ * [.isCaptured](#module_CPromise..CPromise+isCaptured) ⇒ Boolean
+ * [.isPaused](#module_CPromise..CPromise+isPaused) ⇒ Boolean
+ * [.parent](#module_CPromise..CPromise+parent) ⇒ CPromise
\| null
+ * [.totalWeight([weight])](#module_CPromise..CPromise+totalWeight) ⇒ Number
\| CPromise
+ * [.innerWeight([weight])](#module_CPromise..CPromise+innerWeight) ⇒ Number
\| CPromise
+ * [.progress(value, [data])](#module_CPromise..CPromise+progress) ⇒ Number
\| CPromise
+ * [.propagate(type, data)](#module_CPromise..CPromise+propagate) ⇒ CPromise
+ * [.captureProgress([options])](#module_CPromise..CPromise+captureProgress) ⇒ CPromise
+ * [.scopes()](#module_CPromise..CPromise+scopes) ⇒ Array.<CPromise>
+ * [.timeout([ms])](#module_CPromise..CPromise+timeout) ⇒ Number
\| CPromise
+ * [.weight([weight])](#module_CPromise..CPromise+weight) ⇒ Number
\| CPromise
+ * [.label([label])](#module_CPromise..CPromise+label) ⇒ Number
\| CPromise
+ * [.resolve(value)](#module_CPromise..CPromise+resolve) ⇒ CPromise
+ * [.reject(err)](#module_CPromise..CPromise+reject) ⇒ CPromise
+ * [.pause()](#module_CPromise..CPromise+pause) ⇒ Boolean
+ * [.resume()](#module_CPromise..CPromise+resume) ⇒ Boolean
+ * [.cancel([reason])](#module_CPromise..CPromise+cancel)
+ * [.emitSignal(type, data)](#module_CPromise..CPromise+emitSignal) ⇒ Boolean
+ * [.delay(ms)](#module_CPromise..CPromise+delay) ⇒ CPromise
+ * [.then(onFulfilled, [onRejected])](#module_CPromise..CPromise+then) ⇒ CPromise
+ * [.catch(onRejected, [filter])](#module_CPromise..CPromise+catch) ⇒ CPromise
+ * [.listenersCount(type)](#module_CPromise..CPromise+listenersCount) ⇒ Number
+ * [.hasListeners(type)](#module_CPromise..CPromise+hasListeners) ⇒ Boolean
+ * [.once(type, listener)](#module_CPromise..CPromise+once) ⇒ CPromise
+ * [.emit(type, ...args)](#module_CPromise..CPromise+emit) ⇒ CPromise
+ * [.emitHook(type, ...args)](#module_CPromise..CPromise+emitHook) ⇒ Boolean
* _static_
- * [.execute(executor, resolve, reject, options)](#module_CPromise..CPromiseScope.execute) ⇒ CPromiseScope
+ * [.isCanceledError(thing)](#module_CPromise..CPromise.isCanceledError) ⇒ boolean
+ * [.delay(ms, value)](#module_CPromise..CPromise.delay) ⇒ CPromise
+ * [.all(iterable, options)](#module_CPromise..CPromise.all) ⇒ CPromise
+ * [.race(thenables)](#module_CPromise..CPromise.race) ⇒ CPromise
+ * [.allSettled(iterable, options)](#module_CPromise..CPromise.allSettled) ⇒ CPromise
+ * [.from(thing, [resolveSignatures])](#module_CPromise..CPromise.from) ⇒ CPromise
-
+
-#### new CPromiseScope(resolve, reject, options)
-Constructs PromiseScope instance
+#### new CPromise(executor, [options])
+Constructs new CPromise instance
-| Param | Type |
-| --- | --- |
-| resolve | function
|
-| reject | function
|
-| options | PromiseScopeOptions
|
+| Param | Type | Description |
+| --- | --- | --- |
+| executor | CPromiseExecutorFn
| promise executor function that will be invoked in the context of the new CPromiseScope instance |
+| [options] | CPromiseOptions
| |
-
+
-#### cPromiseScope.signal : AbortSignal
+#### cPromise.signal : AbortSignal
get promise abort signal object
-**Kind**: instance property of [CPromiseScope
](#module_CPromise..CPromiseScope)
-
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.isPending ⇒ Boolean
+#### cPromise.isPending ⇒ Boolean
indicates if the promise is pending
-**Kind**: instance property of [CPromiseScope
](#module_CPromise..CPromiseScope)
-
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.isCanceled ⇒ Boolean
+#### cPromise.isCanceled ⇒ Boolean
indicates if the promise is pending
-**Kind**: instance property of [CPromiseScope
](#module_CPromise..CPromiseScope)
-
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.isCaptured ⇒ boolean
+#### cPromise.isCaptured ⇒ Boolean
indicates if the promise progress is captured
-**Kind**: instance property of [CPromiseScope
](#module_CPromise..CPromiseScope)
-
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.onCancel(listener) ⇒ CPromiseScope
-registers the listener for cancel event
+#### cPromise.isPaused ⇒ Boolean
+indicates if the promise is paused
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-| Param | Type |
-| --- | --- |
-| listener | OnCancelListener
|
+#### cPromise.parent ⇒ CPromise
\| null
+get parent promise
-
+**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.totalWeight([weight]) ⇒ Number
\| CPromiseScope
+#### cPromise.totalWeight([weight]) ⇒ Number
\| CPromise
Set or get the total weight of the inner chains
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
| [weight] | Number
|
-
+
-#### cPromiseScope.innerWeight([weight]) ⇒ Number
\| CPromiseScope
+#### cPromise.innerWeight([weight]) ⇒ Number
\| CPromise
Set or get the total weight of the inner chains
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
| [weight] | Number
|
-
+
-#### cPromiseScope.progress(value, [data])
+#### cPromise.progress(value, [data]) ⇒ Number
\| CPromise
Set promise progress
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type | Description |
| --- | --- | --- |
| value | Number
| a number between [0, 1] |
| [data] | \*
| any data to send for progress event listeners |
-
+
-#### cPromiseScope.propagate(type, data) ⇒ CPromiseScope
+#### cPromise.propagate(type, data) ⇒ CPromise
emit propagate event that will propagate through each promise scope in the chain (bubbling)
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| type | String
\| symbol
| | some type to identify the data kind |
| data | \*
|
| some data |
-
+
-#### cPromiseScope.captureProgress([options]) ⇒ CPromiseScope
+#### cPromise.captureProgress([options]) ⇒ CPromise
capture initial progress state of the chain
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type | Description |
| --- | --- | --- |
@@ -423,224 +448,197 @@ capture initial progress state of the chain
| options.throttle | Number
| set min interval for firing progress event |
| options.innerWeight | Number
| set weight of the nested promises |
-
+
-#### cPromiseScope.scopes() ⇒ Array.<CPromiseScope>
+#### cPromise.scopes() ⇒ Array.<CPromise>
Returns all parent scopes that are in pending state
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
-
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.timeout(ms) ⇒ Number
\| CPromiseScope
+#### cPromise.timeout([ms]) ⇒ Number
\| CPromise
timeout before the promise will be canceled
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type | Description |
| --- | --- | --- |
-| ms | Number
| timeout in ms |
+| [ms] | Number
| timeout in ms |
-
+
-#### cPromiseScope.weight(weight) ⇒ Number
\| CPromiseScope
+#### cPromise.weight([weight]) ⇒ Number
\| CPromise
Sets the promise weight in progress capturing process
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
-**Returns**: Number
\| CPromiseScope
- returns weight if no arguments were specified
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+**Returns**: Number
\| CPromise
- returns weight if no arguments were specified
| Param | Type | Description |
| --- | --- | --- |
-| weight | Number
| any number greater or equal 0 |
+| [weight] | Number
| any number greater or equal 0 |
-
+
-#### cPromiseScope.label(label) ⇒ Number
\| CPromiseScope
+#### cPromise.label([label]) ⇒ Number
\| CPromise
Sets the promise label
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
-**Returns**: Number
\| CPromiseScope
- returns weight if no arguments were specified
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+**Returns**: Number
\| CPromise
- returns weight if no arguments were specified
| Param | Type | Description |
| --- | --- | --- |
-| label | String
| any string |
+| [label] | String
| any string |
-
+
-#### cPromiseScope.resolve(value)
+#### cPromise.resolve(value) ⇒ CPromise
Resolves the promise with given value
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param |
| --- |
| value |
-
+
-#### cPromiseScope.reject(err)
+#### cPromise.reject(err) ⇒ CPromise
Rejects the promise with given error
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param |
| --- |
| err |
-
+
-#### cPromiseScope.done(err, value)
-Resolves or rejects the promise depending on the arguments
+#### cPromise.pause() ⇒ Boolean
+Pause promise
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+
-| Param | Type | Description |
-| --- | --- | --- |
-| err | | error object, if specified the promise will be rejected with this error, resolves otherwise |
-| value | \*
| |
+#### cPromise.resume() ⇒ Boolean
+Resume promise
-
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+
-#### cPromiseScope.cancel([reason])
+#### cPromise.cancel([reason])
throws the CanceledError that cause promise chain cancellation
-**Kind**: instance method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
| [reason] | String
\| Error
|
-
+
-#### CPromiseScope.execute(executor, resolve, reject, options) ⇒ CPromiseScope
-Executes the promise executor in the PromiseScope context
+#### cPromise.emitSignal(type, data) ⇒ Boolean
+Emit a signal of the specific type
-**Kind**: static method of [CPromiseScope
](#module_CPromise..CPromiseScope)
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
-| executor | CPromiseExecutorFn
|
-| resolve | function
|
-| reject | function
|
-| options | Object
|
-
-
-
-### CPromise~CPromise ⇐ Promise
-CPromise class
-
-**Kind**: inner class of [CPromise
](#module_CPromise)
-**Extends**: Promise
-
-* [~CPromise](#module_CPromise..CPromise) ⇐ Promise
- * [new CPromise(executor, [options])](#new_module_CPromise..CPromise_new)
- * _instance_
- * [.isPending](#module_CPromise..CPromise+isPending) ⇒ Boolean
- * [.isCanceled](#module_CPromise..CPromise+isCanceled) ⇒ Boolean
- * [.progress(listener)](#module_CPromise..CPromise+progress) ⇒ Number
\| CPromise
- * [.captureProgress(options)](#module_CPromise..CPromise+captureProgress) ⇒ CPromise
- * [.cancel(reason)](#module_CPromise..CPromise+cancel) ⇒ Boolean
- * [.delay(ms)](#module_CPromise..CPromise+delay) ⇒ CPromise
- * [.then(onFulfilled, [onRejected])](#module_CPromise..CPromise+then) ⇒ CPromise
- * [.catch(onRejected, [filter])](#module_CPromise..CPromise+catch) ⇒ CPromise
- * _static_
- * [.isCanceledError(thing)](#module_CPromise..CPromise.isCanceledError) ⇒ boolean
- * [.delay(ms, value)](#module_CPromise..CPromise.delay) ⇒ CPromise
- * [.all(iterable, options)](#module_CPromise..CPromise.all) ⇒ CPromise
- * [.race(thenables)](#module_CPromise..CPromise.race) ⇒ CPromise
- * [.from(thing, [resolveSignatures])](#module_CPromise..CPromise.from) ⇒ CPromise
+| type | String
\| Symbol
|
+| data | \*
|
-
+
-#### new CPromise(executor, [options])
-Constructs new CPromise instance
+#### cPromise.delay(ms) ⇒ CPromise
+Returns a chain that will be resolved after specified timeout
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
-| Param | Type | Description |
-| --- | --- | --- |
-| executor | CPromiseExecutorFn
| promise executor function that will be invoked in the context of the new CPromiseScope instance |
-| [options] | CPromiseOptions
| |
+| Param | Type |
+| --- | --- |
+| ms | Number
|
-
+
-#### cPromise.isPending ⇒ Boolean
-indicates if the promise is pending
+#### cPromise.then(onFulfilled, [onRejected]) ⇒ CPromise
+returns a CPromise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.
-**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
-
+**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
-#### cPromise.isCanceled ⇒ Boolean
-indicates if promise has been canceled
+| Param | Type |
+| --- | --- |
+| onFulfilled | onFulfilled
|
+| [onRejected] | onRejected
|
-**Kind**: instance property of [CPromise
](#module_CPromise..CPromise)
-
+
-#### cPromise.progress(listener) ⇒ Number
\| CPromise
-returns chains progress synchronously or adds a progress event listener if the argument was specified
+#### cPromise.catch(onRejected, [filter]) ⇒ CPromise
+Catches rejection with optionally specified Error class
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
-| listener | function
|
+| onRejected | function
|
+| [filter] | Error
|
-
+
-#### cPromise.captureProgress(options) ⇒ CPromise
-capture initial progress state of the chain
+#### cPromise.listenersCount(type) ⇒ Number
+returns listeners count of the specific event type
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
-| options | Object
|
-| options.throttle | Number
|
+| type | EventType
|
-
+
-#### cPromise.cancel(reason) ⇒ Boolean
-cancel the promise chain with specified reason
+#### cPromise.hasListeners(type) ⇒ Boolean
+checks if there are listeners of a specific type
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
-**Returns**: Boolean
- true if success
| Param | Type |
| --- | --- |
-| reason | String
|
+| type | String
\| Symbol
|
-
+
-#### cPromise.delay(ms) ⇒ CPromise
-Returns a chain that will be resolved after specified timeout
+#### cPromise.once(type, listener) ⇒ CPromise
+add 'once' listener
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
-| ms | Number
|
+| type | EventType
|
+| listener | function
|
-
+
-#### cPromise.then(onFulfilled, [onRejected]) ⇒ CPromise
-returns a CPromise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.
+#### cPromise.emit(type, ...args) ⇒ CPromise
+emits the event
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
| Param | Type |
| --- | --- |
-| onFulfilled | onFulfilled
|
-| [onRejected] | onRejected
|
+| type | EventType
|
+| ...args | |
-
+
-#### cPromise.catch(onRejected, [filter]) ⇒ CPromise
-Catches rejection with optionally specified Error class
+#### cPromise.emitHook(type, ...args) ⇒ Boolean
+emits the hook event
**Kind**: instance method of [CPromise
](#module_CPromise..CPromise)
+**Returns**: Boolean
- - false if some listener returned false
| Param | Type |
| --- | --- |
-| onRejected | function
|
-| [filter] | Error
|
+| type | EventType
|
+| ...args | |
@@ -692,6 +690,18 @@ returns a promise that fulfills or rejects as soon as one of the promises in an
| --- | --- |
| thenables | Iterable
|
+
+
+#### CPromise.allSettled(iterable, options) ⇒ CPromise
+returns a promise that resolves after all of the given promises have either fulfilled or rejected
+
+**Kind**: static method of [CPromise
](#module_CPromise..CPromise)
+
+| Param | Type |
+| --- | --- |
+| iterable | Iterable
\| Generator
\| GeneratorFunction
|
+| options | AllOptions
|
+
#### CPromise.from(thing, [resolveSignatures]) ⇒ CPromise
@@ -704,41 +714,40 @@ Converts thing to CPromise using the following rules:
- CPromise instance return
| thing | \*
| |
| [resolveSignatures] | boolean
| true
|
-
+
-### CPromise~PromiseScopeOptions : Object
+### CPromise~EventType : String
\| Symbol
**Kind**: inner typedef of [CPromise
](#module_CPromise)
-**Properties**
-
-| Name | Type | Default | Description |
-| --- | --- | --- | --- |
-| label | String
| | the label for the promise |
-| weight | Number
| 1
| the progress weight of the promise |
-| timeout | Number
| 0
| max pending time |
-| signal | AbortSignal
| | AbortController signal |
-
-
+
-### CPromise~onFulfilled : function
+### CPromise~CPromiseExecutorFn : function
**Kind**: inner typedef of [CPromise
](#module_CPromise)
-**this**: CPromiseScope
+**this**: CPromise
| Param | Type |
| --- | --- |
-| value | |
-| scope | CPromiseScope
|
+| resolve | function
|
+| reject | function
|
+| scope | CPromise
|
-
+
-### CPromise~onRejected : function
+### CPromise~PromiseOptionsObject : Object
**Kind**: inner typedef of [CPromise
](#module_CPromise)
-**this**: CPromiseScope
+**Properties**
-| Param | Type |
+| Name | Type |
| --- | --- |
-| err | |
-| scope | CPromiseScope
|
+| label | String
|
+| timeout | Number
|
+| weight | Number
|
+
+
+### CPromise~CPromiseOptions : PromiseOptionsObject
\| String
\| Number
+If value is a number it will be considered as the value for timeout option
If value is a string it will be considered as a label
+
+**Kind**: inner typedef of [CPromise
](#module_CPromise)
### CPromise~OnCancelListener : function
@@ -748,23 +757,13 @@ Converts thing to CPromise using the following rules:
- CPromise instance return
| --- | --- |
| reason | CanceledError
|
-
+
-### CPromise~CPromiseExecutorFn : function
+### CPromise~OnPauseListener : function
**Kind**: inner typedef of [CPromise
](#module_CPromise)
-**this**: CPromiseScope
-
-| Param | Type |
-| --- | --- |
-| resolve | function
|
-| reject | function
|
-| scope | CPromiseScope
|
-
-
-
-### CPromise~CPromiseOptions : PromiseScopeOptions
\| String
\| Number
-If value is a number it will be considered as the value for timeout option
If value is a string it will be considered as a label
+
+### CPromise~OnResumeListener : function
**Kind**: inner typedef of [CPromise
](#module_CPromise)
diff --git a/jsdoc2md/README.hbs.md b/jsdoc2md/README.hbs.md
index d33b432..97bbed7 100644
--- a/jsdoc2md/README.hbs.md
+++ b/jsdoc2md/README.hbs.md
@@ -5,7 +5,14 @@
![David](https://img.shields.io/david/DigitalBrainJS/c-promise)
## SYNOPSIS :sparkles:
-A Promise class built on top of the native that supports some additional features such as cancellation, timeouts, progress capturing and concurrency limit.
+
+This library provides an advanced version of the built-in Promise by subclassing.
+You might be interested in using it if you need the following features:
+- promise cancellation (including nested)
+- progress capturing
+- promise suspending
+- timeouts
+- concurrent limit for `all` and `allSettled` methods with `mapper` reducer
In terms of the library **the cancellation means rejection with a special error subclass**.
@@ -79,6 +86,8 @@ has lost its relevance to you.
- `CPromise.all` supports concurrency limit
- `CPromise.all` and `CPromise.race` methods have cancellation support, so the others nested pending promises will be canceled
when the result promise settled
+ - promise suspending (using `pause` and `resume` methods)
+ - custom signals (`emitSignal`)
- `delay` method to return promise that will be resolved with the value after timeout
- ability to set the `weight` for each promise in the chain to manage the impact on chain progress
- ability to attach meta info on each setting of the progress
@@ -222,7 +231,7 @@ const promise= CPromise.from(function*(){
yield [[CPromise.delay(1000), CPromise.delay(1500)]] // resolve chains using CPromise.race([...chains]);
yield new CPromise(resolve=> resolve(true)); // any thenable object will be resolved
return "It works!";
-}, [1, 2, 3])
+})
.progress(value=> console.log(`Progress: ${value}`))
.then(message=> console.log(`Done: ${message}`));
````
diff --git a/lib/abort-controller.js b/lib/abort-controller.js
index 5b45071..c4a1caf 100644
--- a/lib/abort-controller.js
+++ b/lib/abort-controller.js
@@ -91,7 +91,7 @@ class AbortSignal{
* AbortController class
*/
-class AbortController {
+class AbortControllerPolyfill {
/**
* Constructs new AbortController instance
*/
@@ -129,7 +129,24 @@ class AbortController {
}
}
+const isAbortSignal = (thing) => {
+ return thing &&
+ typeof thing === 'object' &&
+ typeof thing.aborted === 'boolean' &&
+ typeof thing.addEventListener === 'function' &&
+ typeof thing.removeEventListener === 'function';
+}
+
module.exports= {
- AbortController,
- AbortSignal
+ AbortController: (() => {
+ try {
+ if (typeof AbortController === 'function' && (new AbortController()).toString() === '[object AbortController]') {
+ return AbortController;
+ }
+ } catch (e) {
+ }
+ return AbortControllerPolyfill;
+ })(),
+ AbortSignal,
+ isAbortSignal
};
diff --git a/lib/c-promise.js b/lib/c-promise.js
index 2ba1082..6ecbb8f 100644
--- a/lib/c-promise.js
+++ b/lib/c-promise.js
@@ -4,119 +4,45 @@
* @exports CPromise
*/
+/**
+ * @typedef {String|Symbol} EventType
+ */
const {CanceledError} = require('./canceled-error');
-const {AbortController: _AbortController} = require('./abort-controller');
-const {TinyEventEmitter} = require('./tiny-event-emitter');
-const {validateOptions, validators}= require('./validator');
+const {AbortController, isAbortSignal} = require('./abort-controller');
+const {validateOptions, validators} = require('./validator');
+const {isThenable, EmptyObject, setImmediate, isGeneratorFunction, isGenerator, toGenerator, toArray} = require('./utils');
const {now} = Date;
-const {isArray}= Array;
+const {isArray} = Array;
+
+const _toCPromise = Symbol.for('toCPromise');
-const _scope = Symbol('scope');
const _handleCancelRejection = Symbol('handleCancelRejection');
-const _isPending = Symbol('isPending');
-const _isCanceled = Symbol('isCanceled');
-const _resolve = Symbol('resolve');
-const _reject = Symbol('reject');
-const _parent = Symbol('parent');
-const _cancel = Symbol('cancel');
-const _innerChain = Symbol('innerChain');
-const _controller = Symbol('controller');
+
const _shadow = Symbol('shadow');
-const _attachScope = Symbol('attachScope');
-const _isChain = Symbol('isChain');
-const _timer = Symbol('timer');
-const _timeout = Symbol('timeout');
+const _events = Symbol('events');
+const _resolve = Symbol('done');
const _objectToCPromise = Symbol('objectToCPromise');
-const _done= Symbol('done');
-const TYPE_PROGRESS = Symbol('TYPE_PROGRESS');
-
-const promiseAssocStore= new WeakMap();
-
-const _toCPromise= Symbol.for('toCPromise');
-
-const __AbortController =
- (() => {
- try {
- if (typeof AbortController === 'function' && (new AbortController()).toString() === '[object AbortController]') {
- return AbortController;
- }
- } catch (e) {
- }
- return _AbortController;
- })();
-
-const _setImmediate = typeof setImmediate === 'function' ? setImmediate : function setImmediateShim(cb) {
- setTimeout(cb, 0)
-}
-
-const isThenable = obj => !!obj && (typeof obj === 'function' || typeof obj === 'object') && typeof obj.then === 'function';
-
-function isGeneratorFunction(thing) {
- return typeof thing === 'function' && thing.constructor && thing.constructor.name === 'GeneratorFunction';
-}
-
-function isGenerator(thing) {
- return thing && typeof thing === 'object' && typeof thing.next === 'function';
-}
-
-const GENERATOR_TYPE_GENERAL= 1;
-const GENERATOR_TYPE_ASYNC= 2;
-
-function getGeneratorFnType(thing) {
- return typeof thing === 'function' &&
- thing.constructor &&
- (thing.constructor.name === 'GeneratorFunction' && GENERATOR_TYPE_GENERAL ||
- thing.constructor.name === 'AsyncGeneratorFunction' && GENERATOR_TYPE_ASYNC) || 0;
-}
-
-const toGenerator= function(thing, args, context= null){
- if(isGeneratorFunction(thing)){
- return thing.apply(context, args);
- }
- return thing && (isGenerator(thing)? thing : (thing[Symbol.iterator] && thing[Symbol.iterator]())) || null;
-}
-
-const toArray= (thing, mapper)=>{
-
- if (thing) {
- if (Array.isArray(thing)) {
- return mapper ? thing.map(mapper) : thing;
- }
- if ((thing= toGenerator(thing))) {
- const arr = [];
- let item;
- while ((item = thing.next()) && item.done === false) {
- arr.push(mapper ? mapper(item.value) : item.value);
- }
- return arr;
- }
- }
-
- return null;
-}
+const TYPE_PROGRESS = Symbol('TYPE_PROGRESS');
+const SIGNAL_CANCEL = Symbol('SIGNAL_CANCEL');
+const SIGNAL_PAUSE = Symbol('SIGNAL_PAUSE');
+const SIGNAL_RESUME = Symbol('SIGNAL_RESUME');
-const isAbortSignal = (thing) => {
- return thing &&
- typeof thing === 'object' &&
- typeof thing.aborted === 'boolean' &&
- typeof thing.addEventListener === 'function' &&
- typeof thing.removeEventListener === 'function';
-}
+const promiseAssocStore = new WeakMap();
const computeWeightSum = promises => {
let i = promises.length;
let sum = 0;
while (i-- > 0) {
- sum += promises[i][_scope][_shadow].weight;
+ sum += promises[i][_shadow].weight;
}
return sum;
}
function resolveGenerator(generatorFn) {
return new this((resolve, reject, scope) => {
- const generator = generatorFn.apply(scope, scope);
+ const generator = generatorFn.call(scope, scope);
if (!isGenerator(generator)) {
return reject(new TypeError('function must return a generator object'));
@@ -152,16 +78,24 @@ function resolveGenerator(generatorFn) {
try {
next(generator.throw(err));
} catch (e) {
- return reject(e);
+ reject(e);
}
}
- scope.on('cancelhook', (err) => {
- if (promise instanceof this) {
- return promise.cancel(err)
+ scope.on('signal', (type, err) => {
+ switch (type) {
+ case SIGNAL_CANCEL:
+ if (!promise.cancel(err)) {
+ onRejected(err);
+ }
+ return false;
+ case SIGNAL_PAUSE:
+ promise.pause();
+ return false;
+ case SIGNAL_RESUME:
+ promise.resume();
+ return false;
}
-
- return !!onRejected(err);
});
const next = (r) => {
@@ -174,7 +108,7 @@ function resolveGenerator(generatorFn) {
sum += weight;
weight = promise.isChain ? 1 : promise.weight();
- _setImmediate(() => {
+ setImmediate(() => {
isCaptured && promise.progress((value, scope, data) => {
setProgress(value, scope, data);
});
@@ -191,88 +125,121 @@ function resolveGenerator(generatorFn) {
}
/**
- * @typedef PromiseScopeOptions {Object}
- * @property {String} label the label for the promise
- * @property {Number} weight=1 the progress weight of the promise
- * @property {Number} timeout=0 max pending time
- * @property {AbortSignal} signal AbortController signal
+ * @typedef {Function} CPromiseExecutorFn
+ * @this CPromise
+ * @param {Function} resolve
+ * @param {Function} reject
+ * @param {CPromise} scope
*/
/**
- * @typedef {Function} onFulfilled
- * @this CPromiseScope
- * @param value
- * @param {CPromiseScope} scope
+ * @typedef {Object} PromiseOptionsObject
+ * @property {String} label
+ * @property {Number} timeout
+ * @property {Number} weight
*/
/**
- * @typedef {Function} onRejected
- * @this CPromiseScope
- * @param err
- * @param {CPromiseScope} scope
+ * If value is a number it will be considered as the value for timeout option
+ * If value is a string it will be considered as a label
+ * @typedef {PromiseOptionsObject|String|Number} CPromiseOptions
*/
/**
- * Scope for CPromises instances
- * @extends TinyEventEmitter
+ * CPromise class
+ * @namespace
+ * @extends Promise
*/
-class CPromiseScope extends TinyEventEmitter {
+class CPromise extends Promise {
/**
- * Constructs PromiseScope instance
- * @param {Function} resolve
- * @param {Function} reject
- * @param {PromiseScopeOptions} options
+ * Constructs new CPromise instance
+ * @param {CPromiseExecutorFn} executor - promise executor function that will be invoked
+ * in the context of the new CPromiseScope instance
+ * @param {CPromiseOptions} [options]
*/
- constructor(resolve, reject, {label, weight, timeout, signal} = {}) {
- super();
- if (signal !== undefined) {
- if (!isAbortSignal(signal)) {
- throw TypeError('signal should implement AbortSignal interface');
- }
- const signalListener = () => {
- this.cancel();
+ constructor(executor, options) {
+ if (options !== undefined && options !== null) {
+ switch (typeof options) {
+ case 'string':
+ options = {label: options};
+ break;
+ case 'number':
+ options = {timeout: options};
+ break;
+ case 'object':
+ break;
+ default:
+ throw TypeError('options must be an object|string|number');
}
- signal.addEventListener('abort', signalListener);
- this.on('done', () => {
- signal.removeEventListener('abort', signalListener);
- })
}
+ let {label, weight, timeout, signal} = options || {};
+
+ let resolve, reject;
+
+ super((_resolve, _reject) => {
+ resolve = _resolve;
+ reject = _reject;
+ });
+
+ this[_events] = new EmptyObject();
+
const shadow = this[_shadow] = {
- captured: false,
+ resolve,
+ reject,
+ paused: false,
+ timestamp: -1,
+ innerChain: null,
+ parent: null,
+ isCaptured: false,
progress: 0,
computedProgress: -1,
totalWeight: -1,
innerWeight: -1,
- isListening: false,
throttle: 0,
- throttleTimer: 0
+ throttleTimer: 0,
+ isListening: false,
+ isPending: true,
+ isCanceled: false,
+ isChain: true,
+ label: '',
+ weight: 1
};
- this[_resolve] = resolve;
- this[_reject] = reject;
- this[_isPending] = true;
- this[_isCanceled] = false;
- this[_parent] = null;
- this[_isChain] = true;
+ this.onCancel = this.onCancel.bind(this);
+ this.onPause = this.onPause.bind(this);
+ this.onResume = this.onResume.bind(this);
- if (timeout !== undefined) {
- this.timeout(timeout);
+ try {
+ executor.call(this, value => {
+ this.resolve(value)
+ }, err => {
+ this.reject(err)
+ }, this);
+ } catch (err) {
+ this.reject(err);
}
- if (weight !== undefined) {
- this.weight(weight);
- } else {
- shadow.weight = 1;
+ if (signal !== undefined) {
+ if (!isAbortSignal(signal)) {
+ throw TypeError('signal should implement AbortSignal interface');
+ }
+ const signalListener = () => {
+ this.cancel();
+ }
+ signal.addEventListener('abort', signalListener);
+ this.on('done', () => {
+ signal.removeEventListener('abort', signalListener);
+ })
}
- if (label !== undefined) {
- this.label(label);
- } else {
- shadow.label = '';
- }
+ timeout !== undefined && this.timeout(timeout);
+
+ weight !== undefined && this.weight(weight);
+
+ label !== undefined && this.label(label);
this.on('propagate', (type, scope, data) => {
if (type === TYPE_PROGRESS) {
@@ -283,8 +250,8 @@ class CPromiseScope extends TinyEventEmitter {
this.on('newListener', (event) => {
if (event === 'progress') {
- shadow.isListening= true;
- if (!shadow.captured) {
+ shadow.isListening = true;
+ if (!shadow.isCaptured) {
this.captureProgress()
}
}
@@ -293,7 +260,7 @@ class CPromiseScope extends TinyEventEmitter {
this.on('removeListener', (event) => {
if (event === 'progress') {
if (shadow.isListening && !this.hasListeners('progress')) {
- shadow.isListening= false;
+ shadow.isListening = false;
}
}
})
@@ -304,24 +271,39 @@ class CPromiseScope extends TinyEventEmitter {
* @param {CanceledError} reason
*/
+ /**
+ * @typedef {Function} OnPauseListener
+ */
+
+ /**
+ * @typedef {Function} OnResumeListener
+ */
+
/**
* registers the listener for cancel event
+ * @name CPromise#onCancel
* @param {OnCancelListener} listener
- * @returns {CPromiseScope}
+ * @returns {CPromise}
*/
- onCancel(listener) {
- if (!this[_isPending]) {
- throw Error('Unable to subscribe to close event since promise has been already settled');
- }
- this.on('cancel', listener);
- return this;
- }
+ /**
+ * registers the listener for pause event
+ * @name CPromise#onPause
+ * @param {OnPauseListener} listener
+ * @returns {CPromise}
+ */
+
+ /**
+ * registers the listener for resume event
+ * @name CPromise#onResume
+ * @param {OnResumeListener} listener
+ * @returns {CPromise}
+ */
/**
* Set or get the total weight of the inner chains
* @param {Number} [weight]
- * @return {Number|CPromiseScope}
+ * @return {Number|CPromise}
*/
totalWeight(weight) {
@@ -338,7 +320,7 @@ class CPromiseScope extends TinyEventEmitter {
/**
* Set or get the total weight of the inner chains
* @param {Number} [weight]
- * @return {Number|CPromiseScope}
+ * @return {Number|CPromise}
*/
innerWeight(weight) {
@@ -357,16 +339,29 @@ class CPromiseScope extends TinyEventEmitter {
return this[_shadow].innerWeight;
}
+ /**
+ * Subscribe to progress event
+ * @param {Function} listener
+ * @returns {CPromise}
+ */
+
/**
* Set promise progress
* @param {Number} value a number between [0, 1]
* @param {*} [data] any data to send for progress event listeners
+ * @returns {Number|CPromise}
*/
progress(value, data) {
const shadow = this[_shadow];
if (arguments.length) {
+
+ if (typeof value === 'function') {
+ this.on('progress', value);
+ return this;
+ }
+
if (!Number.isFinite(value)) {
throw TypeError('value must be a number [0, 1]');
}
@@ -377,7 +372,7 @@ class CPromiseScope extends TinyEventEmitter {
value = 1;
}
- if(!shadow.captured) return;
+ if (!shadow.isCaptured) return this;
if (value !== 0 && value !== 1) {
value = value.toFixed(10) * 1;
@@ -387,13 +382,13 @@ class CPromiseScope extends TinyEventEmitter {
shadow.progress = value;
if (value !== 1 && shadow.throttle) {
- if(!shadow.throttleTimer) {
+ if (!shadow.throttleTimer) {
shadow.throttleTimer = setTimeout(() => {
shadow.throttleTimer = 0;
this.propagate(TYPE_PROGRESS, data);
}, shadow.throttle);
}
- return;
+ return this;
}
this.propagate(TYPE_PROGRESS, data);
@@ -402,75 +397,45 @@ class CPromiseScope extends TinyEventEmitter {
return this;
}
- if(shadow.computedProgress === -1) {
- shadow.totalWeight===-1 && this.captureProgress();
-
- const scopes = this.scopes();
- let i = scopes.length;
- let sum = 0;
- let progress= 0;
-
- while (i-- > 0) {
- const scope = scopes[i];
- const thatShadow = scope[_shadow];
- const weight = thatShadow.weight;
- if (weight > 0) {
- sum += weight;
- progress += thatShadow.progress * weight;
- }
- }
+ if (shadow.computedProgress === -1) {
+ shadow.totalWeight === -1 && this.captureProgress();
+
+ const scopes = this.scopes();
+ let i = scopes.length;
+ let sum = 0;
+ let progress = 0;
+
+ while (i-- > 0) {
+ const scope = scopes[i];
+ const thatShadow = scope[_shadow];
+ const weight = thatShadow.weight;
+ if (weight > 0) {
+ sum += weight;
+ progress += thatShadow.progress * weight;
+ }
+ }
- let total = shadow.totalWeight;
+ let total = shadow.totalWeight;
- if (total > 0) {
- return (shadow.computedProgress = (progress + (total - sum)) / total);
- }
+ if (total > 0) {
+ return (shadow.computedProgress = (progress + (total - sum)) / total);
+ }
- shadow.computedProgress = progress / sum;
- }
+ shadow.computedProgress = progress / sum;
+ }
- return shadow.computedProgress;
+ return shadow.computedProgress;
}
/**
* emit propagate event that will propagate through each promise scope in the chain (bubbling)
* @param {String|symbol} type - some type to identify the data kind
* @param {*} data - some data
- * @returns {CPromiseScope}
+ * @returns {CPromise}
*/
propagate(type, data = null) {
- this.emit('propagate', type, this, data);
- return this;
- }
-
- [_attachScope](thatScope, innerChain = false) {
- if (innerChain) {
- const shadow = this[_shadow];
- this[_innerChain] = thatScope;
-
- thatScope.on('propagate', (type, scope, data) => {
- if (type === TYPE_PROGRESS) {
- const progress = thatScope.progress();
- if (scope === thatScope) {
- this.progress(progress, data);
- return;
- }
- }
-
- this.emit('propagate', type, scope, data);
- });
-
- shadow.captured && thatScope.captureProgress();
-
- shadow.innerWeight= thatScope[_shadow].totalWeight;
- } else {
- thatScope[_parent] = this;
- this.on('propagate', (type, scope, data) => {
- thatScope.emit('propagate', type, scope, data);
- });
- thatScope[_isChain] = false;
- }
+ return this.emit('propagate', type, this, data);
}
/**
@@ -478,11 +443,10 @@ class CPromiseScope extends TinyEventEmitter {
* @param {Object} [options]
* @param {Number} options.throttle set min interval for firing progress event
* @param {Number} options.innerWeight set weight of the nested promises
- * @returns {CPromiseScope}
+ * @returns {CPromise}
*/
captureProgress(options) {
-
if (options) {
validateOptions(options, {
throttle: validators.numberFinitePositive,
@@ -491,7 +455,7 @@ class CPromiseScope extends TinyEventEmitter {
const {throttle, innerWeight} = options;
- if (throttle!==undefined){
+ if (throttle !== undefined) {
this[_shadow].throttle = throttle;
}
@@ -513,13 +477,13 @@ class CPromiseScope extends TinyEventEmitter {
if (weight > 0) {
sum += weight;
- if(!thatShadow.captured){
- thatShadow.captured = true;
+ if (!thatShadow.isCaptured) {
+ thatShadow.isCaptured = true;
scope.emit('capture', scope);
}
- const inner = scope[_innerChain];
- if(inner && !inner[_shadow].captured){
+ const inner = thatShadow.innerChain;
+ if (inner && !inner[_shadow].isCaptured) {
inner.captureProgress(options);
}
}
@@ -532,13 +496,13 @@ class CPromiseScope extends TinyEventEmitter {
/**
* Returns all parent scopes that are in pending state
- * @returns {CPromiseScope[]}
+ * @returns {CPromise[]}
*/
scopes() {
let scope = this;
const scopes = [scope];
- while ((scope = scope[_parent])) {
+ while ((scope = scope[_shadow].parent)) {
scopes.push(scope);
}
return scopes;
@@ -546,15 +510,18 @@ class CPromiseScope extends TinyEventEmitter {
/**
* timeout before the promise will be canceled
- * @param {Number} ms - timeout in ms
- * @returns {Number|CPromiseScope}
+ * @param {Number} [ms] - timeout in ms
+ * @returns {Number|CPromise}
*/
timeout(ms) {
+ const shadow = this[_shadow];
+
if (arguments.length) {
- if (this[_timer]) {
- clearTimeout(this[_timer]);
- this[_timer] = null;
+ if (shadow.timer) {
+ shadow.timestamp = -1;
+ clearTimeout(shadow.timer);
+ shadow.timer = null;
}
if (typeof ms !== 'number' || ms < 0) {
@@ -562,14 +529,15 @@ class CPromiseScope extends TinyEventEmitter {
}
if (ms > 0) {
+ shadow.timestamp = now();
setTimeout(() => {
this.cancel('timeout');
- }, (this[_timeout] = ms));
+ }, (shadow.timeout = ms));
}
return this;
}
- return this[_timeout];
+ return shadow.timeout;
}
/**
@@ -578,15 +546,15 @@ class CPromiseScope extends TinyEventEmitter {
*/
get signal() {
- if (this[_controller]) return this[_controller].signal;
+ if (this[_shadow].controller) return this[_shadow].controller.signal;
- return (this[_controller] = new __AbortController()).signal;
+ return (this[_shadow].controller = new AbortController()).signal;
}
/**
* Sets the promise weight in progress capturing process
- * @param {Number} weight - any number greater or equal 0
- * @returns {Number|CPromiseScope} returns weight if no arguments were specified
+ * @param {Number} [weight] - any number greater or equal 0
+ * @returns {Number|CPromise} returns weight if no arguments were specified
*/
weight(weight) {
@@ -607,8 +575,8 @@ class CPromiseScope extends TinyEventEmitter {
/**
* Sets the promise label
- * @param {String} label - any string
- * @returns {Number|CPromiseScope} returns weight if no arguments were specified
+ * @param {String} [label] - any string
+ * @returns {Number|CPromise} returns weight if no arguments were specified
*/
label(label) {
@@ -625,7 +593,7 @@ class CPromiseScope extends TinyEventEmitter {
*/
get isPending() {
- return this[_isPending];
+ return this[_shadow].isPending;
}
/**
@@ -634,273 +602,224 @@ class CPromiseScope extends TinyEventEmitter {
*/
get isCanceled() {
- return this[_isCanceled];
+ return this[_shadow].isCanceled;
}
/**
* indicates if the promise progress is captured
- * @return {boolean}
+ * @return {Boolean}
*/
- get isCaptured(){
- return this[_shadow].captured;
+ get isCaptured() {
+ return this[_shadow].isCaptured;
}
/**
- * Resolves the promise with given value
- * @param value
+ * indicates if the promise is paused
+ * @returns {Boolean}
*/
- resolve(value) {
- if (!this[_isPending]) return;
-
- if (isThenable(value)) {
- if (value instanceof CPromise) {
- this[_attachScope](value[_scope], true);
- }
- value.then(
- (value) => this[_done](null, value),
- (err) => this[_done](err, undefined, true)
- )
- } else {
- this[_done](null, value);
- }
+ get isPaused() {
+ return this[_shadow].paused;
}
/**
- * Rejects the promise with given error
- * @param err
+ * get parent promise
+ * @returns {CPromise|null}
*/
- reject(err) {
- this[_done](err, undefined, true);
+ get parent() {
+ return this[_shadow].parent;
}
/**
- * @param err
+ * Resolves the promise with given value
* @param value
- * @param {boolean} [reject]
- * @private
- */
-
- [_done](err, value, reject) {
- if (!this[_isPending]) return;
- this[_isPending] = false;
-
- this[_timer] && clearTimeout(this[_timer]);
-
- if (err || reject) {
- if (err && err instanceof CanceledError) {
- this[_handleCancelRejection](err);
- }
- this.emit('done', err);
- this[_reject](err);
- }else {
- this[_shadow].captured && this.progress(1);
- this.emit('done', undefined, value);
- this[_resolve](value);
- }
-
- this.removeAllListeners();
-
- this[_innerChain] = null;
- this[_parent] = null;
- }
-
- /**
- * Resolves or rejects the promise depending on the arguments
- * @param err - error object, if specified the promise will be rejected with this error, resolves otherwise
- * @param {*} value
+ * @returns {CPromise}
*/
- done(err, value){
- return this[_done](err, value);
- }
-
- [_handleCancelRejection](err) {
- this[_isCanceled] = true;
-
- err.scope || (err.scope = this);
-
- if (this[_controller]) {
- this[_controller].abort();
- this[_controller] = null;
- }
-
- this.emit('cancel', err);
+ resolve(value) {
+ this[_resolve](value, false);
+ return this;
}
/**
- * throws the CanceledError that cause promise chain cancellation
- * @param {String|Error} [reason]
+ * Rejects the promise with given error
+ * @param err
+ * @returns {CPromise}
*/
- cancel(reason) {
- return this[_cancel](CanceledError.from(reason));
+ reject(err) {
+ this[_resolve](err, true);
+ return this;
}
- [_cancel](err) {
- if (!this[_isPending] || this[_isCanceled]) return false;
-
- let parent = this[_parent];
+ [_resolve](value, isRejected) {
+ const shadow = this[_shadow];
+ if (!shadow.isPending) return this;
+
+ const complete = (value, isRejected) => {
+ shadow.timer && clearTimeout(shadow.timer);
+
+ const resolve = () => {
+ if (isRejected) {
+ this.emit('done', value);
+ shadow.reject(value);
+ } else {
+ shadow.isCaptured && this.progress(1);
+ this.emit('done', undefined, value);
+ shadow.resolve(value);
+ }
+ shadow.isPending = false;
+ shadow.innerChain = null;
+ shadow.parent = null;
+ this[_events] = null;
+ }
- if (parent && parent[_cancel](err)) {
- return true;
- }
+ if (isRejected && value && value instanceof CanceledError) {
+ this[_handleCancelRejection](value);
+ resolve();
+ return;
+ }
- const innerChain = this[_innerChain];
+ if (shadow.paused) {
+ return this.on('resume', resolve);
+ }
- if (innerChain && innerChain[_cancel](err)) {
- return true;
+ resolve();
}
- if (this.hasListeners('cancelhook')) {
- return this.emitHook('cancelhook', err, this);
+ if (!isThenable(value)) {
+ complete(value, isRejected);
+ return;
}
- this.reject(err);
+ if (value instanceof CPromise) {
+ shadow.innerChain = value;
- return true;
- }
+ value.on('propagate', (type, scope, data) => {
+ if (type === TYPE_PROGRESS) {
+ const progress = value.progress();
+ if (scope === value) {
+ this.progress(progress, data);
+ return;
+ }
+ }
- /**
- * Executes the promise executor in the PromiseScope context
- * @param {CPromiseExecutorFn} executor
- * @param {Function?} resolve
- * @param {Function?} reject
- * @param {Object?} options
- * @returns {CPromiseScope}
- */
+ this.emit('propagate', type, scope, data);
+ });
- static execute(executor, resolve, reject, options) {
- const scope = new this(resolve, reject, options);
+ shadow.isCaptured && value.captureProgress();
- try {
- executor.call(scope, (value) => {
- scope.resolve(value);
- }, (err) => {
- scope.reject(err);
- }, scope
- );
- } catch (err) {
- scope.reject(err);
+ shadow.innerWeight = value[_shadow].totalWeight;
}
- return scope;
+ super.then.call(
+ value,
+ (value) => {
+ complete(value)
+ },
+ (err) => {
+ complete(err, true)
+ }
+ );
}
-}
-
-/**
- * @typedef {Function} CPromiseExecutorFn
- * @this CPromiseScope
- * @param {Function} resolve
- * @param {Function} reject
- * @param {CPromiseScope} scope
- */
-/**
- * If value is a number it will be considered as the value for timeout option
- * If value is a string it will be considered as a label
- * @typedef {PromiseScopeOptions|String|Number} CPromiseOptions
- */
-
-/**
- * CPromise class
- * @namespace
- * @extends Promise
- */
-
-class CPromise extends Promise {
- /**
- * Constructs new CPromise instance
- * @param {CPromiseExecutorFn} executor - promise executor function that will be invoked
- * in the context of the new CPromiseScope instance
- * @param {CPromiseOptions} [options]
- */
+ [_handleCancelRejection](err) {
+ const shadow = this[_shadow];
+ shadow.isCanceled = true;
- constructor(executor, options) {
- let scope;
+ err.scope || (err.scope = this);
- if (options !== undefined && options !== null) {
- switch (typeof options) {
- case 'string':
- options = {label: options};
- break;
- case 'number':
- options = {timeout: options};
- break;
- case 'object':
- break;
- default:
- throw TypeError('options must be an object|string|number');
- }
+ if (shadow.controller) {
+ shadow.controller.abort();
+ shadow.controller = null;
}
- super((resolve, reject) => {
-
- scope = CPromiseScope.execute(executor, resolve, reject, options);
- });
-
- this[_scope] = scope;
+ this.emit('cancel', err);
}
/**
- * indicates if the promise is pending
+ * Pause promise
* @returns {Boolean}
*/
- get isPending() {
- return this[_scope][_isPending];
+ pause() {
+ return this.emitSignal(SIGNAL_PAUSE);
}
/**
- * indicates if promise has been canceled
+ * Resume promise
* @returns {Boolean}
*/
- get isCanceled() {
- return this[_scope][_isCanceled];
- }
-
- get isChain() {
- return this[_scope][_isChain];
+ resume() {
+ return this.emitSignal(SIGNAL_RESUME);
}
/**
- * returns chains progress synchronously or adds a progress event listener if the argument was specified
- * @param {Function} listener
- * @returns {Number|CPromise}
+ * throws the CanceledError that cause promise chain cancellation
+ * @param {String|Error} [reason]
*/
- progress(listener) {
- if (arguments.length === 0) {
- return this[_scope].progress();
- }
-
- this.on('progress', listener);
- return this;
+ cancel(reason) {
+ return this.emitSignal(SIGNAL_CANCEL, CanceledError.from(reason));
}
/**
- * capture initial progress state of the chain
- * @param {Object} options
- * @param {Number} options.throttle
- * @returns {CPromise}
+ * Emit a signal of the specific type
+ * @param {String|Symbol} type
+ * @param {*} data
+ * @returns {Boolean}
*/
- captureProgress(options) {
- this[_scope].captureProgress(options);
- return this;
- }
+ emitSignal(type, data) {
+ const shadow = this[_shadow];
+ if (!shadow.isPending) return false;
- /**
- * cancel the promise chain with specified reason
- * @param {String} reason
- * @returns {Boolean} true if success
- */
+ let {parent, innerChain} = shadow;
- cancel(reason) {
- return this[_scope].cancel(reason);
+ if (parent && parent.emitSignal(type, data)) {
+ return true;
+ }
+
+ if (innerChain && innerChain.emitSignal(type, data)) {
+ return true;
+ }
+
+ const flag = this.emitHook('signal', type, data);
+
+ if (flag !== false) {
+ switch (type) {
+ case SIGNAL_CANCEL:
+ this.reject(data);
+ return true;
+ case SIGNAL_PAUSE:
+ if (!shadow.paused) {
+ shadow.paused = true;
+ if (shadow.timer) {
+ clearTimeout(shadow.timer);
+ shadow.timer = null;
+ shadow.timestamp !== -1 && (shadow.timeLeft = now() - shadow.timestamp);
+ }
+
+ this.emit('pause');
+ }
+ return true;
+ case SIGNAL_RESUME:
+ if (shadow.paused) {
+ shadow.paused = false;
+ if (shadow.timeLeft) {
+ this.timeout(shadow.timeLeft);
+ shadow.timeLeft = 0;
+ }
+ this.emit('resume');
+ }
+ return true;
+ }
+ }
+
+ return true;
}
/**
@@ -922,11 +841,15 @@ class CPromise extends Promise {
then(onFulfilled, onRejected) {
const promise = super.then(
- onFulfilled && ((value) => onFulfilled.call(promise[_scope], value, promise[_scope])),
- onRejected && ((err) => onRejected.call(promise[_scope], err, promise[_scope]))
+ onFulfilled && ((value) => onFulfilled.call(promise, value, promise)),
+ onRejected && ((err) => onRejected.call(promise, err, promise))
);
- this[_scope][_attachScope](promise[_scope]);
+ promise[_shadow].parent = this;
+
+ this.on('propagate', (type, scope, data) => {
+ promise.emit('propagate', type, scope, data);
+ });
return promise;
}
@@ -1005,7 +928,7 @@ class CPromise extends Promise {
return new this((resolve, reject, scope) => {
let pending;
let results;
- let progressAcc= 0;
+ let progressAcc = 0;
let isCaptured;
let endReached;
let generator;
@@ -1024,10 +947,10 @@ class CPromise extends Promise {
ignoreResults,
signatures,
mapper
- }= options || {}
+ } = options || {}
- const cancel= (reason)=>{
- const {length}= pending;
+ const cancel = (reason) => {
+ const {length} = pending;
for (let i = 0; i < length; i++) {
pending[i].cancel(reason);
}
@@ -1035,7 +958,21 @@ class CPromise extends Promise {
scope.onCancel(cancel);
- const handleProgress= (value, _scope, data) => {
+ scope.onPause(() => {
+ const {length} = pending;
+ for (let i = 0; i < length; i++) {
+ pending[i].pause();
+ }
+ });
+
+ scope.onResume(() => {
+ const {length} = pending;
+ for (let i = 0; i < length; i++) {
+ pending[i].resume();
+ }
+ })
+
+ const handleProgress = (value, _scope, data) => {
let total = scope.innerWeight();
let sum = progressAcc;
const {length} = pending;
@@ -1046,12 +983,12 @@ class CPromise extends Promise {
sum <= total && scope.progress(sum / total, _scope, data);
};
- const _reject= err=> {
+ const _reject = err => {
reject(err);
cancel();
}
- function throwConvertError(){
+ function throwConvertError() {
throw TypeError('unable to convert object to iterable');
}
@@ -1065,8 +1002,8 @@ class CPromise extends Promise {
});
if (!concurrency) {
- pending = toArray(iterable, (value, i)=> {
- return this.from(mapper? mapper(value, i) : value, signatures);
+ pending = toArray(iterable, (value, i) => {
+ return this.from(mapper ? mapper(value, i) : value, signatures);
}) || throwConvertError();
return super.all(pending).then(resolve, _reject);
@@ -1074,10 +1011,10 @@ class CPromise extends Promise {
generator = toGenerator(iterable) || throwConvertError();
- pending= [];
- !ignoreResults && (results= []);
+ pending = [];
+ !ignoreResults && (results = []);
- const next= (value)=> {
+ const next = (value) => {
const promise = this.from(value, signatures);
pending.push(promise);
@@ -1107,16 +1044,16 @@ class CPromise extends Promise {
let item;
try {
item = generator.next();
- }catch(err){
+ } catch (err) {
_reject(err);
return;
}
- if (item.done){
- endReached= true;
+ if (item.done) {
+ endReached = true;
return;
}
- next(mapper? mapper(item.value) : item.value);
+ next(mapper ? mapper(item.value) : item.value);
}
}
@@ -1163,6 +1100,18 @@ class CPromise extends Promise {
scope.onCancel(cancel);
+ scope.onPause(() => {
+ for (let i = 0; i < length; i++) {
+ thenables[i].pause();
+ }
+ })
+
+ scope.onResume(() => {
+ for (let i = 0; i < length; i++) {
+ thenables[i].resume();
+ }
+ })
+
super.race(thenables).then((value) => {
resolve(value);
cancel();
@@ -1173,6 +1122,33 @@ class CPromise extends Promise {
});
}
+ /**
+ * returns a promise that resolves after all of the given promises have either fulfilled or rejected
+ * @param {Iterable|Generator|GeneratorFunction} iterable
+ * @param {AllOptions} options
+ * @returns {CPromise}
+ */
+
+ static allSettled(iterable, options) {
+ const {mapper, ...allOptions} = options || {};
+
+ if (mapper !== undefined) {
+ validateOptions(options, {
+ mapper
+ })
+ }
+
+ return this.all(iterable, {
+ ...allOptions,
+ mapper: (value, i) => {
+ return this.resolve(mapper ? mapper(value, i) : value).then(
+ value => ({status: "fulfilled", value}),
+ err => ({status: "rejected", reason: err})
+ )
+ }
+ })
+ }
+
static [_objectToCPromise](thing) {
const convertMethod = thing[_toCPromise];
@@ -1225,12 +1201,12 @@ class CPromise extends Promise {
* @returns {CPromise}
*/
- static from(thing, resolveSignatures= true) {
+ static from(thing, resolveSignatures = true) {
if (thing && thing instanceof this) {
return thing;
}
- if(resolveSignatures) {
+ if (resolveSignatures) {
const type = typeof thing;
if (type === 'object') {
@@ -1256,153 +1232,196 @@ class CPromise extends Promise {
}
/**
- * inner weight accessor
- * @name CPromise#innerWeight
- * @function
- * @param {number} weight - the weight to set
+ * adds a new listener
+ * @alias CPromise#addEventListener
+ * @param {EventType} type
+ * @param {Function} listener
* @returns {CPromise}
*/
- /**
- * weight accessor
- * @name CPromise#weight
- * @function
- * @param {number} [weight]
- * @returns {number|CPromise}
- */
+ on(type, listener) {
+ const events = this[_events];
+ if (!events) return this;
+ const listeners = events[type];
- /**
- * label accessor
- * @name CPromise#label
- * @function
- * @param {string} [label]
- * @returns {string|CPromise}
- */
+ events['newListener'] && this.emit('newListener', type, listener);
- /**
- * timeout accessor
- * @name CPromise#timeout
- * @function
- * @param {number} [timeout]
- * @returns {number|CPromise}
- */
+ if (!listeners) {
+ events[type] = listener;
+ return this;
+ }
+
+ if (typeof listeners === 'function') {
+ events[type] = [listeners, listener];
+ return this;
+ }
+
+ listeners.push(listener);
+ return this;
+ }
/**
- * add a new event listener
- * @name CPromise#on
- * @function
- * @param {string|symbol} listener
- * @param {function} listener
+ * removes the listener
+ * @alias CPromise#removeEventListener
+ * @param {EventType} type
+ * @param {Function} listener
* @returns {CPromise}
*/
+ off(type, listener) {
+ if (typeof listener !== 'function') {
+ throw TypeError('listener must be a function');
+ }
+
+ const events = this[_events]
+ if (!events) return this;
+ const listeners = events[type];
+ if (!listeners) {
+ return this;
+ }
+
+ if (typeof listeners === 'function' && listeners === listener) {
+ events[type] = null;
+ events['removeListener'] && this.emit('removeListener', type, listener);
+ return this;
+ }
+
+ const len = listeners.length;
+
+ for (let i = 0; i < len; i++) {
+ if (listeners[i] === listener) {
+ len === 1 ? events[type] = null : listeners.splice(i, 1);
+ events['removeListener'] && this.emit('removeListener', type, listener);
+ return this;
+ }
+ }
+
+ return this;
+ }
+
/**
- * remove the event listener
- * @name CPromise#off
- * @function
- * @param {string|symbol} listener
- * @param {function} listener
- * @returns {CPromise}
+ * returns listeners count of the specific event type
+ * @param {EventType} type
+ * @returns {Number}
*/
+ listenersCount(type) {
+ const events = this[_events];
+ if (!events) return 0;
+ const listeners = events[type];
+ if (!listeners) return 0;
+ return typeof listeners === 'function' ? 1 : listeners.length;
+ }
+
/**
- * add a new event listener that will be fired only once
- * @name CPromise#once
- * @function
- * @param {string|symbol} listener
- * @param {function} listener
- * @returns {CPromise}
+ * checks if there are listeners of a specific type
+ * @param {String|Symbol} type
+ * @returns {Boolean}
*/
+ hasListeners(type) {
+ const events = this[_events];
+ return !!(events && events[type]);
+ }
+
/**
- * @name CPromise.CanceledError
- * @constructor
- * @param {string} reason
+ * add 'once' listener
+ * @param {EventType} type
+ * @param {Function} listener
+ * @returns {CPromise}
*/
+ once(type, listener) {
+ const emitter = this;
+
+ function _listener() {
+ emitter.off(type, _listener);
+ listener.apply(emitter, arguments);
+ }
+
+ return this.on(type, _listener);
+ }
+
/**
- * AbortController class
- * @name CPromise.AbortController
- * @class
+ * emits the event
+ * @param {EventType} type
+ * @param args
+ * @returns {CPromise}
*/
-}
-const {prototype} = CPromise;
+ emit(type, ...args) {
+ const events = this[_events];
+ if (!events) return this;
+ const listeners = events[type];
+ if (!listeners) return this;
-['on', 'off', 'once'].forEach(methodName => {
- const scopeMethod = CPromiseScope.prototype[methodName];
+ if (typeof listeners === 'function') {
+ listeners.apply(this, args);
+ return this;
+ }
- prototype[methodName] = function () {
- try {
- scopeMethod.apply(this[_scope], arguments);
- }catch(err){
- this[_scope].reject(err);
+ for (let i = 0; i < listeners.length; i++) {
+ listeners[i].apply(this, args)
}
+
return this;
}
-});
-['captureProgress'].forEach(method=>{
- const fn= prototype[method];
- prototype[method]= function(){
- try{
- fn.apply(this, arguments);
- }catch(err){
- this[_scope].reject(err);
- }
- return this;
- }
-});
+ /**
+ * emits the hook event
+ * @param {EventType} type
+ * @param args
+ * @returns {Boolean} - false if some listener returned false
+ */
-['weight', 'label', 'timeout', 'innerWeight'].forEach(methodName => {
- const scopeMethod = CPromiseScope.prototype[methodName];
- prototype[methodName] = function () {
- if (arguments.length) {
- try {
- scopeMethod.apply(this[_scope], arguments);
- }catch(err){
- this[_scope].reject(err);
+ emitHook(type, ...args) {
+ const events = this[_events];
+ if (!events) return false;
+ const listeners = events[type];
+ if (!listeners) return true;
+
+ let returnValue;
+
+ if (typeof listeners === 'function') {
+ returnValue = listeners.apply(this, args);
+ return returnValue === undefined ? undefined : !!returnValue;
+ }
+
+ for (let i = 0; i < listeners.length; i++) {
+ returnValue = listeners[i].apply(this, args);
+ if (returnValue === true) {
+ return true;
}
- return this;
}
- return scopeMethod.call(this[_scope]);
+
+ return returnValue;
}
-})
-function bindMethod(prototype, methodName) {
- const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);
- if (!descriptor) {
- throw Error(`Property ${methodName} doesn't exists`);
+ static overload() {
+ const _global = typeof window === 'undefined' ? global : window;
+ _global.Promise = this;
}
- const method = descriptor.value;
- const boundSymbol = Symbol(`${methodName}Bound`);
-
- Object.defineProperty(prototype, methodName, {
- get() {
- const context = this;
- return this[boundSymbol] || (this[boundSymbol] = function () {
- return method.apply(context, arguments);
- })
- }
- });
}
-bindMethod(CPromiseScope.prototype, 'onCancel');
+const {prototype} = CPromise;
+
+prototype.addEventListener = prototype.on;
+prototype.removeEventListener = prototype.off;
+
+['Cancel', 'Pause', 'Resume'].forEach(type => {
+ const typeL = type.toLowerCase();
+ prototype['on' + type] = function (listener) {
+ if (!this[_shadow].isPending) {
+ throw Error(`Unable to subscribe to ${typeL} event since promise has been already settled`);
+ }
+ return this.on(typeL, listener);
+ }
+});
Object.defineProperties(CPromise, {
CanceledError: {value: CanceledError, configurable: true},
- AbortController: {value: _AbortController, configurable: true},
- CPromiseScope: {value: CPromiseScope, configurable: true}
+ AbortController: {value: AbortController, configurable: true}
});
-/**
- * Exports CPromise class as a default
- * @exports CPromise
- */
module.exports = CPromise;
-
-
-
-
-
diff --git a/lib/c-promise2.js b/lib/c-promise2.js
new file mode 100644
index 0000000..bf2a6b2
--- /dev/null
+++ b/lib/c-promise2.js
@@ -0,0 +1,1235 @@
+/**
+ * Cancellable Promise with extra features
+ * @module CPromise
+ * @exports CPromise
+ */
+
+/**
+ * @typedef {String|Symbol} EventType
+ */
+
+const {CanceledError} = require('./canceled-error');
+const {AbortController, isAbortSignal} = require('./abort-controller');
+const {validateOptions, validators}= require('./validator');
+const {isThenable, EmptyObject, setImmediate, isGeneratorFunction, isGenerator, toGenerator, toArray}= require('./utils');
+
+const {now} = Date;
+const {isArray}= Array;
+
+const _toCPromise= Symbol.for('toCPromise');
+
+const TYPE_PROGRESS = Symbol('TYPE_PROGRESS');
+const _handleCancelRejection = Symbol('handleCancelRejection');
+
+const _shadow = Symbol('shadow');
+const _events = Symbol('events');
+
+const computeWeightSum = promises => {
+ let i = promises.length;
+ let sum = 0;
+ while (i-- > 0) {
+ sum += promises[i][_shadow].weight;
+ }
+ return sum;
+}
+
+function resolveGenerator(generatorFn) {
+ return new this((resolve, reject, scope) => {
+ const generator = generatorFn.apply(scope, scope);
+
+ if (!isGenerator(generator)) {
+ return reject(new TypeError('function must return a generator object'));
+ }
+
+ let isCaptured;
+ let progress = 0;
+ let sum = 0;
+ let weight = 0;
+ let promise;
+
+ scope.on('capture', () => {
+ isCaptured = true;
+ });
+
+ const setProgress = (value, _scope, data) => {
+ progress = (value * weight + sum) / scope.innerWeight();
+ if (progress > 1) {
+ progress = 1;
+ }
+ scope.progress(progress, _scope, data);
+ }
+
+ const onFulfilled = (result) => {
+ try {
+ next(generator.next(result));
+ } catch (e) {
+ return reject(e);
+ }
+ }
+
+ const onRejected = (err) => {
+ try {
+ next(generator.throw(err));
+ } catch (e) {
+ return reject(e);
+ }
+ }
+
+ scope.on('cancelhook', (err) => {
+ if (promise instanceof this) {
+ return promise.cancel(err)
+ }
+
+ return !!onRejected(err);
+ });
+
+ const next = (r) => {
+ if (r.done) {
+ return resolve(r.value);
+ }
+
+ promise = this.from(r.value);
+
+ sum += weight;
+ weight = promise.isChain ? 1 : promise.weight();
+
+ _setImmediate(() => {
+ isCaptured && promise.progress((value, scope, data) => {
+ setProgress(value, scope, data);
+ });
+ });
+
+ return promise.then((value) => {
+ setProgress(1, promise);
+ onFulfilled(value)
+ }, onRejected);
+ }
+
+ onFulfilled();
+ })
+}
+
+/**
+ * @typedef {Function} CPromiseExecutorFn
+ * @this CPromise
+ * @param {Function} resolve
+ * @param {Function} reject
+ * @param {CPromise} scope
+ */
+
+/**
+ * @typedef {Object} PromiseOptionsObject
+ * @property {String} label
+ * @property {Number} timeout
+ * @property {Number} weight
+ */
+
+/**
+ * If value is a number it will be considered as the value for timeout option
+ * If value is a string it will be considered as a label
+ * @typedef {PromiseOptionsObject|String|Number} CPromiseOptions
+ */
+
+/**
+ * CPromise class
+ * @namespace
+ * @extends Promise
+ */
+
+class CPromise extends Promise {
+ /**
+ * Constructs new CPromise instance
+ * @param {CPromiseExecutorFn} executor - promise executor function that will be invoked
+ * in the context of the new CPromiseScope instance
+ * @param {CPromiseOptions} [options]
+ */
+
+ constructor(executor, options ) {
+ if (options !== undefined && options !== null) {
+ switch (typeof options) {
+ case 'string':
+ options = {label: options};
+ break;
+ case 'number':
+ options = {timeout: options};
+ break;
+ case 'object':
+ break;
+ default:
+ throw TypeError('options must be an object|string|number');
+ }
+ }
+
+ let {label, weight, timeout, signal}= options || {};
+
+ let resolve, reject;
+
+ super((_resolve, _reject) => {
+ resolve= _resolve;
+ reject= _reject;
+ });
+
+ const shadow = this[_shadow] = {
+ resolve,
+ reject,
+ innerChain: null,
+ parent: null,
+ captured: false,
+ progress: 0,
+ computedProgress: -1,
+ totalWeight: -1,
+ innerWeight: -1,
+ isListening: false,
+ throttle: 0,
+ throttleTimer: 0,
+ isPending: true,
+ isCanceled: false,
+ isChain: true,
+ label: '',
+ weight: 1
+ };
+
+ try {
+ executor.call(this, this.resolve, this.reject, this);
+ }catch(err){
+ this.reject(err);
+ }
+
+ if (signal !== undefined) {
+ if (!isAbortSignal(signal)) {
+ throw TypeError('signal should implement AbortSignal interface');
+ }
+ const signalListener = () => {
+ this.cancel();
+ }
+ signal.addEventListener('abort', signalListener);
+ this.on('done', () => {
+ signal.removeEventListener('abort', signalListener);
+ })
+ }
+
+ timeout !== undefined && this.timeout(timeout);
+
+ weight !== undefined && this.weight(weight);
+
+ label !== undefined && this.label(label);
+
+ this.on('propagate', (type, scope, data) => {
+ if (type === TYPE_PROGRESS) {
+ shadow.computedProgress = -1;
+ shadow.isListening && this.emit('progress', this.progress(), scope, data);
+ }
+ });
+
+ this.on('newListener', (event) => {
+ if (event === 'progress') {
+ shadow.isListening= true;
+ if (!shadow.captured) {
+ this.captureProgress()
+ }
+ }
+ })
+
+ this.on('removeListener', (event) => {
+ if (event === 'progress') {
+ if (shadow.isListening && !this.hasListeners('progress')) {
+ shadow.isListening= false;
+ }
+ }
+ })
+ }
+
+ /**
+ * @typedef {Function} OnCancelListener
+ * @param {CanceledError} reason
+ */
+
+ /**
+ * registers the listener for cancel event
+ * @param {OnCancelListener} listener
+ * @returns {CPromise}
+ */
+
+ onCancel(listener) {
+ if (!this[_shadow].isPending) {
+ throw Error('Unable to subscribe to close event since promise has been already settled');
+ }
+ this.on('cancel', listener);
+ return this;
+ }
+
+ /**
+ * Set or get the total weight of the inner chains
+ * @param {Number} [weight]
+ * @return {Number|CPromise}
+ */
+
+ totalWeight(weight) {
+ if (arguments.length) {
+ if (weight <= 0 || !Number.isFinite(weight)) {
+ throw Error('weight must be a number greater than 0')
+ }
+ this[_shadow].totalWeight = weight;
+ return this;
+ }
+ return this[_shadow].totalWeight;
+ }
+
+ /**
+ * Set or get the total weight of the inner chains
+ * @param {Number} [weight]
+ * @return {Number|CPromise}
+ */
+
+ innerWeight(weight) {
+ if (arguments.length) {
+ if (!Number.isFinite(weight)) {
+ throw Error('inner weight must be a number')
+ }
+
+ if (weight <= 0) {
+ throw Error('inner weight must be greater than 0')
+ }
+
+ this[_shadow].innerWeight = weight;
+ return this;
+ }
+ return this[_shadow].innerWeight;
+ }
+
+ /**
+ * Subscribe to progress event
+ * @param {Function} listener
+ * @returns {CPromise}
+ *//**
+ * Set promise progress
+ * @param {Number} value a number between [0, 1]
+ * @param {*} [data] any data to send for progress event listeners
+ * @returns {Number|CPromise}
+ */
+
+ progress(value, data) {
+ const shadow = this[_shadow];
+
+ if (arguments.length) {
+
+ if (typeof value === 'function') {
+ this.on('progress', value);
+ return this;
+ }
+
+ if (!Number.isFinite(value)) {
+ throw TypeError('value must be a number [0, 1]');
+ }
+
+ if (value < 0) {
+ value = 0;
+ } else if (value > 1) {
+ value = 1;
+ }
+
+ if(!shadow.captured) return this;
+
+ if (value !== 0 && value !== 1) {
+ value = value.toFixed(10) * 1;
+ }
+
+ if (shadow.progress !== value) {
+ shadow.progress = value;
+
+ if (value !== 1 && shadow.throttle) {
+ if(!shadow.throttleTimer) {
+ shadow.throttleTimer = setTimeout(() => {
+ shadow.throttleTimer = 0;
+ this.propagate(TYPE_PROGRESS, data);
+ }, shadow.throttle);
+ }
+ return this;
+ }
+
+ this.propagate(TYPE_PROGRESS, data);
+ }
+
+ return this;
+ }
+
+ if(shadow.computedProgress === -1) {
+ shadow.totalWeight===-1 && this.captureProgress();
+
+ const scopes = this.scopes();
+ let i = scopes.length;
+ let sum = 0;
+ let progress= 0;
+
+ while (i-- > 0) {
+ const scope = scopes[i];
+ const thatShadow = scope[_shadow];
+ const weight = thatShadow.weight;
+ if (weight > 0) {
+ sum += weight;
+ progress += thatShadow.progress * weight;
+ }
+ }
+
+ let total = shadow.totalWeight;
+
+ if (total > 0) {
+ return (shadow.computedProgress = (progress + (total - sum)) / total);
+ }
+
+ shadow.computedProgress = progress / sum;
+ }
+
+ return shadow.computedProgress;
+ }
+
+ /**
+ * emit propagate event that will propagate through each promise scope in the chain (bubbling)
+ * @param {String|symbol} type - some type to identify the data kind
+ * @param {*} data - some data
+ * @returns {CPromise}
+ */
+
+ propagate(type, data = null) {
+ return this.emit('propagate', type, this, data);
+ }
+
+ /**
+ * capture initial progress state of the chain
+ * @param {Object} [options]
+ * @param {Number} options.throttle set min interval for firing progress event
+ * @param {Number} options.innerWeight set weight of the nested promises
+ * @returns {CPromise}
+ */
+
+ captureProgress(options) {
+ if (options) {
+ validateOptions(options, {
+ throttle: validators.numberFinitePositive,
+ innerWeight: validators.numberFinitePositive
+ })
+
+ const {throttle, innerWeight} = options;
+
+ if (throttle !== undefined) {
+ this[_shadow].throttle = throttle;
+ }
+
+ if (innerWeight !== undefined) {
+ this.innerWeight(innerWeight);
+ }
+ }
+
+ const shadow = this[_shadow];
+ const scopes = this.scopes();
+ let i = scopes.length;
+ let sum = 0;
+
+ while (i-- > 0) {
+ const scope = scopes[i];
+ const thatShadow = scope[_shadow];
+ const weight = thatShadow.weight;
+
+ if (weight > 0) {
+ sum += weight;
+
+ if (!thatShadow.captured) {
+ thatShadow.captured = true;
+ scope.emit('capture', scope);
+ }
+
+ const inner = thatShadow.innerChain;
+ if (inner && !inner[_shadow].captured) {
+ inner.captureProgress(options);
+ }
+ }
+ }
+
+ shadow.totalWeight = sum;
+
+ return this;
+ }
+
+ /**
+ * Returns all parent scopes that are in pending state
+ * @returns {CPromise[]}
+ */
+
+ scopes() {
+ let scope = this;
+ const scopes = [scope];
+ while ((scope = scope[_shadow].parent)) {
+ scopes.push(scope);
+ }
+ return scopes;
+ }
+
+ /**
+ * timeout before the promise will be canceled
+ * @param {Number} ms - timeout in ms
+ * @returns {Number|CPromise}
+ */
+
+ timeout(ms) {
+ if (arguments.length) {
+ if (this[_shadow].timer) {
+ clearTimeout(this[_shadow].timer);
+ this[_shadow].timer = null;
+ }
+
+ if (typeof ms !== 'number' || ms < 0) {
+ throw TypeError('timeout must be a positive number');
+ }
+
+ if (ms > 0) {
+ setTimeout(() => {
+ this.cancel('timeout');
+ }, (this[_shadow].timeout = ms));
+ }
+ return this;
+ }
+
+ return this[_shadow].timeout;
+ }
+
+ /**
+ * get promise abort signal object
+ * @type {AbortSignal}
+ */
+
+ get signal() {
+ if (this[_shadow].controller) return this[_shadow].controller.signal;
+
+ return (this[_shadow].controller = new AbortController()).signal;
+ }
+
+ /**
+ * Sets the promise weight in progress capturing process
+ * @param {Number} weight - any number greater or equal 0
+ * @returns {Number|CPromise} returns weight if no arguments were specified
+ */
+
+ weight(weight) {
+ if (arguments.length) {
+ if (typeof weight !== 'number') {
+ throw TypeError('weight must be a number');
+ }
+
+ if (weight < 0) {
+ throw Error('weight must must be a positive number');
+ }
+
+ this[_shadow].weight = weight;
+ return this;
+ }
+ return this[_shadow].weight;
+ }
+
+ /**
+ * Sets the promise label
+ * @param {String} label - any string
+ * @returns {Number|CPromise} returns weight if no arguments were specified
+ */
+
+ label(label) {
+ if (arguments.length) {
+ this[_shadow].label = label;
+ return this;
+ }
+ return this[_shadow].label;
+ }
+
+ /**
+ * indicates if the promise is pending
+ * @returns {Boolean}
+ */
+
+ get isPending() {
+ return this[_shadow].isPending;
+ }
+
+ /**
+ * indicates if the promise is pending
+ * @returns {Boolean}
+ */
+
+ get isCanceled() {
+ return this[_shadow].isCanceled;
+ }
+
+ /**
+ * indicates if the promise progress is captured
+ * @return {boolean}
+ */
+
+ get isCaptured(){
+ return this[_shadow].captured;
+ }
+
+ /**
+ * Resolves the promise with given value
+ * @param value
+ * @returns {CPromise}
+ */
+
+ resolve(value) {
+ if (!this[_shadow].isPending) return this;
+
+ if (isThenable(value)) {
+ if (value instanceof CPromise) {
+ const promise= value;
+ const shadow = this[_shadow];
+
+ shadow.innerChain = promise;
+
+ promise.on('propagate', (type, scope, data) => {
+ if (type === TYPE_PROGRESS) {
+ const progress = promise.progress();
+ if (scope === promise) {
+ this.progress(progress, data);
+ return;
+ }
+ }
+
+ this.emit('propagate', type, scope, data);
+ });
+
+ shadow.captured && promise.captureProgress();
+
+ shadow.innerWeight= promise[_shadow].totalWeight;
+ }
+ value.then(
+ (value) => this[_done](null, value),
+ (err) => this[_done](err)
+ )
+ } else {
+ this[_done](null, value);
+ }
+ return this;
+ }
+
+ /**
+ * Rejects the promise with given error
+ * @param err
+ * @returns {CPromise}
+ */
+
+ reject(err) {
+ this[_done](err, undefined, true);
+ return this;
+ }
+
+ /**
+ * Resolves or rejects the promise depending on the arguments
+ * @param err - error object, if specified the promise will be rejected with this error, resolves otherwise
+ * @param {*} value
+ * @returns {CPromise}
+ */
+
+ done(err, value){
+ const shadow= this[_shadow];
+ if (!shadow.isPending) return;
+ shadow.isPending = false;
+
+ shadow.timer && clearTimeout(shadow.timer);
+
+ if (arguments.length < 2) {
+ if (err && err instanceof CanceledError) {
+ this[_handleCancelRejection](err);
+ }
+ this.emit('done', err);
+ shadow.reject(err);
+ }else {
+ shadow.captured && this.progress(1);
+ this.emit('done', undefined, value);
+ shadow.resolve(value);
+ }
+
+ this.removeAllListeners();
+
+ shadow.innerChain = null;
+ shadow.parent = null;
+ return this;
+ }
+
+ [_handleCancelRejection](err) {
+ const shadow= this[_shadow];
+ shadow.isCanceled = true;
+
+ err.scope || (err.scope = this);
+
+ if (shadow.controller) {
+ shadow.controller.abort();
+ shadow.controller = null;
+ }
+
+ this.emit('cancel', err);
+ }
+
+ /**
+ * throws the CanceledError that cause promise chain cancellation
+ * @param {String|Error} [reason]
+ */
+
+ cancel(reason) {
+ return this[_cancel](CanceledError.from(reason));
+ }
+
+ [_cancel](err) {
+ if (!this[_isPending] || this[_isCanceled]) return false;
+
+ let parent = this[_parent];
+
+ if (parent && parent[_cancel](err)) {
+ return true;
+ }
+
+ const innerChain = this[_innerChain];
+
+ if (innerChain && innerChain[_cancel](err)) {
+ return true;
+ }
+
+ if (this.hasListeners('cancelhook')) {
+ return this.emitHook('cancelhook', err, this);
+ }
+
+ this.reject(err);
+
+ return true;
+ }
+
+ /**
+ * Returns a chain that will be resolved after specified timeout
+ * @param {Number} ms
+ * @returns {CPromise}
+ */
+
+ delay(ms) {
+ return this.then((value) => this.constructor.delay(ms, value));
+ }
+
+ /**
+ * returns a CPromise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.
+ * @param {onFulfilled} onFulfilled
+ * @param {onRejected} [onRejected]
+ * @returns {CPromise}
+ */
+
+ then(onFulfilled, onRejected) {
+ const promise = super.then(
+ onFulfilled && ((value) => onFulfilled.call(promise, value, promise)),
+ onRejected && ((err) => onRejected.call(promise, err, promise))
+ );
+
+ promise[_shadow].parent = this;
+
+ this.on('propagate', (type, scope, data) => {
+ promise.emit('propagate', type, scope, data);
+ });
+
+ return promise;
+ }
+
+ /**
+ * Catches rejection with optionally specified Error class
+ * @param {Function} onRejected
+ * @param {Error} [filter]
+ * @returns {CPromise}
+ */
+
+ catch(onRejected, filter) {
+ if (filter) {
+ return super.catch((err) => {
+ if (err instanceof filter) {
+ onRejected(err);
+ return;
+ }
+ throw err;
+ });
+ }
+
+ return super.catch(onRejected);
+ }
+
+ /**
+ * Checks if thing is an CanceledError instance
+ * @param thing
+ * @returns {boolean}
+ */
+
+ static isCanceledError(thing) {
+ return thing instanceof CanceledError;
+ }
+
+ /**
+ * Returns a CPromise that will be resolved after specified timeout
+ * @param {Number} ms - delay before resolve the promise with specified value
+ * @param value
+ * @returns {CPromise}
+ */
+
+ static delay(ms, value) {
+ return new this((resolve, reject, scope) => {
+ if (!Number.isFinite(ms)) {
+ throw TypeError('timeout must be a finite number');
+ }
+ const timer = setTimeout(() => resolve(value), ms);
+ scope.onCancel(() => clearTimeout(timer));
+ })
+ }
+
+ /**
+ * @typedef {object} AllOptions
+ * @property {number} concurrency limit concurrency of promise being run simultaneously
+ * @property {function} mapper function to map each element
+ * @property {boolean} ignoreResults do not collect results
+ * @property {boolean} signatures use advanced signatures for vales resolving
+ */
+
+ /**
+ * Returns a single CPromise that resolves to an array of the results of the input promises.
+ * If one fails then other promises will be canceled immediately
+ * @param {Iterable|Generator|GeneratorFunction} iterable
+ * @param {AllOptions} options
+ * @returns {CPromise}
+ * @example
+ * CPromise.all(function*(){
+ * yield axios.get(url1);
+ * yield axios.get(url2);
+ * yield axios.get(url3);
+ * }, {concurrency: 1}).then(console.log)
+ */
+
+ static all(iterable, options) {
+ return new this((resolve, reject, scope) => {
+ let pending;
+ let results;
+ let progressAcc= 0;
+ let isCaptured;
+ let endReached;
+ let generator;
+
+ if (options !== undefined) {
+ validateOptions(options, {
+ concurrency: validators.numberFinitePositive,
+ ignoreResults: validators.boolean,
+ signatures: validators.boolean,
+ mapper: validators.function
+ })
+ }
+
+ let {
+ concurrency = 0,
+ ignoreResults,
+ signatures,
+ mapper
+ }= options || {}
+
+ const cancel= (reason)=>{
+ const {length}= pending;
+ for (let i = 0; i < length; i++) {
+ pending[i].cancel(reason);
+ }
+ }
+
+ scope.onCancel(cancel);
+
+ const handleProgress= (value, _scope, data) => {
+ let total = scope.innerWeight();
+ let sum = progressAcc;
+ const {length} = pending;
+ for (let i = 0; i < length; i++) {
+ const promise = pending[i];
+ sum += promise.progress() * promise.weight();
+ }
+ sum <= total && scope.progress(sum / total, _scope, data);
+ };
+
+ const _reject= err=> {
+ reject(err);
+ cancel();
+ }
+
+ function throwConvertError(){
+ throw TypeError('unable to convert object to iterable');
+ }
+
+ scope.on('capture', () => {
+ let i = pending.length;
+ while (i-- > 0) {
+ pending[i].progress(handleProgress);
+ }
+ isCaptured = true;
+ scope.innerWeight() === -1 && scope.innerWeight(computeWeightSum(pending));
+ });
+
+ if (!concurrency) {
+ pending = toArray(iterable, (value, i)=> {
+ return this.from(mapper? mapper(value, i) : value, signatures);
+ }) || throwConvertError();
+
+ return super.all(pending).then(resolve, _reject);
+ }
+
+ generator = toGenerator(iterable) || throwConvertError();
+
+ pending= [];
+ !ignoreResults && (results= []);
+
+ const next= (value)=> {
+ const promise = this.from(value, signatures);
+
+ pending.push(promise);
+
+ isCaptured && promise.progress(handleProgress);
+
+ promise.then(resolved => {
+ const index = pending.indexOf(promise);
+ if (index !== -1) {
+ pending.splice(index, 1);
+ }
+
+ !ignoreResults && results.push(resolved);
+
+ isCaptured && (progressAcc += promise.weight());
+
+ !endReached && pump();
+
+ if (!pending.length) {
+ resolve(ignoreResults ? undefined : results);
+ }
+ }, _reject);
+ }
+
+ const pump = () => {
+ while (!endReached && pending.length < concurrency) {
+ let item;
+ try {
+ item = generator.next();
+ }catch(err){
+ _reject(err);
+ return;
+ }
+
+ if (item.done){
+ endReached= true;
+ return;
+ }
+ next(mapper? mapper(item.value) : item.value);
+ }
+ }
+
+ pump();
+ })
+ }
+
+ /**
+ * returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects,
+ * with the value or reason from that promise. Other pending promises will be canceled immediately
+ * @param {Iterable} thenables
+ * @returns {CPromise}
+ */
+
+ static race(thenables) {
+ return new this((resolve, reject, scope) => {
+ thenables = toArray(thenables);
+
+ const {length} = thenables;
+
+ for (let i = 0; i < length; i++) {
+ thenables[i] = this.from(thenables[i]);
+ }
+
+ const cancel = (reason) => {
+ for (let i = 0; i < length; i++) {
+ thenables[i].cancel(reason);
+ }
+ };
+
+ scope.on('capture', () => {
+ let max = 0;
+ for (let i = 0; i < length; i++) {
+ thenables[i].progress((value, scope, data) => {
+ for (let i = 0; i < length; i++) {
+ if (value > max) {
+ max = value;
+ return scope.set(value, data);
+ }
+ }
+ })
+ }
+ });
+
+ scope.onCancel(cancel);
+
+ super.race(thenables).then((value) => {
+ resolve(value);
+ cancel();
+ }, (err) => {
+ reject(err);
+ cancel();
+ });
+ });
+ }
+
+ static [_objectToCPromise](thing) {
+ const convertMethod = thing[_toCPromise];
+
+ if (typeof convertMethod === 'function') {
+ if (promiseAssocStore.has(thing)) {
+ return promiseAssocStore.get(thing)
+ }
+
+ const returnedValue = convertMethod.call(thing, this);
+
+ if (!(returnedValue instanceof this)) {
+ throw Error(`method '[${convertMethod}]' must return a CPromise instance`)
+ }
+
+ promiseAssocStore.set(thing, returnedValue);
+
+ return returnedValue;
+ }
+
+ if (thing && typeof thing.then === 'function') {
+ return new this((resolve, reject, {onCancel}) => {
+ if (typeof thing.cancel === 'function') {
+ onCancel(reason => {
+ try {
+ thing.cancel(reason);
+ } catch (err) {
+ reject(err);
+ }
+ });
+ }
+ return thing.then(resolve, reject);
+ });
+ }
+
+ return null;
+ }
+
+ /**
+ * Converts thing to CPromise using the following rules:
+ * - CPromise instance returns as is
+ * - Objects with special method defined with key `Symbol.for('toCPromise')` will be converted using this method
+ * The result will be cached for future calls
+ * - Thenable wraps into a new CPromise instance, if thenable has the `cancel` method it will be used for canceling
+ * - Generator function will be resolved to CPromise
+ * - Array will be resoled via `CPromise.all`, arrays with one element (e.g. `[[1000]]`) will be resolved via `CPromise.race`
+ *
+ * This method returns null if the conversion failed.
+ * @param {*} thing
+ * @param {boolean} [resolveSignatures= true]
+ * @returns {CPromise}
+ */
+
+ static from(thing, resolveSignatures= true) {
+ if (thing && thing instanceof this) {
+ return thing;
+ }
+
+ if(resolveSignatures) {
+ const type = typeof thing;
+
+ if (type === 'object') {
+ if (isArray(thing)) {
+ if (thing.length === 1) {
+ const first = thing[0];
+ if (isArray(first)) {
+ return this.race(first.map(this.from, this));
+ }
+ }
+ return this.all(thing.map(this.from, this))
+ }
+ } else if (type === 'function') {
+ if (isGeneratorFunction(thing)) {
+ return resolveGenerator.call(this, thing)
+ }
+ }
+
+ return this[_objectToCPromise](thing) || this.resolve(thing);
+ }
+
+ return this.resolve(thing);
+ }
+
+
+ /**
+ * adds a new listener
+ * @alias CPromise#addEventListener
+ * @param {EventType} type
+ * @param {Function} listener
+ * @returns {CPromise}
+ */
+ on(type, listener) {
+ const events = this[_events] || (this[_events] = new EmptyObject());
+ const listeners = events[type];
+
+ events['newListener'] && this.emit('newListener', type, listener);
+
+ if (!listeners) {
+ events[type] = listener;
+ return this;
+ }
+
+ if (typeof listeners === 'function') {
+ events[type] = [listeners, listener];
+ return this;
+ }
+
+ listeners.push(listener);
+ return this;
+ }
+
+ /**
+ * removes the listener
+ * @alias CPromise#removeEventListener
+ * @param {EventType} type
+ * @param {Function} listener
+ * @returns {CPromise}
+ */
+
+ off(type, listener) {
+ if(typeof listener!=='function'){
+ throw TypeError('listener must be a function');
+ }
+
+ const events = this[_events]
+ if (!events) return this;
+ const listeners = events[type];
+ if (!listeners) {
+ return this;
+ }
+
+ if (typeof listeners === 'function' && listeners === listener) {
+ events[type] = null;
+ events['removeListener'] && this.emit('removeListener', type, listener);
+ return this;
+ }
+
+ const len = listeners.length;
+
+ for (let i = 0; i < len; i++) {
+ if (listeners[i] === listener) {
+ len === 1 ? events[type] = null : listeners.splice(i, 1);
+ events['removeListener'] && this.emit('removeListener', type, listener);
+ return this;
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * returns listeners count of the specific event type
+ * @param {EventType} type
+ * @returns {Number}
+ */
+
+ listenersCount(type){
+ const events = this[_events];
+ if (!events) return 0;
+ const listeners= events[type];
+ if(!listeners) return 0;
+ return typeof listeners==='function'? 1 : listeners.length;
+ }
+
+ /**
+ * checks if there are listeners of a specific type
+ * @param {String|Symbol} type
+ * @returns {Boolean}
+ */
+
+ hasListeners(type){
+ const events = this[_events];
+ return !!(events && events[type]);
+ }
+
+ /**
+ * add 'once' listener
+ * @param {EventType} type
+ * @param {Function} listener
+ * @returns {CPromise}
+ */
+
+ once(type, listener) {
+ const emitter = this;
+
+ function _listener() {
+ emitter.off(type, _listener);
+ listener.apply(emitter, arguments);
+ }
+
+ return this.on(type, _listener);
+ }
+
+ /**
+ * emits the event
+ * @param {EventType} type
+ * @param args
+ * @returns {CPromise}
+ */
+
+ emit(type, ...args) {
+ const events = this[_events];
+ if (!events) return this;
+ const listeners = events[type];
+ if (!listeners) return this;
+
+ if (typeof listeners === 'function') {
+ listeners.apply(this, args);
+ return this;
+ }
+
+ for (let i = 0; i < listeners.length; i++) {
+ listeners[i].apply(this, args)
+ }
+
+ return this;
+ }
+
+ /**
+ * emits the hook event
+ * @param {EventType} type
+ * @param args
+ * @returns {Boolean} - false if some listener returned false
+ */
+
+ emitHook(type, ...args) {
+ const events = this[_events];
+ if (!events) return this;
+ const listeners = events[type];
+ if (!listeners) return true;
+
+ if (typeof listeners === 'function') {
+ return listeners.apply(this, args) !== false;
+ }
+
+ for (let i = 0; i < listeners.length; i++) {
+ if (listeners[i].apply(this, args) === false) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * removes all listeners
+ * @returns {CPromise}
+ */
+
+ removeAllListeners() {
+ this[_events] = null;
+ return this;
+ }
+}
+
+const {prototype}= CPromise;
+
+prototype.addEventListener = prototype.on;
+prototype.removeEventListener = prototype.off;
+
+module.exports= CPromise;
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 0000000..28fd768
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,53 @@
+const isThenable = obj => !!obj && (typeof obj === 'function' || typeof obj === 'object') && typeof obj.then === 'function';
+const _setImmediate = typeof setImmediate === 'function' ? setImmediate : function setImmediateShim(cb) {
+ setTimeout(cb, 0)
+}
+function isGeneratorFunction(thing) {
+ return typeof thing === 'function' && thing.constructor && thing.constructor.name === 'GeneratorFunction';
+}
+
+function isGenerator(thing) {
+ return thing && typeof thing === 'object' && typeof thing.next === 'function';
+}
+
+function EmptyObject() {
+}
+
+EmptyObject.prototype = null;
+
+const toGenerator= function(thing, args, context= null){
+ if(isGeneratorFunction(thing)){
+ return thing.apply(context, args);
+ }
+ return thing && (isGenerator(thing)? thing : (thing[Symbol.iterator] && thing[Symbol.iterator]())) || null;
+}
+
+const toArray= (thing, mapper)=>{
+
+ if (thing) {
+ if (Array.isArray(thing)) {
+ return mapper ? thing.map(mapper) : thing;
+ }
+
+ if ((thing= toGenerator(thing))) {
+ const arr = [];
+ let item;
+ while ((item = thing.next()) && item.done === false) {
+ arr.push(mapper ? mapper(item.value) : item.value);
+ }
+ return arr;
+ }
+ }
+
+ return null;
+}
+
+module.exports={
+ isThenable,
+ setImmediate: _setImmediate,
+ isGenerator,
+ isGeneratorFunction,
+ EmptyObject,
+ toGenerator,
+ toArray
+};
diff --git a/package-lock.json b/package-lock.json
index ea439db..7b95fdd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -346,22 +346,6 @@
"integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
"dev": true
},
- "@mrmlnc/readdir-enhanced": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
- "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
- "dev": true,
- "requires": {
- "call-me-maybe": "^1.0.1",
- "glob-to-regexp": "^0.3.0"
- }
- },
- "@nodelib/fs.stat": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
- "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
- "dev": true
- },
"@rollup/plugin-commonjs": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-15.0.0.tgz",
@@ -624,51 +608,12 @@
"sprintf-js": "~1.0.2"
}
},
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
- },
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
- "dev": true
- },
- "arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
- "dev": true
- },
"array-back": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.1.tgz",
"integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==",
"dev": true
},
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
- "dev": true,
- "requires": {
- "array-uniq": "^1.0.1"
- }
- },
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
"array.prototype.map": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz",
@@ -696,33 +641,12 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true
},
- "assign-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
- "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
- "dev": true
- },
- "async": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
- "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.14"
- }
- },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
- "dev": true
- },
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -741,61 +665,6 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "dev": true,
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -920,23 +789,6 @@
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
"dev": true
},
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "dev": true,
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- }
- },
"cache-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz",
@@ -992,12 +844,6 @@
"write-file-atomic": "^3.0.0"
}
},
- "call-me-maybe": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
- "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
- "dev": true
- },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -1010,12 +856,6 @@
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
- "capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
- "dev": true
- },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -1063,29 +903,6 @@
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
"dev": true
},
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
- },
"clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -1156,16 +973,6 @@
"stream-via": "^1.0.4"
}
},
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
- "dev": true,
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- }
- },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1287,12 +1094,6 @@
"integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
"dev": true
},
- "component-emitter": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
- "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
- "dev": true
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1347,12 +1148,6 @@
}
}
},
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
- "dev": true
- },
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -1385,15 +1180,6 @@
"request": "^2.88.2"
}
},
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "dev": true,
- "requires": {
- "capture-stack-trace": "^1.0.0"
- }
- },
"cross-env": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz",
@@ -1444,12 +1230,6 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true
},
- "decode-uri-component": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
- "dev": true
- },
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
@@ -1495,47 +1275,6 @@
"object-keys": "^1.0.12"
}
},
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -1548,32 +1287,6 @@
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
- "dir-glob": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
- "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
- "dev": true,
- "requires": {
- "path-type": "^3.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
- "dev": true
- }
- }
- },
"dmd": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/dmd/-/dmd-5.0.2.tgz",
@@ -1611,547 +1324,20 @@
"is-obj": "^2.0.0"
}
},
- "dox": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/dox/-/dox-0.9.0.tgz",
- "integrity": "sha1-vpewhcufSgt+gINdVH53uGh9Cgw=",
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"dev": true,
"requires": {
- "commander": "~2.9.0",
- "jsdoctypeparser": "^1.2.0",
- "markdown-it": "~7.0.0"
- },
- "dependencies": {
- "commander": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
- "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
- "dev": true,
- "requires": {
- "graceful-readlink": ">= 1.0.0"
- }
- },
- "entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "dev": true
- },
- "markdown-it": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-7.0.1.tgz",
- "integrity": "sha1-8S2LiKk+ZCVDSN/Rg71wv2BWekI=",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "entities": "~1.1.1",
- "linkify-it": "^2.0.0",
- "mdurl": "^1.0.1",
- "uc.micro": "^1.0.1"
- }
- }
- }
- },
- "doxdox": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doxdox/-/doxdox-3.0.0.tgz",
- "integrity": "sha512-6yvubIVhlPcTyoszMET9Za/61M2R1/IJXrnIH8uzCHIio1+oTZpbZtjDfarQlWynruhXtatm3b0LrhacrsevBw==",
- "dev": true,
- "requires": {
- "chalk": "2.4.2",
- "doxdox-parser-dox": "~2.0.0",
- "doxdox-plugin-bootstrap": "~2.0.0",
- "doxdox-plugin-handlebars": "~2.0.0",
- "doxdox-plugin-markdown": "~2.0.0",
- "globby": "9.0.0",
- "parse-cmd-args": "2.0.0",
- "update-notifier": "2.5.0"
- },
- "dependencies": {
- "ansi-align": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
- "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
- "dev": true,
- "requires": {
- "string-width": "^2.0.0"
- }
- },
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "boxen": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
- "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
- "dev": true,
- "requires": {
- "ansi-align": "^2.0.0",
- "camelcase": "^4.0.0",
- "chalk": "^2.0.1",
- "cli-boxes": "^1.0.0",
- "string-width": "^2.0.0",
- "term-size": "^1.2.0",
- "widest-line": "^2.0.0"
- }
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "ci-info": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
- "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
- "dev": true
- },
- "cli-boxes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
- "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
- "dev": true
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
- },
- "configstore": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz",
- "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==",
- "dev": true,
- "requires": {
- "dot-prop": "^4.2.1",
- "graceful-fs": "^4.1.2",
- "make-dir": "^1.0.0",
- "unique-string": "^1.0.0",
- "write-file-atomic": "^2.0.0",
- "xdg-basedir": "^3.0.0"
- }
- },
- "crypto-random-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
- "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
- "dev": true
- },
- "dot-prop": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
- "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
- "dev": true,
- "requires": {
- "is-obj": "^1.0.0"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- },
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
- },
- "global-dirs": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
- "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
- "dev": true,
- "requires": {
- "ini": "^1.3.4"
- }
- },
- "got": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
- "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
- "dev": true,
- "requires": {
- "create-error-class": "^3.0.0",
- "duplexer3": "^0.1.4",
- "get-stream": "^3.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "safe-buffer": "^5.0.1",
- "timed-out": "^4.0.0",
- "unzip-response": "^2.0.1",
- "url-parse-lax": "^1.0.0"
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "is-ci": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
- "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
- "dev": true,
- "requires": {
- "ci-info": "^1.5.0"
- }
- },
- "is-installed-globally": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
- "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
- "dev": true,
- "requires": {
- "global-dirs": "^0.1.0",
- "is-path-inside": "^1.0.0"
- }
- },
- "is-npm": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
- "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
- "dev": true
- },
- "is-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
- "dev": true
- },
- "is-path-inside": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
- "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
- "dev": true,
- "requires": {
- "path-is-inside": "^1.0.1"
- }
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
- },
- "latest-version": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
- "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
- "dev": true,
- "requires": {
- "package-json": "^4.0.0"
- }
- },
- "make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "package-json": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
- "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
- "dev": true,
- "requires": {
- "got": "^6.7.1",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
- "dev": true
- },
- "prepend-http": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
- "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
- "dev": true
- },
- "registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "dev": true,
- "requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dev": true,
- "requires": {
- "rc": "^1.0.1"
- }
- },
- "semver-diff": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
- "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
- "dev": true,
- "requires": {
- "semver": "^5.0.3"
- }
- },
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "term-size": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
- "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
- "dev": true,
- "requires": {
- "execa": "^0.7.0"
- }
- },
- "unique-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
- "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
- "dev": true,
- "requires": {
- "crypto-random-string": "^1.0.0"
- }
- },
- "update-notifier": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
- "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
- "dev": true,
- "requires": {
- "boxen": "^1.2.1",
- "chalk": "^2.0.1",
- "configstore": "^3.0.0",
- "import-lazy": "^2.1.0",
- "is-ci": "^1.0.10",
- "is-installed-globally": "^0.1.0",
- "is-npm": "^1.0.0",
- "latest-version": "^3.0.0",
- "semver-diff": "^2.0.0",
- "xdg-basedir": "^3.0.0"
- }
- },
- "url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "dev": true,
- "requires": {
- "prepend-http": "^1.0.1"
- }
- },
- "widest-line": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
- "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
- "dev": true,
- "requires": {
- "string-width": "^2.1.1"
- }
- },
- "write-file-atomic": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
- "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.11",
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.2"
- }
- },
- "xdg-basedir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
- "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
- "dev": true
- }
- }
- },
- "doxdox-parser-dox": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doxdox-parser-dox/-/doxdox-parser-dox-2.0.0.tgz",
- "integrity": "sha512-XWuitnRJjUZixPDc+VYv/QeAgk+G7UJAtGmOxhy4L8xoTqm8S9Xlfr8fZQvewPXUIraF5JrkjqYVvrIqQWVosA==",
- "dev": true,
- "requires": {
- "dox": "0.9.0"
- }
- },
- "doxdox-plugin-bootstrap": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doxdox-plugin-bootstrap/-/doxdox-plugin-bootstrap-2.0.0.tgz",
- "integrity": "sha512-ODrtIk8K/Ln84bhTd+Th4sC5gPX7UJcvQ045mIluFa3UjeJsuofs+AiPo+LrLCIVzXaqIe7FBAckqduxBDencg==",
- "dev": true,
- "requires": {
- "handlebars": "4.1.0",
- "highlight.js": "9.15.6",
- "markdown-it": "8.4.2"
- },
- "dependencies": {
- "entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "dev": true
- },
- "handlebars": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
- "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
- "dev": true,
- "requires": {
- "async": "^2.5.0",
- "optimist": "^0.6.1",
- "source-map": "^0.6.1",
- "uglify-js": "^3.1.4"
- }
- },
- "markdown-it": {
- "version": "8.4.2",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
- "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "entities": "~1.1.1",
- "linkify-it": "^2.0.0",
- "mdurl": "^1.0.1",
- "uc.micro": "^1.0.5"
- }
- }
- }
- },
- "doxdox-plugin-handlebars": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doxdox-plugin-handlebars/-/doxdox-plugin-handlebars-2.0.0.tgz",
- "integrity": "sha512-NQyMDJZM9Z7Mfs5ETSCKIPl2z4F9bw9W39oCDKXIhiEsn7pRmjWonKI7i5TMsfBqXNQEzO4aNraLt+424n/Tdw==",
- "dev": true,
- "requires": {
- "handlebars": "4.1.0",
- "highlight.js": "9.15.6",
- "markdown-it": "8.4.2"
- },
- "dependencies": {
- "entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "dev": true
- },
- "handlebars": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
- "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
- "dev": true,
- "requires": {
- "async": "^2.5.0",
- "optimist": "^0.6.1",
- "source-map": "^0.6.1",
- "uglify-js": "^3.1.4"
- }
- },
- "markdown-it": {
- "version": "8.4.2",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
- "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "entities": "~1.1.1",
- "linkify-it": "^2.0.0",
- "mdurl": "^1.0.1",
- "uc.micro": "^1.0.5"
- }
- }
- }
- },
- "doxdox-plugin-markdown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doxdox-plugin-markdown/-/doxdox-plugin-markdown-2.0.0.tgz",
- "integrity": "sha512-KKiGEPPmc/34QhcxzxWA9cxmBHYAKMfGKfQmOKFvvvrwblWNCaiSnKRKAyDaANXKjvstbuokOJkV5Z2/xrkHvA==",
- "dev": true,
- "requires": {
- "handlebars": "4.1.0"
- },
- "dependencies": {
- "handlebars": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
- "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
- "dev": true,
- "requires": {
- "async": "^2.5.0",
- "optimist": "^0.6.1",
- "source-map": "^0.6.1",
- "uglify-js": "^3.1.4"
- }
- }
- }
- },
- "duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
- },
- "ecc-jsbn": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
- "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
- "dev": true,
- "requires": {
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.1.0"
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
}
},
"emoji-regex": {
@@ -2265,212 +1451,12 @@
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
- "execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
- "dev": true,
- "requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
- },
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "dev": true,
- "requires": {
- "shebang-regex": "^1.0.0"
- }
- },
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
- "dev": true
- },
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- }
- }
- },
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
- "extend-shallow": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
- "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "dev": true,
- "requires": {
- "assign-symbols": "^1.0.0",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -2483,43 +1469,6 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
- "fast-glob": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
- "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
- "dev": true,
- "requires": {
- "@mrmlnc/readdir-enhanced": "^2.2.1",
- "@nodelib/fs.stat": "^1.1.2",
- "glob-parent": "^3.1.0",
- "is-glob": "^4.0.0",
- "merge2": "^1.2.3",
- "micromatch": "^3.1.10"
- },
- "dependencies": {
- "glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
- "dev": true,
- "requires": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
- }
- }
- }
- },
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -2601,12 +1550,6 @@
"is-buffer": "~2.0.3"
}
},
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
- "dev": true
- },
"foreground-child": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
@@ -2634,15 +1577,6 @@
"mime-types": "^2.1.12"
}
},
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "dev": true,
- "requires": {
- "map-cache": "^0.2.2"
- }
- },
"fromentries": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.1.tgz",
@@ -2701,12 +1635,6 @@
"pump": "^3.0.0"
}
},
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
- "dev": true
- },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -2739,12 +1667,6 @@
"is-glob": "^4.0.1"
}
},
- "glob-to-regexp": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
- "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
- "dev": true
- },
"global-dirs": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
@@ -2760,29 +1682,6 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
- "globby": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-9.0.0.tgz",
- "integrity": "sha512-q0qiO/p1w/yJ0hk8V9x1UXlgsXUxlGd0AHUOXZVXBO6aznDtpx7M8D1kBrCAItoPm+4l8r6ATXV1JpjY2SBQOw==",
- "dev": true,
- "requires": {
- "array-union": "^1.0.2",
- "dir-glob": "^2.2.1",
- "fast-glob": "^2.2.6",
- "glob": "^7.1.3",
- "ignore": "^4.0.3",
- "pify": "^4.0.1",
- "slash": "^2.0.0"
- },
- "dependencies": {
- "slash": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
- "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
- "dev": true
- }
- }
- },
"got": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
@@ -2808,12 +1707,6 @@
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
- "graceful-readlink": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
- "dev": true
- },
"growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
@@ -2870,64 +1763,6 @@
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
},
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"has-yarn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
@@ -2950,12 +1785,6 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
- "highlight.js": {
- "version": "9.15.6",
- "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.6.tgz",
- "integrity": "sha512-zozTAWM1D6sozHo8kqhfYgsac+B+q0PmsjXeyDrYIHHcBN0zTVT66+s2GW1GZv7DbyaROdLXKdabwS/WqPyIdQ==",
- "dev": true
- },
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -2997,12 +1826,6 @@
"which-pm-runs": "^1.0.0"
}
},
- "ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
- "dev": true
- },
"ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
@@ -3073,32 +1896,6 @@
"integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
"dev": true
},
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"is-arguments": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
@@ -3141,63 +1938,12 @@
"ci-info": "^2.0.0"
}
},
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"is-date-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
"dev": true
},
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
- "dev": true
- },
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -3271,21 +2017,6 @@
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
"dev": true
},
- "is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- }
- },
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
- "dev": true
- },
"is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@@ -3304,12 +2035,6 @@
"has-symbols": "^1.0.1"
}
},
- "is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
- "dev": true
- },
"is-set": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
@@ -3367,12 +2092,6 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -3607,23 +2326,6 @@
"walk-back": "^4.0.0"
}
},
- "jsdoctypeparser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz",
- "integrity": "sha1-597cFToRhJ/8UUEUSuhqfvDCU5I=",
- "dev": true,
- "requires": {
- "lodash": "^3.7.0"
- },
- "dependencies": {
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
- "dev": true
- }
- }
- },
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -3690,12 +2392,6 @@
"json-buffer": "3.0.0"
}
},
- "kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true
- },
"klaw": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
@@ -3801,16 +2497,6 @@
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true
},
- "lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
@@ -3837,21 +2523,6 @@
}
}
},
- "map-cache": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
- "dev": true
- },
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
- "dev": true,
- "requires": {
- "object-visit": "^1.0.0"
- }
- },
"markdown-it": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
@@ -3889,123 +2560,6 @@
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
- "merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- },
- "dependencies": {
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
- }
- }
- }
- },
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
@@ -4042,27 +2596,6 @@
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
- "mixin-deep": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
- "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
- "dev": true,
- "requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -4125,25 +2658,6 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- }
- },
"neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@@ -7741,23 +6255,6 @@
}
}
},
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
- "dev": true,
- "requires": {
- "path-key": "^2.0.0"
- },
- "dependencies": {
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true
- }
- }
- },
"nyc": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
@@ -7911,59 +6408,22 @@
},
"yargs-parser": {
"version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- }
- }
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
- "dev": true
- },
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "dev": true,
- "requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"requires": {
- "is-buffer": "^1.1.5"
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
}
}
}
},
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
"object-get": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz",
@@ -7988,15 +6448,6 @@
"integrity": "sha512-ZMT4owlXg3JGegecLlAgAA/6BsdKHn63R3ayXcAa3zFkF7oUBHcSb0oxszeutYe0FO2c1lT5pwCuidLkC4Gx3g==",
"dev": true
},
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.0"
- }
- },
"object.assign": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
@@ -8009,15 +6460,6 @@
"object-keys": "^1.0.11"
}
},
- "object.pick": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- }
- },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -8033,42 +6475,12 @@
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
"dev": true
},
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
- "dev": true,
- "requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
- },
- "dependencies": {
- "minimist": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
- "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
- "dev": true
- },
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
- "dev": true
- }
- }
- },
"p-cancelable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
"dev": true
},
- "p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true
- },
"p-limit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
@@ -8143,12 +6555,6 @@
"callsites": "^3.0.0"
}
},
- "parse-cmd-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/parse-cmd-args/-/parse-cmd-args-2.0.0.tgz",
- "integrity": "sha1-KtbQ/UhdeWMs1AbIPU2HfXk6k1U=",
- "dev": true
- },
"parse-json": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
@@ -8161,18 +6567,6 @@
"lines-and-columns": "^1.1.6"
}
},
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
- "dev": true
- },
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
- "dev": true
- },
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -8185,12 +6579,6 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -8221,12 +6609,6 @@
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
- "pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true
- },
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -8284,12 +6666,6 @@
"semver-compare": "^1.0.0"
}
},
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
- "dev": true
- },
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
@@ -8318,12 +6694,6 @@
"iterate-value": "^1.0.0"
}
},
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@@ -8477,16 +6847,6 @@
}
}
},
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
- }
- },
"registry-auth-token": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
@@ -8514,18 +6874,6 @@
"es6-error": "^4.0.1"
}
},
- "repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
- "dev": true
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
- "dev": true
- },
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -8590,12 +6938,6 @@
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
},
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "dev": true
- },
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
@@ -8605,12 +6947,6 @@
"lowercase-keys": "^1.0.0"
}
},
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
- },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -8647,15 +6983,6 @@
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "dev": true,
- "requires": {
- "ret": "~0.1.10"
- }
- },
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -8712,29 +7039,6 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true
},
- "set-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
- "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -8762,140 +7066,6 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "dev": true,
- "requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "dev": true,
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "dev": true,
- "requires": {
- "kind-of": "^3.2.0"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"sort-array": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.2.tgz",
@@ -8920,19 +7090,6 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
- "source-map-resolve": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
- "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
- "dev": true,
- "requires": {
- "atob": "^2.1.2",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
- }
- },
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
@@ -8951,12 +7108,6 @@
}
}
},
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
- "dev": true
- },
"sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
@@ -8977,15 +7128,6 @@
"which": "^2.0.1"
}
},
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.0"
- }
- },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -9009,27 +7151,6 @@
"tweetnacl": "~0.14.0"
}
},
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "dev": true,
- "requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
- },
"stream-connect": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
@@ -9101,12 +7222,6 @@
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
"dev": true
},
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
- },
"strip-json-comments": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
@@ -9215,62 +7330,18 @@
}
}
},
- "timed-out": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true
- },
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
"dev": true
},
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"to-readable-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
"integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
"dev": true
},
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
- "dev": true,
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- }
- },
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -9380,18 +7451,6 @@
"integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==",
"dev": true
},
- "union-value": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
- "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^2.0.1"
- }
- },
"unique-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -9401,58 +7460,6 @@
"crypto-random-string": "^2.0.0"
}
},
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "dev": true,
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
- },
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
- "dev": true
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- }
- }
- },
- "unzip-response": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
- "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
- "dev": true
- },
"update-notifier": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz",
@@ -9495,12 +7502,6 @@
"punycode": "^2.1.0"
}
},
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
- "dev": true
- },
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
@@ -9510,12 +7511,6 @@
"prepend-http": "^2.0.0"
}
},
- "use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
- "dev": true
- },
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -9739,12 +7734,6 @@
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"dev": true
},
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
"yaml": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
diff --git a/package.json b/package.json
index a857512..e202458 100644
--- a/package.json
+++ b/package.json
@@ -89,6 +89,7 @@
"yield",
"race",
"delay",
+ "suspending",
"wait",
"bluebird",
"deferred",
@@ -96,6 +97,7 @@
"aborting",
"close",
"closable",
+ "pause",
"task",
"p-cancelable"
],
diff --git a/test/tests/CPromise.js b/test/tests/CPromise.js
index ed53f70..6e28747 100644
--- a/test/tests/CPromise.js
+++ b/test/tests/CPromise.js
@@ -43,7 +43,7 @@ module.exports = {
})
},
- 'prototype.cancel()': {
+ 'cancellation': {
'should reject the promise with CanceledError': async function () {
const promise = new CPromise((resolve, reject) => {
setTimeout(resolve, 1000, 123);
@@ -111,9 +111,38 @@ module.exports = {
}
throw err;
});
- }
+ },
+
+ 'throwing the CanceledError inside the promise': {
+ "should lead to chains cancellation": async function () {
+ let canceled = false;
+ let signaled = false;
+
+ return CPromise.delay(10, 123).then((value, {signal, onCancel}) => {
+ onCancel((reason) => {
+ assert.equal(reason.message, 'test');
+ canceled = true;
+ });
+
+ signal.addEventListener('abort', () => {
+ signaled = true;
+ })
+
+ return CPromise.delay(20).then(() => {
+ throw new CPromise.CanceledError('test');
+ });
+ }).then(() => {
+ assert.fail("has not been rejected");
+ }, (err) => {
+ assert.equal(err.message, 'test');
+ assert.ok(canceled, "not cancelled");
+ assert.ok(signaled, "not signaled");
+ assert.ok(err instanceof CPromise.CanceledError);
+ })
+ }
+ },
},
- 'prototype.progress': {
+ 'progress capturing': {
'should return correct chain progress': async function () {
const chain = delay(100)
.then(() => {
@@ -143,33 +172,36 @@ module.exports = {
})
}
},
-
- "throwing the CanceledError inside the promise": {
- "should lead to chains cancellation": async function () {
- let canceled = false;
- let signaled = false;
-
- return CPromise.delay(10, 123).then((value, {signal, onCancel}) => {
- onCancel((reason) => {
- assert.equal(reason.message, 'test');
- canceled = true;
+ 'suspension': {
+ 'should support pause and resume methods': async function() {
+ let timestamp = Date.now();
+ let pauseEmitted, resumeEmitted;
+ const passed = () => {
+ return Date.now() - timestamp;
+ }
+ const chain = new CPromise((resolve, reject, {onPause, onResume}) => {
+ setTimeout(resolve, 500);
+ onPause(() => {
+ pauseEmitted = true;
});
- signal.addEventListener('abort', () => {
- signaled = true;
- })
-
- return CPromise.delay(20).then(() => {
- throw new CPromise.CanceledError('test');
+ onResume(() => {
+ resumeEmitted = true;
});
}).then(() => {
- assert.fail("has not been rejected");
- }, (err) => {
- assert.equal(err.message, 'test');
- assert.ok(canceled, "not cancelled");
- assert.ok(signaled, "not signaled");
- assert.ok(err instanceof CPromise.CanceledError);
- })
+ assert.ok(passed() > 1200, `early completion (${passed()}ms)`);
+ assert.ok(pauseEmitted, 'pause event has not been emitted');
+ assert.ok(resumeEmitted, 'resume event has not been emitted');
+ });
+
+ setTimeout(() => {
+ chain.pause();
+ setTimeout(() => {
+ chain.resume();
+ }, 1000);
+ }, 300);
+
+ return chain;
}
},
@@ -190,7 +222,63 @@ module.exports = {
}
},
- 'from': {
+ 'CPromise#Symbol(toCPromise)': {
+ 'should be invoked to convert the object to an CPromise instance': async function () {
+ const toCPromise = Symbol.for('toCPromise');
+ let invoked = false;
+ const obj = {
+ [toCPromise]: function (CPromise) {
+ invoked = true;
+ return new CPromise((resolve) => resolve(123));
+ }
+ };
+
+ const promise = CPromise.from(obj);
+
+ assert.ok(invoked);
+ assert.ok(promise instanceof CPromise);
+
+ return promise.then(value => {
+ assert.equal(value, 123);
+ })
+ }
+ },
+
+ 'CPromise#setProgress()': {
+ 'should set the value of the promise progress': function (done) {
+ const p = new CPromise(function (resolve, reject) {
+ let progress = 0;
+ let i = 0;
+ const timer = setInterval(() => {
+ progress += 0.2;
+ this.progress(progress, {description: 'test', value: i++});
+ if (progress >= 1) {
+ clearInterval(timer);
+ resolve('done');
+ }
+
+ }, 10);
+ });
+
+ const expect = [0.2, 0.4, 0.6, 0.8, 1];
+ let index = 0;
+
+ p.on('progress', (actualProgress, scope, data) => {
+ const expected = expect[index];
+
+ assert.equal(actualProgress, expected);
+ assert.deepStrictEqual(data, {description: 'test', value: index});
+ index++;
+ })
+
+ p.then(result => {
+ assert.equal(result, 'done');
+ done();
+ }).catch(done);
+ }
+ },
+
+ 'CPromise.from': {
'should convert thing to a CPromise instance': async function () {
let isCanceled = false;
const thenable = {
@@ -253,7 +341,8 @@ module.exports = {
const delay = (ms) => new CPromise((resolve, reject, {onCancel}) => {
onCancel(() => {
canceledInternals = true;
- })
+ });
+ setTimeout(resolve, ms);
});
const chain = CPromise.from(function* () {
@@ -262,13 +351,14 @@ module.exports = {
yield delay(100);
} catch (err) {
thrown = true;
- assert.ok(err instanceof CanceledError);
+ assert.ok(err instanceof CanceledError, 'error is not an instanceof CanceledError');
}
+ yield CPromise.delay(100);
+
if (!thrown) {
assert.fail('The canceled error was not thrown');
}
-
});
setTimeout(() => {
@@ -296,7 +386,8 @@ module.exports = {
}
}
},
- 'all': {
+
+ 'CPromise.all': {
'should resolved with array of inner chain vales': async function () {
const v1 = 123;
const v2 = 456;
@@ -355,7 +446,8 @@ module.exports = {
})
}
},
- 'race': {
+
+ 'CPromise.race': {
'should return a promise that fulfills or rejects as soon as one of the promises settled': async function () {
const v1 = 123;
const v2 = 456;
@@ -381,25 +473,68 @@ module.exports = {
});
}
},
- 'method Symbol(toCPromise)': {
- 'should be invoked to convert the object to an CPromise instance': async function () {
- const toCPromise = Symbol.for('toCPromise');
- let invoked = false;
- const obj = {
- [toCPromise]: function (CPromise) {
- invoked = true;
- return new CPromise((resolve) => resolve(123));
- }
- };
- const promise = CPromise.from(obj);
+ 'CPromise.allSettled': async function(){
+ const err= new Error('test1');
+ return CPromise.allSettled([
+ delay(100, 123),
+ CPromise.reject(err),
+ CPromise.resolve(456)
+ ]).then(results=>{
+ assert.deepStrictEqual(results, [
+ {status: 'fulfilled', value: 123},
+ {status: 'rejected', reason: err},
+ {status: 'fulfilled', value: 456}
+ ]);
+ })
+ },
- assert.ok(invoked);
- assert.ok(promise instanceof CPromise);
+ 'CPromise.on': {
+ 'should add new listener': function () {
+ const ee= new CPromise(resolve=>{});
+ assert.equal(ee.listenersCount('test'), 0);
+ ee.on('test', function(){});
+ assert.equal(ee.listenersCount('test'), 1);
+ ee.on('test', function(){});
+ assert.equal(ee.listenersCount('test'), 2);
+ }
+ },
- return promise.then(value => {
- assert.equal(value, 123);
- })
+ 'CPromise.off': {
+ 'should remove the listener': function () {
+ const ee= new CPromise(resolve=>{});
+ const listener1= function(){};
+ const listener2= function(){};
+ ee.on('test', listener1);
+ assert.equal(ee.listenersCount('test'), 1);
+ ee.on('test', listener2);
+ assert.equal(ee.listenersCount('test'), 2);
+ ee.off('test', listener1);
+ assert.equal(ee.listenersCount('test'), 1);
+ ee.off('test', listener2);
+ assert.equal(ee.listenersCount('test'), 0);
}
- }
+ },
+
+ 'CPromise.emit': {
+ 'should emit the event listeners': function () {
+ const ee= new CPromise(resolve=>{});
+ let invoked1, invoked2;
+ const listener1= function(...data){
+ invoked1= true;
+ assert.deepStrictEqual(data, [1, 2, 3]);
+ };
+ const listener2= function(...data){
+ invoked2= true;
+ assert.deepStrictEqual(data, [1, 2, 3]);
+ };
+ ee.on('test', listener1);
+ ee.on('test', listener2);
+
+ ee.emit('test', 1, 2, 3);
+
+ assert.ok(invoked1);
+ assert.ok(invoked2);
+ }
+ },
};
diff --git a/test/tests/EventEmitter.js b/test/tests/EventEmitter.js
deleted file mode 100644
index 2d2f83a..0000000
--- a/test/tests/EventEmitter.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const assert= require('assert');
-const {TinyEventEmitter} = require( '../../lib/tiny-event-emitter');
-
-module.exports = {
- on: {
- 'should add new listener': function () {
- const ee= new TinyEventEmitter();
- assert.equal(ee.listenersCount('test'), 0);
- ee.on('test', function(){});
- assert.equal(ee.listenersCount('test'), 1);
- ee.on('test', function(){});
- assert.equal(ee.listenersCount('test'), 2);
- }
- },
-
- off: {
- 'should remove the listener': function () {
- const ee= new TinyEventEmitter();
- const listener1= function(){};
- const listener2= function(){};
- ee.on('test', listener1);
- assert.equal(ee.listenersCount('test'), 1);
- ee.on('test', listener2);
- assert.equal(ee.listenersCount('test'), 2);
- ee.off('test', listener1);
- assert.equal(ee.listenersCount('test'), 1);
- ee.off('test', listener2);
- assert.equal(ee.listenersCount('test'), 0);
- }
- },
-
- emit: {
- 'should emit the event listeners': function () {
- const ee= new TinyEventEmitter();
- let invoked1, invoked2;
- const listener1= function(...data){
- invoked1= true;
- assert.deepStrictEqual(data, [1, 2, 3]);
- };
- const listener2= function(...data){
- invoked2= true;
- assert.deepStrictEqual(data, [1, 2, 3]);
- };
- ee.on('test', listener1);
- ee.on('test', listener2);
-
- ee.emit('test', 1, 2, 3);
-
- assert.ok(invoked1);
- assert.ok(invoked2);
- }
- },
-}
diff --git a/test/tests/PromiseScope.js b/test/tests/PromiseScope.js
deleted file mode 100644
index 814686b..0000000
--- a/test/tests/PromiseScope.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const assert= require('assert');
-const CPromise = require( '../../lib/c-promise');
-
-module.exports = {
- 'setProgress()': {
- 'should set the value of the promise progress': function (done) {
- const p = new CPromise(function (resolve, reject) {
- let progress = 0;
- let i = 0;
- const timer = setInterval(() => {
- progress += 0.2;
- this.progress(progress, {description: 'test', value: i++});
- if (progress >= 1) {
- clearInterval(timer);
- resolve('done');
- }
-
- }, 10);
- });
-
- const expect = [0.2, 0.4, 0.6, 0.8, 1];
- let index = 0;
-
- p.on('progress', (actualProgress, scope, data) => {
- const expected = expect[index];
-
- assert.equal(actualProgress, expected);
- assert.deepStrictEqual(data, {description: 'test', value: index});
- index++;
- })
-
- p.then(result => {
- assert.equal(result, 'done');
- done();
- }).catch(done);
- }
- }
-}