Skip to content

Commit

Permalink
Removed CPromise.from method;
Browse files Browse the repository at this point in the history
Added `resolveSignatures` option to the `CPromise.resolve` method as a replacement for the `CPromise.from` method;
Added `aggregate` method;
Added CanceledError `priority` & `forced` properties;
Updated cancellation logic to support CanceledError priorities;
Updated `CanceledError.registerErrors` logic;
Updated CanceledError constructor signature;
  • Loading branch information
DigitalBrainJS committed May 7, 2021
1 parent 5e3ebb1 commit b79f8c5
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 66 deletions.
45 changes: 33 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1115,9 +1115,10 @@ Creates a new CPromise instance
* [.pause()](#module_CPromise..CPromise+pause) ⇒ <code>Boolean</code>
* [.resume()](#module_CPromise..CPromise+resume) ⇒ <code>Boolean</code>
* [.atomic([type])](#module_CPromise..CPromise+atomic)
* [.cancel([reason], [force])](#module_CPromise..CPromise+cancel)
* [.cancel([reason], [forced])](#module_CPromise..CPromise+cancel)
* [.emitSignal(type, [data], [handler], [locator])](#module_CPromise..CPromise+emitSignal) ⇒ <code>Boolean</code>
* [.delay(ms)](#module_CPromise..CPromise+delay) ⇒ <code>CPromise</code>
* [.aggregate([weight])](#module_CPromise..CPromise+aggregate) ⇒ <code>CPromise</code>
* [.then(onFulfilled, [onRejected])](#module_CPromise..CPromise+then) ⇒ <code>CPromise</code>
* [.catch(onRejected, [filter])](#module_CPromise..CPromise+catch) ⇒ <code>CPromise</code>
* [.finally(onFinally)](#module_CPromise..CPromise+finally) ⇒ <code>Promise.&lt;(T\|void)&gt;</code>
Expand All @@ -1141,7 +1142,7 @@ Creates a new CPromise instance
* [.race(thenables)](#module_CPromise..CPromise.race) ⇒ <code>CPromise</code>
* [.allSettled(iterable, [options])](#module_CPromise..CPromise.allSettled) ⇒ <code>CPromise</code>
* [.retry(fn, [options])](#module_CPromise..CPromise.retry) ⇒ <code>CPromise</code>
* [.from(thing, [options])](#module_CPromise..CPromise.from) ⇒ <code>CPromise</code>
* [.resolve(thing, [options])](#module_CPromise..CPromise.resolve) ⇒ <code>CPromise</code>
* [.promisify(originalFn, [options])](#module_CPromise..CPromise.promisify) ⇒ <code>function</code>
* [.run(generatorFn, [options])](#module_CPromise..CPromise.run) ⇒ <code>CPromise</code>
* [.async([options])](#module_CPromise..CPromise.async)
Expand Down Expand Up @@ -1410,15 +1411,15 @@ Make promise chain atomic (non-cancellable for external signals)

<a name="module_CPromise..CPromise+cancel"></a>

#### cPromise.cancel([reason], [force])
#### cPromise.cancel([reason], [forced])
throws the CanceledError that cause promise chain cancellation

**Kind**: instance method of [<code>CPromise</code>](#module_CPromise..CPromise)

| Param | Type | Default |
| --- | --- | --- |
| [reason] | <code>String</code> \| <code>Error</code> | |
| [force] | <code>Boolean</code> | <code>false</code> |
| [forced] | <code>Boolean</code> | <code>false</code> |

<a name="module_CPromise..CPromise+emitSignal"></a>

Expand All @@ -1445,6 +1446,17 @@ Returns a chain that will be resolved after specified timeout
| --- | --- |
| ms | <code>Number</code> |

<a name="module_CPromise..CPromise+aggregate"></a>

#### cPromise.aggregate([weight]) ⇒ <code>CPromise</code>
Aggregate promise chain into one promise

**Kind**: instance method of [<code>CPromise</code>](#module_CPromise..CPromise)

| Param | Type | Default |
| --- | --- | --- |
| [weight] | <code>number</code> | <code>1</code> |

<a name="module_CPromise..CPromise+then"></a>

#### cPromise.then(onFulfilled, [onRejected]) ⇒ <code>CPromise</code>
Expand Down Expand Up @@ -1699,19 +1711,17 @@ Retry async operation
| [options.delayWeight] | <code>number</code> \| <code>CPRetryDelayResolver</code> |
| [options.delay] | <code>object</code> |

<a name="module_CPromise..CPromise.from"></a>
<a name="module_CPromise..CPromise.resolve"></a>

#### CPromise.from(thing, [options]) ⇒ <code>CPromise</code>
#### CPromise.resolve(thing, [options]) ⇒ <code>CPromise</code>
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.

**Kind**: static method of [<code>CPromise</code>](#module_CPromise..CPromise)

| Param | Type | Default |
| --- | --- | --- |
| thing | <code>\*</code> | |
| [options] | <code>Object</code> | |
| [options.resolveSignatures] | <code>Boolean</code> | <code>true</code> |
| [options.args] | <code>Array</code> | |
| Param | Type |
| --- | --- |
| thing | <code>\*</code> |
| [options] | <code>resolveOptionsObject</code> \| <code>Boolean</code> |

<a name="module_CPromise..CPromise.promisify"></a>

Expand Down Expand Up @@ -2069,6 +2079,17 @@ If value is a number it will be considered as the value for timeout option If va
| attempt | <code>number</code> |
| retries | <code>number</code> |

<a name="module_CPromise..resolveOptionsObject"></a>

### CPromise~resolveOptionsObject : <code>Object</code>
**Kind**: inner typedef of [<code>CPromise</code>](#module_CPromise)
**Properties**

| Name | Type | Default |
| --- | --- | --- |
| [resolveSignatures] | <code>Boolean</code> | <code>true</code> |
| [args] | <code>\*</code> | |

<a name="module_CPromise..PromisifyFinalizeFn"></a>

### CPromise~PromisifyFinalizeFn : <code>function</code>
Expand Down
89 changes: 60 additions & 29 deletions lib/c-promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,9 @@ const CPromise= class CPromise extends Promise {
}
}

shadow.totalWeight = sum;
if (shadow.totalWeight === -1) {
shadow.totalWeight = sum;
}

return this;
}
Expand Down Expand Up @@ -825,17 +827,28 @@ const CPromise= class CPromise extends Promise {
/**
* throws the CanceledError that cause promise chain cancellation
* @param {String|Error} [reason]
* @param {Boolean} [force]
* @param {Boolean} [forced= false]
*/

cancel(reason, force = false) {
return this.emitSignal(SIGNAL_CANCEL, {err: CanceledError.from(reason), force}, function ({err}) {
!this[_shadow].canceledWith && this.reject(err);
cancel(reason, forced = false) {
let ignoreCancelError= false;
const err= CanceledError.from(reason);

return this.emitSignal(SIGNAL_CANCEL, {err, force: forced || err.forced}, function ({err}) {
!ignoreCancelError && !this[_shadow].canceledWith && this.reject(err);
return true;
}, ({err, force}, type, scope, isRoot) => {

const shadow = scope[_shadow];
const {atomic}= shadow;
const {atomic, parent} = shadow;

if (parent) {
const {isCanceled, value} = parent[_shadow];
if (isCanceled && err.priority <= value.priority) {
ignoreCancelError = true;
return false;
}
}

if (atomic === ATOMIC_TYPE_DETACHED) {
return false;
Expand Down Expand Up @@ -923,6 +936,17 @@ const CPromise= class CPromise extends Promise {
return this.then((value) => this.constructor.delay(ms, value));
}

/**
* Aggregate promise chain into one promise
* @param {number} [weight=1]
* @returns {CPromise}
*/

aggregate(weight= 1){
const promise= new this.constructor(resolve => resolve(this));
return weight !== 1 ? promise.weight(weight) : promise;
}

/**
* returns a CPromise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.
* @param {onFulfilled} onFulfilled
Expand Down Expand Up @@ -1265,19 +1289,23 @@ const CPromise= class CPromise extends Promise {

if (!concurrency) {
pending = toArray(iterable, (value, i) => {
return this.from(mapper ? mapper(value, i) : value, signatures);
return this.resolve(mapper ? mapper(value, i) : value, signatures);
}) || throwConvertError();

return super.all(pending).then(resolve, _reject);
}

if (isArray(iterable)) {
scope.innerWeight(iterable.length || 1);
}

generator = toGenerator(iterable, args, scope) || throwConvertError();

pending = [];
!ignoreResults && (results = []);

const next = (value) => {
const promise = this.from(value, signatures);
const promise = this.resolve(value, signatures);

pending.push(promise);

Expand Down Expand Up @@ -1337,7 +1365,7 @@ const CPromise= class CPromise extends Promise {
const {length} = thenables;

for (let i = 0; i < length; i++) {
thenables[i] = this.from(thenables[i]);
thenables[i] = this.resolve(thenables[i]);
}

const cancel = (reason) => {
Expand All @@ -1346,7 +1374,7 @@ const CPromise= class CPromise extends Promise {
}
};

scope.on('capture', () => {
scope.onCapture(() => {
let max = 0;
for (let i = 0; i < length; i++) {
thenables[i].progress((value, scope, data) => {
Expand Down Expand Up @@ -1482,7 +1510,7 @@ const CPromise= class CPromise extends Promise {

const doAttempt = () => {
return isGeneratorFunction(fn) ?
this.run(fn, {args: fnArgs, scopeArg: true}) : this.from(fn.apply(scope, fnArgs));
this.run(fn, {args: fnArgs, scopeArg: true}) : this.resolve(fn.apply(scope, fnArgs));
}

let _delay = delay;
Expand Down Expand Up @@ -1560,6 +1588,12 @@ const CPromise= class CPromise extends Promise {
return null;
}

/**
* @typedef {Object} resolveOptionsObject
* @property {Boolean} [resolveSignatures= true]
* @property {*} [args]
*/

/**
* Converts thing to CPromise using the following rules:
* - CPromise instance returns as is
Expand All @@ -1571,18 +1605,17 @@ const CPromise= class CPromise extends Promise {
*
* This method returns null if the conversion failed.
* @param {*} thing
* @param {Object} [options]
* @param {Boolean} [options.resolveSignatures= true]
* @param {Array} [options.args]
* @param {resolveOptionsObject|Boolean} [options]
* @returns {CPromise}
*/

static from(thing, options) {
static resolve(thing, options) {
if (thing instanceof this) {
return thing;
}

const {resolveSignatures = true, args} = (typeof options === 'boolean' ? {resolveSignatures: options} : options) || {};
const {resolveSignatures = true} =
(typeof options === 'boolean' ? {resolveSignatures: options} : options) || {};

if (resolveSignatures) {
const type = typeof thing;
Expand All @@ -1592,21 +1625,19 @@ const CPromise= class CPromise extends Promise {
if (thing.length === 1) {
const first = thing[0];
if (isArray(first)) {
return this.race(first.map(this.from, this));
return this.race(first.map(thing=> this.resolve(thing, options)));
}
}
return this.all(thing.map(this.from, this))
}
} else if (type === 'function') {
if (isGeneratorFunction(thing)) {
return this.run(thing, args)
return this.all(thing.map(thing=> this.resolve(thing, options)))
}
} else if (isGeneratorFunction(thing)) {
return this.run(thing)
}

return this[_objectToCPromise](thing) || this.resolve(thing);
return this[_objectToCPromise](thing) || super.resolve(thing);
}

return this.resolve(thing);
return super.resolve(thing);
}

/**
Expand Down Expand Up @@ -1762,6 +1793,10 @@ const CPromise= class CPromise extends Promise {
return new this((resolve, reject, scope) => {
let generator;

const name= generatorFn && generatorFn.name;

scope[_shadow].label = (name ? name : 'generator') + '*';

if (!context) {
context = scope;
}
Expand Down Expand Up @@ -1795,9 +1830,6 @@ const CPromise= class CPromise extends Promise {

const setProgress = (value, _scope, data) => {
progress = (value * weight + sum) / (scope.innerWeight() || 1);
if (progress > 1) {
progress = 1;
}
scope.progress(progress, _scope, data);
}

Expand Down Expand Up @@ -1833,7 +1865,7 @@ const CPromise= class CPromise extends Promise {
return resolve(r.value);
}

promise = this.from(r.value, {resolveSignatures});
promise = this.resolve(r.value, {resolveSignatures});

scope[_setInnerChain](promise, false);

Expand Down Expand Up @@ -1901,7 +1933,6 @@ const CPromise= class CPromise extends Promise {
*/
static progress(onProgressHandler){}


/**
* @typedef {object} ReactComponentDecoratorOptions
* @property {boolean} [subscribeAll= false]
Expand Down
Loading

0 comments on commit b79f8c5

Please sign in to comment.