protoblast
Advanced tools
Comparing version 0.5.5 to 0.5.6
@@ -1,3 +0,13 @@ | ||
## 0.5.5 (WIP) | ||
## 0.5.6 (2018-06-20) | ||
* Add `Pledge.resolve` and `Pledge.reject` | ||
* `Function.parallel` and `Function.series` now accept an array of Pledges/Promises | ||
* Add `Pledge.all` support & some more rejection fixes | ||
* Add `Pledge.race` and make it so a Pledge's state can't change | ||
* Make `Pledge` class global (if allowed) | ||
* Add `String#startsWithAny` and `String#endsWithAny` | ||
* Add `Object.values` and `Object.entries` polyfill | ||
## 0.5.5 (2018-06-18) | ||
* Fix some reserved words | ||
@@ -4,0 +14,0 @@ * Fix `URL#parse` not working on node v10 |
@@ -188,3 +188,12 @@ module.exports = function BlastFunctionFlow(Blast, Collection, Bound) { | ||
if (typeof callback !== 'function') { | ||
callback = thrower; | ||
callback = function throwWhenNotCaught(err) { | ||
if (!err) { | ||
return; | ||
} | ||
if (!pledge._caught_rejection) { | ||
thrower(err); | ||
} | ||
}; | ||
} | ||
@@ -230,19 +239,25 @@ | ||
try { | ||
tasks[next](function nextHandler(err, result) { | ||
function nextHandler(err, result) { | ||
if (count == 1) { | ||
stop = true; | ||
err = new Error('Next handler has been called multiple times'); | ||
pledge.reject(err); | ||
return callback(err); | ||
} else if (count > 1) { | ||
// Just ignore further calls | ||
return; | ||
} | ||
if (count == 1) { | ||
stop = true; | ||
err = new Error('Next handler has been called multiple times'); | ||
pledge.reject(err); | ||
return callback(err); | ||
} else if (count > 1) { | ||
// Just ignore further calls | ||
return; | ||
} | ||
count++; | ||
count++; | ||
return handler(err, result); | ||
}); | ||
return handler(err, result); | ||
} | ||
try { | ||
if (typeof tasks[next] == 'function') { | ||
tasks[next](nextHandler); | ||
} else { | ||
Blast.Classes.Pledge.prototype.handleCallback.call(tasks[next], nextHandler); | ||
} | ||
} catch (err) { | ||
@@ -287,3 +302,3 @@ | ||
* @since 0.1.2 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
*/ | ||
@@ -398,3 +413,12 @@ Blast.defineStatic('Function', 'parallel', function parallel(_forceAsync, _limit, _tasks, _callback) { | ||
if (typeof callback !== 'function') { | ||
callback = thrower; | ||
callback = function throwWhenNotCaught(err) { | ||
if (!err) { | ||
return; | ||
} | ||
if (!pledge._caught_rejection) { | ||
thrower(err); | ||
} | ||
}; | ||
} | ||
@@ -498,6 +522,13 @@ | ||
function nextHandler(err, val) { | ||
handler(index, err, val); | ||
} | ||
try { | ||
fnc(function nextHandler(err, val) { | ||
handler(index, err, val); | ||
}); | ||
if (typeof fnc == 'function') { | ||
fnc(nextHandler); | ||
} else { | ||
Blast.Classes.Pledge.prototype.handleCallback.call(fnc, nextHandler); | ||
} | ||
} catch (err) { | ||
@@ -504,0 +535,0 @@ |
@@ -319,2 +319,50 @@ module.exports = function BlastObject(Blast, Collection, Bound, Obj) { | ||
/** | ||
* Get all the values of an object as an array | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Object} obj The object to get the values from | ||
* | ||
* @return {Array} | ||
*/ | ||
Blast.defineStatic('Object', 'values', function values(obj) { | ||
var keys = Object.keys(obj), | ||
result = new Array(keys.length), | ||
i; | ||
for (i = 0; i < keys.length; i++) { | ||
result[i] = obj[keys[i]]; | ||
} | ||
return result; | ||
}, true); | ||
/** | ||
* Get all the key-values of an object as an array | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Object} obj The object to get the values from | ||
* | ||
* @return {Array} | ||
*/ | ||
Blast.defineStatic('Object', 'entries', function entries(obj) { | ||
var keys = Object.keys(obj), | ||
result = new Array(keys.length), | ||
i; | ||
for (i = 0; i < keys.length; i++) { | ||
result[i] = [keys[i], obj[keys[i]]]; | ||
} | ||
return result; | ||
}, true); | ||
/** | ||
* Parse a path and return an array | ||
@@ -574,69 +622,2 @@ * | ||
/** | ||
* Get an array of the object values. | ||
* Does not include prototype or non-enumerables by default. | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.1.0 | ||
* @version 0.1.3 | ||
* | ||
* @param {Object} obj The object to get the values from | ||
* @param {Array} keys The order of the keys to use | ||
* @param {Boolean} include_prototype If true, prototypal properties also count | ||
* | ||
* @return {Array} | ||
*/ | ||
Blast.defineStatic('Object', 'values', function values(obj, keys, include_prototype) { | ||
var skipProtocheck, | ||
result, | ||
length, | ||
key, | ||
i; | ||
// If no object is given, return an empty array | ||
if (!obj) { | ||
return result; | ||
} | ||
// If no key order is given, use the keys of the object itself | ||
if (!Array.isArray(keys)) { | ||
// Remember the prototype value | ||
include_prototype = keys; | ||
// Get all the own, enumerable keys | ||
keys = Object.keys(obj); | ||
// If we want the prototype, add them | ||
if (include_prototype) { | ||
keys = keys.concat(Object.keys(Object.getPrototypeOf(obj))); | ||
} | ||
skipProtocheck = true; | ||
} else if (typeof include_prototype == 'undefined') { | ||
// When keys have been given, include_prototype defaults to true. | ||
// Because the user specifically wants that key | ||
include_prototype = true; | ||
skipProtocheck = true; | ||
} | ||
// Get the amount of keys | ||
length = keys.length; | ||
// Prepare the array | ||
result = new Array(length); | ||
for (i = 0; i < length; i++) { | ||
key = keys[i]; | ||
if (skipProtocheck || obj.hasOwnProperty(key)) { | ||
result[i] = obj[key]; | ||
} | ||
} | ||
return result; | ||
}); | ||
/** | ||
* Inject the enumerable properties of one object into another target object | ||
@@ -643,0 +624,0 @@ * |
@@ -12,3 +12,3 @@ module.exports = function BlastPledge(Blast, Collection) { | ||
* @since 0.4.0 | ||
* @version 0.4.0 | ||
* @version 0.5.6 | ||
* | ||
@@ -27,3 +27,3 @@ * @param {Function} executor | ||
// Start the executor when the event loop is empty | ||
this._startExecutor(true); | ||
this._startExecutor(false); | ||
}); | ||
@@ -120,2 +120,85 @@ | ||
/** | ||
* Create a new pledge and resolve it with the given value | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Mixed} value | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setStatic(function resolve(value) { | ||
var pledge = new this(); | ||
Blast.nextTick(function onNextTick() { | ||
pledge.resolve(value); | ||
}); | ||
return pledge; | ||
}); | ||
/** | ||
* Create a new pledge and reject it with the given value | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Error} err | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setStatic(function reject(err) { | ||
var pledge = new this(); | ||
Blast.nextTick(function onNextTick() { | ||
pledge.reject(err); | ||
}); | ||
return pledge; | ||
}); | ||
/** | ||
* Create a new pledge and perform the given tasks | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Array} tasks | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setStatic(function all(tasks) { | ||
if (tasks == null || !Array.isArray(tasks)) { | ||
return this.reject(new Error('No valid tasks were given')); | ||
} | ||
return Blast.Bound.Function.parallel(false, tasks); | ||
}); | ||
/** | ||
* Create a new pledge and race the given tasks | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Array} tasks | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setStatic(function race(tasks) { | ||
return new this(function doPledgeRace(resolve, reject) { | ||
for (var i = 0; i < tasks.length; i += 1) { | ||
Pledge.resolve(tasks[i]).then(resolve, reject); | ||
} | ||
}); | ||
}); | ||
/** | ||
* Start the executor | ||
@@ -252,6 +335,10 @@ * | ||
* @since 0.4.0 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
*/ | ||
Pledge.setMethod(function resolve(value) { | ||
if (this.state != PENDING) { | ||
return; | ||
} | ||
if (value === this) { | ||
@@ -269,3 +356,3 @@ throw new TypeError('A pledge cannot be resolved with itself.'); | ||
* @since 0.4.0 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
*/ | ||
@@ -301,3 +388,3 @@ Pledge.setMethod(function _doResolve(value) { | ||
* @since 0.4.0 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
* | ||
@@ -308,6 +395,12 @@ * @param {Error} reason | ||
var result = this._doReject(reason); | ||
var result; | ||
if (this.state != PENDING) { | ||
return; | ||
} | ||
result = this._doReject(reason); | ||
if (!result) { | ||
throw reason; | ||
console.warn('Uncaught Pledge error: ' + reason); | ||
} | ||
@@ -321,3 +414,3 @@ }); | ||
* @since 0.4.0 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
* | ||
@@ -352,2 +445,4 @@ * @param {Error} reason | ||
this._caught_rejection = caught_rejection; | ||
return caught_rejection; | ||
@@ -361,7 +456,10 @@ }); | ||
* @since 0.4.0 | ||
* @version 0.5.2 | ||
* @version 0.5.6 | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setMethod(function then(on_fulfilled, on_rejected) { | ||
var then_pledge = new Pledge(); | ||
var that = this, | ||
then_pledge = new this.constructor(); | ||
@@ -402,2 +500,3 @@ // Create the arrays only when listeners are added | ||
caught_rejection = true; | ||
that._caught_rejection = true; | ||
} else { | ||
@@ -432,2 +531,4 @@ result = reason; | ||
* @version 0.4.0 | ||
* | ||
* @return {Pledge} | ||
*/ | ||
@@ -439,2 +540,32 @@ Pledge.setMethod('catch', function _catch(on_rejected) { | ||
/** | ||
* When the promise is settled, whether fulfilled or rejected, | ||
* the specified callback function is executed | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Function} on_finally | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setMethod('finally', function _finally(on_finally) { | ||
var constructor = this.constructor; | ||
return this.then( | ||
function afterResolved(value) { | ||
return constructor.resolve(on_finally()).then(function() { | ||
return value; | ||
}); | ||
}, | ||
function afterRejected(reason) { | ||
return constructor.resolve(on_finally()).then(function() { | ||
return constructor.reject(reason); | ||
}); | ||
} | ||
); | ||
}); | ||
/** | ||
* Handle an old-style callback | ||
@@ -444,3 +575,3 @@ * | ||
* @since 0.5.0 | ||
* @version 0.5.0 | ||
* @version 0.5.6 | ||
*/ | ||
@@ -457,2 +588,7 @@ Pledge.setMethod(function handleCallback(callback) { | ||
// Catch when the supplied context is changed to a non-promise | ||
if (!this || !this.then) { | ||
return callback(null, this); | ||
} | ||
this.then(function onResolved(value) { | ||
@@ -465,2 +601,3 @@ callback(null, value); | ||
Blast.defineClass('Pledge', Pledge); | ||
}; |
@@ -962,2 +962,30 @@ module.exports = function BlastString(Blast, Collection, Bound, Obj) { | ||
/** | ||
* See if a string starts with any of the given strings | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Array} strings | ||
* | ||
* @return {Boolean} | ||
*/ | ||
Blast.definePrototype('String', 'startsWithAny', function startsWithAny(strings) { | ||
var i; | ||
if (!Array.isArray(strings)) { | ||
return this.startsWith(strings); | ||
} | ||
for (i = 0; i < strings.length; i++) { | ||
if (this.startsWith(strings[i])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}); | ||
/** | ||
* See if a string ends with the given word | ||
@@ -983,2 +1011,30 @@ * | ||
/** | ||
* See if a string ends with any of the given strings | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* | ||
* @param {Array} strings | ||
* | ||
* @return {Boolean} | ||
*/ | ||
Blast.definePrototype('String', 'endsWithAny', function endsWithAny(strings) { | ||
var i; | ||
if (!Array.isArray(strings)) { | ||
return this.endsWith(strings); | ||
} | ||
for (i = 0; i < strings.length; i++) { | ||
if (this.endsWith(strings[i])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}); | ||
/** | ||
* Add a postfix to a string if it isn't present yet | ||
@@ -985,0 +1041,0 @@ * |
{ | ||
"name": "protoblast", | ||
"description": "Native object expansion library", | ||
"version": "0.5.5", | ||
"version": "0.5.6", | ||
"author": "Jelle De Loecker <jelle@develry.be>", | ||
@@ -27,10 +27,11 @@ "keywords": [ | ||
"devDependencies": { | ||
"browserify" : "5.11.0", | ||
"codecov" : "~3.0.0", | ||
"git-rev" : "0.2.1", | ||
"istanbul" : "^0.4.5", | ||
"matcha" : "skerit/matcha", | ||
"mocha" : "^5.0.1", | ||
"uglify-js" : "3.2.0", | ||
"wd" : "1.4.1" | ||
"browserify" : "5.11.0", | ||
"codecov" : "~3.0.0", | ||
"git-rev" : "0.2.1", | ||
"istanbul" : "^0.4.5", | ||
"matcha" : "skerit/matcha", | ||
"mocha" : "^5.0.1", | ||
"promises-aplus-tests" : "~2.1.2", | ||
"uglify-js" : "3.2.0", | ||
"wd" : "1.4.1" | ||
}, | ||
@@ -37,0 +38,0 @@ "engines": { |
501966
20605
9