protoblast
Advanced tools
Comparing version 0.5.0 to 0.5.1
@@ -0,1 +1,13 @@ | ||
## 0.5.1 (2018-02-24) | ||
* `Function.regulate` will throw an error if no function is given | ||
* `Blast.require`'d files will now be added to the client script | ||
* All files required by Blast are now loaded using `"use strict";` | ||
* Fixed many strict errors | ||
* Setting `module.exports` in a Blast file function will have the expected result (when using `Blast.require`) | ||
* A `Pledge` will now throw an `Error` if there are no rejection listeners for it | ||
* Added `Pledge#silentReject` which won't throw an `Error` in case there are no rejection listeners | ||
* Add context setting as the second parameter to `Blast.nextTick` and `Blast.setImmediate` | ||
* Removed `Blast.setTimeout` | ||
## 0.5.0 (2018-02-17) | ||
@@ -2,0 +14,0 @@ |
(function() { | ||
var useCommon; | ||
var useCommon, | ||
client_extras = []; | ||
@@ -5,0 +6,0 @@ function require(p){ |
module.exports = function BlastDate(Blast, Collection, Bound, Obj) { | ||
var msUnits; | ||
var unitMillisecondFactors, | ||
msUnits; | ||
@@ -5,0 +6,0 @@ msUnits = unitMillisecondFactors = { |
@@ -97,3 +97,3 @@ module.exports = function BlastFunctionFlow(Blast, Collection, Bound) { | ||
* @since 0.1.2 | ||
* @version 0.4.1 | ||
* @version 0.5.1 | ||
* | ||
@@ -203,3 +203,3 @@ * @param {Boolean} _forceAsync Force asynchronous behaviour [TRUE] | ||
stop = true; | ||
pledge.reject(err); | ||
pledge.silentReject(err); | ||
return callback(err); | ||
@@ -232,3 +232,3 @@ } | ||
stop = true; | ||
pledge.reject(err); | ||
pledge.silentReject(err); | ||
return callback(err); | ||
@@ -265,3 +265,3 @@ } | ||
* @since 0.1.2 | ||
* @version 0.4.1 | ||
* @version 0.5.1 | ||
*/ | ||
@@ -405,3 +405,3 @@ Blast.defineStatic('Function', 'parallel', function parallel(_forceAsync, _limit, _tasks, _callback) { | ||
stop = true; | ||
pledge.reject(err); | ||
pledge.silentReject(err); | ||
return callback(err); | ||
@@ -429,3 +429,3 @@ } | ||
stop = true; | ||
pledge.reject(err); | ||
pledge.silentReject(err); | ||
return callback(err); | ||
@@ -466,3 +466,3 @@ } | ||
stop = true; | ||
pledge.reject(err); | ||
pledge.silentReject(err); | ||
return callback(err); | ||
@@ -987,3 +987,3 @@ } | ||
* @since 0.1.6 | ||
* @version 0.1.6 | ||
* @version 0.5.1 | ||
* | ||
@@ -998,2 +998,6 @@ * @param {Function} fnc | ||
if (typeof fnc != 'function') { | ||
throw new Error('Function.regulate requires a valid function'); | ||
} | ||
if (!amount) { | ||
@@ -1000,0 +1004,0 @@ amount = 1; |
@@ -304,3 +304,3 @@ module.exports = function BlastInheritance(Blast, Collection) { | ||
* @since 0.1.3 | ||
* @version 0.5.0 | ||
* @version 0.5.1 | ||
* | ||
@@ -317,2 +317,4 @@ * @param {String|Function|Array} _parent Parent class to inherit from | ||
var parent_namespace, | ||
parent_constructor, | ||
super_constructor, | ||
parentConstructor = _parent, | ||
@@ -475,7 +477,7 @@ newConstructor = _newConstructor, | ||
for (i = 0; i < names.length; i++) { | ||
superConstructor = null; | ||
super_constructor = null; | ||
path = names[i]; | ||
superConstructor = getClass(path); | ||
super_constructor = getClass(path); | ||
inherits(superConstructor, namespace, newConstructor, _do_constitutors); | ||
inherits(super_constructor, namespace, newConstructor, _do_constitutors); | ||
} | ||
@@ -747,3 +749,3 @@ | ||
* @since 0.1.4 | ||
* @version 0.1.4 | ||
* @version 0.5.1 | ||
* | ||
@@ -807,3 +809,6 @@ * @param {Mixed} target | ||
result = temp; | ||
result.compositorParent = this; | ||
if (result) { | ||
result.compositorParent = this; | ||
} | ||
} | ||
@@ -810,0 +815,0 @@ |
@@ -468,3 +468,3 @@ module.exports = function BlastFunction(Blast, Collection) { | ||
* @since 0.1.0 | ||
* @version 0.1.0 | ||
* @version 0.5.1 | ||
* | ||
@@ -475,3 +475,5 @@ * @return {Function} | ||
var curryArgs, | ||
var curried_source, | ||
sourcecode, | ||
curry_args, | ||
curried, | ||
@@ -490,6 +492,6 @@ name, | ||
// Keep function optimized by not leaking the `arguments` object | ||
curryArgs = new Array(arguments.length); | ||
for (i = 0; i < curryArgs.length; i++) curryArgs[i] = arguments[i]; | ||
curry_args = new Array(arguments.length); | ||
for (i = 0; i < curry_args.length; i++) curry_args[i] = arguments[i]; | ||
curriedSource = function () { | ||
curried_source = function () { | ||
@@ -500,3 +502,3 @@ var args, | ||
// Clone the pre-filled arguments | ||
args = curryArgs.slice(0); | ||
args = curry_args.slice(0); | ||
@@ -515,3 +517,3 @@ // Add the new arguments | ||
// Get the sourcecode | ||
sourcecode = 'function ' + name + String(curriedSource).slice(9); | ||
sourcecode = 'function ' + name + String(curried_source).slice(9); | ||
@@ -518,0 +520,0 @@ eval('curried = ' + sourcecode); |
@@ -695,2 +695,3 @@ module.exports = function BlastInformer(Blast, Collection) { | ||
doit, | ||
key, | ||
i; | ||
@@ -824,3 +825,3 @@ | ||
* @since 0.1.3 | ||
* @version 0.3.10 | ||
* @version 0.5.1 | ||
* | ||
@@ -834,3 +835,4 @@ * @param {String|Object} type | ||
var typeName, | ||
var listeners, | ||
typeName, | ||
result, | ||
@@ -837,0 +839,0 @@ filter, |
232
lib/init.js
@@ -7,5 +7,9 @@ module.exports = function BlastInit(modifyPrototype) { | ||
other_ver, | ||
required, | ||
libpath, | ||
package, | ||
Globals, | ||
version, | ||
modulep, | ||
extras, | ||
Names, | ||
@@ -91,2 +95,17 @@ Blast, | ||
// Require the module package | ||
modulep = require('module'); | ||
// And the path package | ||
libpath = require('path'); | ||
// Sometimes scripts recursively call the blast init script, | ||
// make sure to not overwrite the original wrapper then | ||
if (!modulep.original_wrap) { | ||
modulep.original_wrap = modulep.wrap; | ||
modulep.original_wrapper = modulep.wrapper.slice(0); | ||
modulep.original_resolve = modulep._resolveFilename; | ||
modulep.strict_wrapper = modulep.original_wrapper[0] + '"use strict";'; | ||
} | ||
// Split the version | ||
@@ -158,2 +177,8 @@ temp = package.version.split('.'); | ||
// Extra files to load go here | ||
extras = []; | ||
// Already required files | ||
required = {}; | ||
Names = [ | ||
@@ -624,3 +649,3 @@ 'Function', | ||
* @since 0.1.1 | ||
* @version 0.4.1 | ||
* @version 0.5.1 | ||
* | ||
@@ -631,4 +656,4 @@ * @return {String} | ||
var template, | ||
libpath = require('path'), | ||
var client_extras = [], | ||
template, | ||
result, | ||
@@ -668,13 +693,3 @@ cpath, | ||
'init', | ||
'inflections', | ||
'diacritics', | ||
'date_format', | ||
'weakmap', | ||
'json-dry', | ||
'function_flow', | ||
'function_inheritance', | ||
'benchmark', | ||
'string_entities', | ||
'setimmediate', | ||
'sorting' | ||
'json-dry' | ||
].concat(Names); | ||
@@ -702,3 +717,16 @@ | ||
code += '});\n'; | ||
}); | ||
// Now iterate over the extras | ||
extras.forEach(function eachExtra(options) { | ||
var temp = fs.readFileSync(options.path, {encoding: 'utf8'}); | ||
if (options.added_wrapper) { | ||
temp = 'module.exports = function(Blast, Collection, Bound, Obj) {"use strict";' + temp + '\n};'; | ||
} | ||
code += 'require.register("' + options.name + '", function(module, exports, require){\n'; | ||
code += temp; | ||
code += '});\n'; | ||
}); | ||
@@ -712,2 +740,16 @@ | ||
// Add the extras to the client | ||
extras.forEach(function eachExtra(options) { | ||
if (options.client === false) { | ||
return; | ||
} | ||
client_extras.push({ | ||
name : options.name | ||
}); | ||
}); | ||
code += '\nclient_extras = ' + JSON.stringify(client_extras) + ';\n'; | ||
template = template.slice(0, id) + code + template.slice(id); | ||
@@ -879,2 +921,52 @@ | ||
/** | ||
* Check require call | ||
*/ | ||
function checkNextRequire(options) { | ||
if (!modulep) { | ||
return; | ||
} | ||
if (options.strict === false) { | ||
return; | ||
} | ||
// Overwrite the original wrap method | ||
modulep.wrap = function wrap(script) { | ||
// Restore the original functions | ||
modulep.wrap = modulep.original_wrap; | ||
modulep._resolveFilename = modulep.original_resolve; | ||
if (options.add_wrapper !== false) { | ||
if (options.add_wrapper || script.slice(0, 14) != 'module.exports') { | ||
if (script.indexOf('__cov_') > -1 && script.indexOf('module.exports=function ') > 7) { | ||
// We're in coverage mode, just ignore | ||
} else { | ||
// Yes: "added_wrapper", as in "done" | ||
options.added_wrapper = true; | ||
script = 'module.exports = function(Blast, Collection, Bound, Obj) {' + script + '\n};'; | ||
} | ||
} | ||
} | ||
// Add the strict wrapper for this requirement | ||
return modulep.strict_wrapper + script + modulep.wrapper[1]; | ||
}; | ||
// Overwrite the original _resolveFilename method | ||
modulep._resolveFilename = function _resolveFilename(request, parent, is_main) { | ||
try { | ||
return modulep.original_resolve(request, parent, is_main); | ||
} catch (err) { | ||
modulep.wrap = modulep.original_wrap; | ||
modulep._resolveFilename = modulep.original_resolve; | ||
throw err; | ||
} | ||
}; | ||
} | ||
/** | ||
* Require a Protoblast module | ||
@@ -884,8 +976,78 @@ * | ||
* @since 0.4.1 | ||
* @version 0.4.1 | ||
* @version 0.5.1 | ||
* | ||
* @param {String} name | ||
* @param {Object} options | ||
*/ | ||
Blast.require = function _require(name) { | ||
return require('./' + name + '.js')(Blast, Collection, Blast.Bound, Blast.Bound.Object); | ||
Blast.require = function _require(name, options) { | ||
var exported_module, | ||
exported_fnc, | ||
result; | ||
if (!options) { | ||
options = {}; | ||
} | ||
if (options.client == null) { | ||
options.client = true; | ||
} | ||
if (options.server == null) { | ||
options.server = true; | ||
} | ||
options.name = name; | ||
if (options.is_extra !== false) { | ||
extras.push(options); | ||
} | ||
if (Array.isArray(name)) { | ||
name = libpath.resolve.apply(libpath, name); | ||
} | ||
if (required[name]) { | ||
return; | ||
} | ||
required[name] = true; | ||
if (!options.path) { | ||
if (libpath) { | ||
if (name == libpath.basename(name)) { | ||
options.name = name; | ||
options.path = libpath.resolve(__dirname, name + '.js'); | ||
} else { | ||
options.path = name; | ||
options.name = libpath.basename(options.path); | ||
} | ||
} | ||
} | ||
if (Blast.isNode && options.server === false) { | ||
return; | ||
} | ||
// Make next require strict + look for exports | ||
checkNextRequire(options); | ||
// Get the exported function | ||
exported_fnc = require(options.path || name); | ||
// Execute the exported function | ||
result = exported_fnc(Blast, Collection, Blast.Bound, Blast.Bound.Object); | ||
if (result != null) { | ||
return result; | ||
} else if (require.cache) { | ||
// Try getting the actual exported module | ||
exported_module = require.cache[options.path || name]; | ||
if (!exported_module) { | ||
return; | ||
} | ||
return exported_module.exports; | ||
} | ||
}; | ||
@@ -901,4 +1063,18 @@ | ||
Names.forEach(function eachName(name) { | ||
var options = { | ||
// These are core files, don't add to extra | ||
is_extra : false, | ||
// Core files are already wrapped | ||
add_wrapper : false | ||
}; | ||
name = name.toLowerCase(); | ||
Blast.require(name); | ||
if (name == 'jsonpath') { | ||
options.strict = false; | ||
} | ||
Blast.require(name, options); | ||
}); | ||
@@ -909,13 +1085,17 @@ | ||
Blast.require('string_entities'); | ||
Blast.require('function_flow'); | ||
Blast.require('setimmediate'); | ||
Blast.require('inflections'); | ||
Blast.require('date_format'); | ||
Blast.require('diacritics'); | ||
Blast.require('benchmark'); | ||
Blast.require('sorting'); | ||
Blast.require('string_entities', {add_wrapper: false}); | ||
Blast.require('function_flow', {add_wrapper: false}); | ||
Blast.require('setimmediate', {add_wrapper: false}); | ||
Blast.require('inflections', {add_wrapper: false}); | ||
Blast.require('date_format', {add_wrapper: false}); | ||
Blast.require('diacritics', {add_wrapper: false}); | ||
Blast.require('benchmark', {add_wrapper: false}); | ||
Blast.require('sorting', {add_wrapper: false}); | ||
if (Blast.isBrowser) { | ||
Blast.require('browsershims'); | ||
client_extras.forEach(function eachExtra(options) { | ||
Blast.require(options.name); | ||
}); | ||
} | ||
@@ -922,0 +1102,0 @@ |
@@ -443,3 +443,4 @@ module.exports = function BlastMath(Blast, Collection, Bound) { | ||
half, | ||
len; | ||
len, | ||
i; | ||
@@ -446,0 +447,0 @@ if (Array.isArray(arr)) { |
@@ -208,3 +208,5 @@ module.exports = function BlastPledge(Blast, Collection) { | ||
* @since 0.4.0 | ||
* @version 0.4.0 | ||
* @version 0.5.1 | ||
* | ||
* @param {Error} reason | ||
*/ | ||
@@ -220,2 +222,15 @@ Pledge.setMethod(function reject(reason) { | ||
/** | ||
* Reject silently: don't throw if no listeners are available | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.4.0 | ||
* @version 0.5.1 | ||
* | ||
* @param {Error} reason | ||
*/ | ||
Pledge.setMethod(function silentReject(reason) { | ||
this._doReject(reason, true); | ||
}); | ||
/** | ||
* Do the actual rejection | ||
@@ -225,5 +240,8 @@ * | ||
* @since 0.4.0 | ||
* @version 0.4.0 | ||
* @version 0.5.1 | ||
* | ||
* @param {Error} reason | ||
* @param {Boolean} silent Don't throw errors when no rejection listeners are available | ||
*/ | ||
Pledge.setMethod(function _doReject(reason) { | ||
Pledge.setMethod(function _doReject(reason, silent) { | ||
@@ -233,7 +251,15 @@ var that = this; | ||
if (reason && reason.then) { | ||
return reason.then(function onFulfilledReject(value) { | ||
that.reject(value); | ||
}, function onRejectedReject(reason) { | ||
that.reject(reason); | ||
}); | ||
if (silent && reason.silentReject) { | ||
return reason.then(function onFulfilledReject(value) { | ||
that.silentReject(value); | ||
}, function onRejectedReject(reason) { | ||
that.silentReject(reason); | ||
}); | ||
} else { | ||
return reason.then(function onFulfilledReject(value) { | ||
that.reject(value); | ||
}, function onRejectedReject(reason) { | ||
that.reject(reason); | ||
}); | ||
} | ||
} | ||
@@ -247,2 +273,4 @@ | ||
this._on_fulfilled.length = 0; | ||
} else if (silent !== true) { | ||
throw reason; | ||
} | ||
@@ -249,0 +277,0 @@ }); |
@@ -26,3 +26,5 @@ // Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola | ||
var global = Blast.Globals, | ||
realSetImmediate, | ||
timeout_counter = 0, | ||
realNextTick, | ||
timeouts = {}, | ||
@@ -32,12 +34,12 @@ resolved; | ||
if (global.nextTick) { | ||
Blast.nextTick = global.nextTick; | ||
realNextTick = global.nextTick; | ||
} else if (global.process && global.process.nextTick) { | ||
Blast.nextTick = global.process.nextTick; | ||
realNextTick = global.process.nextTick; | ||
} else if (typeof Promise !== 'undefined' && Promise.resolve) { | ||
resolved = Promise.resolve(); | ||
Blast.nextTick = function nextTick(callback) { | ||
realNextTick = function nextTick(callback) { | ||
resolved.then(callback); | ||
}; | ||
} else if (typeof Image !== 'undefined') { | ||
Blast.nextTick = function nextTick(callback) { | ||
realNextTick = function nextTick(callback) { | ||
var img = new Image; | ||
@@ -48,3 +50,3 @@ img.onerror = callback; | ||
} else { | ||
Blast.nextTick = function nextTick(callback) { | ||
realNextTick = function nextTick(callback) { | ||
return setTimeout(callback, 0); | ||
@@ -55,91 +57,2 @@ }; | ||
/** | ||
* A more precise timeout | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.2.1 | ||
* @version 0.2.1 | ||
* | ||
* @param {Function} task The function to execute | ||
* @param {Number} ms The amount of time to wait | ||
* | ||
* @return {Number} | ||
*/ | ||
Blast.setTimeout = function BlastSetTimeout(task, ms) { | ||
var start = Date.now(), | ||
ticked = null, | ||
checks = 0, | ||
delay = null, | ||
id = ++timeout_counter; | ||
timeouts[id] = true; | ||
// When the wait time is very close, | ||
// do a next tick first | ||
// This is because on boot, setImmediate will still be slow | ||
if (ms < 6) { | ||
delay = 6; | ||
ticked = start; | ||
Blast.nextTick(check); | ||
} else { | ||
// Schedule a short timeout to see how long the delay is | ||
setTimeout(check, 5); | ||
} | ||
function check() { | ||
var elapsed, | ||
left, | ||
next, | ||
cur; | ||
// If this timeout has been cleared, do nothing | ||
if (timeouts[id] == null) { | ||
return; | ||
} | ||
cur = Date.now(); | ||
elapsed = cur - start; | ||
left = ms - elapsed; | ||
// Calculate delay | ||
if (delay == null) { | ||
delay = (elapsed - 5); | ||
if (delay < 5) { | ||
delay = 5; | ||
} | ||
delay += 1; | ||
} | ||
checks++; | ||
if (elapsed >= ms) { | ||
return task(); | ||
} else if (left > delay) { | ||
next = ~~(left / 2); | ||
// Only use timeout when next is shorter than the delay | ||
if (next > delay) { | ||
setTimeout(check, next); | ||
return; | ||
} | ||
} | ||
// If we used nextTick last time, | ||
// and there still is a delay, use it this time too | ||
if (ticked && (cur - ticked) > 1) { | ||
ticked = cur; | ||
Blast.nextTick(check); | ||
} else { | ||
ticked = null; | ||
Blast.setImmediate(check); | ||
} | ||
} | ||
return id; | ||
}; | ||
/** | ||
* Clear a blast timeout | ||
@@ -162,3 +75,3 @@ * | ||
* @since 0.2.1 | ||
* @version 0.2.1 | ||
* @version 0.5.1 | ||
* | ||
@@ -171,3 +84,3 @@ * @param {Function} task The function to execute | ||
Blast.setSchedule = function setSchedule(task, timestamp) { | ||
return Blast.setTimeout(task, timestamp - Date.now()); | ||
return setTimeout(task, timestamp - Date.now()); | ||
}; | ||
@@ -180,3 +93,3 @@ | ||
* @since 0.2.1 | ||
* @version 0.2.1 | ||
* @version 0.5.1 | ||
* | ||
@@ -186,180 +99,231 @@ * @param {Number} id The id to clear | ||
Blast.clearSchedule = function clearSchedule(id) { | ||
return Blast.clearTimeout(id); | ||
return clearTimeout(id); | ||
}; | ||
if (global.setImmediate) { | ||
Blast.setImmediate = global.setImmediate.bind(global); | ||
return; | ||
} | ||
realSetImmediate = global.setImmediate.bind(global); | ||
} else { | ||
var nextHandle = 1; // Spec says greater than zero | ||
var tasksByHandle = {}; | ||
var currentlyRunningATask = false; | ||
var doc = global.document; | ||
var setImmediate; | ||
var nextHandle = 1; // Spec says greater than zero | ||
var tasksByHandle = {};realSetImmediate | ||
var currentlyRunningATask = false; | ||
var doc = global.document; | ||
var realSetImmediate; | ||
function addFromSetImmediateArguments(args) { | ||
tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args); | ||
return nextHandle++; | ||
} | ||
function addFromSetImmediateArguments(args) { | ||
tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args); | ||
return nextHandle++; | ||
} | ||
// This function accepts the same arguments as setImmediate, but | ||
// returns a function that requires no arguments. | ||
function partiallyApplied(handler) { | ||
// This function accepts the same arguments as setImmediate, but | ||
// returns a function that requires no arguments. | ||
function partiallyApplied(handler) { | ||
var args, | ||
i; | ||
var args, | ||
i; | ||
// Keep function optimized by not leaking the `arguments` object | ||
args = new Array(arguments.length-1); | ||
for (i = 0; i < args.length; i++) args[i] = arguments[i+1]; | ||
// Keep function optimized by not leaking the `arguments` object | ||
args = new Array(arguments.length-1); | ||
for (i = 0; i < args.length; i++) args[i] = arguments[i+1]; | ||
return function doHandler() { | ||
if (typeof handler === "function") { | ||
handler.apply(undefined, args); | ||
return function doHandler() { | ||
if (typeof handler === "function") { | ||
handler.apply(undefined, args); | ||
} else { | ||
(new Function("" + handler))(); | ||
} | ||
}; | ||
} | ||
function runIfPresent(handle) { | ||
// From the spec: "Wait until any invocations of this algorithm started before this one have completed." | ||
// So if we're currently running a task, we'll need to delay this invocation. | ||
if (currentlyRunningATask) { | ||
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a | ||
// "too much recursion" error. | ||
setTimeout(partiallyApplied(runIfPresent, handle), 0); | ||
} else { | ||
(new Function("" + handler))(); | ||
var task = tasksByHandle[handle]; | ||
if (task) { | ||
currentlyRunningATask = true; | ||
try { | ||
task(); | ||
} finally { | ||
clearImmediate(handle); | ||
currentlyRunningATask = false; | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
function runIfPresent(handle) { | ||
// From the spec: "Wait until any invocations of this algorithm started before this one have completed." | ||
// So if we're currently running a task, we'll need to delay this invocation. | ||
if (currentlyRunningATask) { | ||
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a | ||
// "too much recursion" error. | ||
setTimeout(partiallyApplied(runIfPresent, handle), 0); | ||
} else { | ||
var task = tasksByHandle[handle]; | ||
if (task) { | ||
currentlyRunningATask = true; | ||
try { | ||
task(); | ||
} finally { | ||
clearImmediate(handle); | ||
currentlyRunningATask = false; | ||
function clearImmediate(handle) { | ||
delete tasksByHandle[handle]; | ||
} | ||
function installNextTickImplementation() { | ||
realSetImmediate = function setImmediateNexttick() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
process.nextTick(partiallyApplied(runIfPresent, handle)); | ||
return handle; | ||
}; | ||
} | ||
function canUsePostMessage() { | ||
// The test against `importScripts` prevents this implementation from being installed inside a web worker, | ||
// where `global.postMessage` means something completely different and can't be used for this purpose. | ||
if (global.postMessage && !global.importScripts) { | ||
var postMessageIsAsynchronous = true; | ||
var oldOnMessage = global.onmessage; | ||
global.onmessage = function() { | ||
postMessageIsAsynchronous = false; | ||
}; | ||
global.postMessage("", "*"); | ||
global.onmessage = oldOnMessage; | ||
return postMessageIsAsynchronous; | ||
} | ||
} | ||
function installPostMessageImplementation() { | ||
// Installs an event handler on `global` for the `message` event: see | ||
// * https://developer.mozilla.org/en/DOM/window.postMessage | ||
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages | ||
var messagePrefix = 'setImmediate$' + Math.random() + '$'; | ||
var onGlobalMessage = function(event) { | ||
if (event.source === global && | ||
typeof event.data === "string" && | ||
event.data.indexOf(messagePrefix) === 0) { | ||
runIfPresent(+event.data.slice(messagePrefix.length)); | ||
} | ||
}; | ||
if (global.addEventListener) { | ||
global.addEventListener("message", onGlobalMessage, false); | ||
} else { | ||
global.attachEvent("onmessage", onGlobalMessage); | ||
} | ||
realSetImmediate = function setImmediatePostmessage() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
global.postMessage(messagePrefix + handle, "*"); | ||
return handle; | ||
}; | ||
} | ||
} | ||
function clearImmediate(handle) { | ||
delete tasksByHandle[handle]; | ||
} | ||
function installMessageChannelImplementation() { | ||
var channel = new MessageChannel(); | ||
channel.port1.onmessage = function onmessage(event) { | ||
var handle = event.data; | ||
runIfPresent(handle); | ||
}; | ||
function installNextTickImplementation() { | ||
setImmediate = function setImmediateNexttick() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
process.nextTick(partiallyApplied(runIfPresent, handle)); | ||
return handle; | ||
}; | ||
} | ||
realSetImmediate = function setImmediateMessageChannel() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
channel.port2.postMessage(handle); | ||
return handle; | ||
}; | ||
} | ||
function canUsePostMessage() { | ||
// The test against `importScripts` prevents this implementation from being installed inside a web worker, | ||
// where `global.postMessage` means something completely different and can't be used for this purpose. | ||
if (global.postMessage && !global.importScripts) { | ||
var postMessageIsAsynchronous = true; | ||
var oldOnMessage = global.onmessage; | ||
global.onmessage = function() { | ||
postMessageIsAsynchronous = false; | ||
function installReadyStateChangeImplementation() { | ||
var html = doc.documentElement; | ||
realSetImmediate = function setImmediateStatechange() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted | ||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. | ||
var script = doc.createElement("script"); | ||
script.onreadystatechange = function onreadystatechange() { | ||
runIfPresent(handle); | ||
script.onreadystatechange = null; | ||
html.removeChild(script); | ||
script = null; | ||
}; | ||
html.appendChild(script); | ||
return handle; | ||
}; | ||
global.postMessage("", "*"); | ||
global.onmessage = oldOnMessage; | ||
return postMessageIsAsynchronous; | ||
} | ||
} | ||
function installPostMessageImplementation() { | ||
// Installs an event handler on `global` for the `message` event: see | ||
// * https://developer.mozilla.org/en/DOM/window.postMessage | ||
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages | ||
function installSetTimeoutImplementation() { | ||
realSetImmediate = function setImmediateTimeout() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
setTimeout(partiallyApplied(runIfPresent, handle), 0); | ||
return handle; | ||
}; | ||
} | ||
var messagePrefix = 'setImmediate$' + Math.random() + '$'; | ||
var onGlobalMessage = function(event) { | ||
if (event.source === global && | ||
typeof event.data === "string" && | ||
event.data.indexOf(messagePrefix) === 0) { | ||
runIfPresent(+event.data.slice(messagePrefix.length)); | ||
} | ||
}; | ||
// Don't get fooled by e.g. browserify environments. | ||
if ({}.toString.call(global.process) === "[object process]") { | ||
// For Node.js before 0.9 | ||
installNextTickImplementation(); | ||
if (global.addEventListener) { | ||
global.addEventListener("message", onGlobalMessage, false); | ||
} else if (canUsePostMessage()) { | ||
// For non-IE10 modern browsers | ||
installPostMessageImplementation(); | ||
} else if (global.MessageChannel) { | ||
// For web workers, where supported | ||
installMessageChannelImplementation(); | ||
} else if (doc && "onreadystatechange" in doc.createElement("script")) { | ||
// For IE 6–8 | ||
installReadyStateChangeImplementation(); | ||
} else { | ||
global.attachEvent("onmessage", onGlobalMessage); | ||
// For older browsers | ||
installSetTimeoutImplementation(); | ||
} | ||
setImmediate = function setImmediatePostmessage() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
global.postMessage(messagePrefix + handle, "*"); | ||
return handle; | ||
}; | ||
} | ||
function installMessageChannelImplementation() { | ||
var channel = new MessageChannel(); | ||
channel.port1.onmessage = function onmessage(event) { | ||
var handle = event.data; | ||
runIfPresent(handle); | ||
}; | ||
/** | ||
* A nextTick that can set the context | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.1 | ||
* @version 0.5.1 | ||
* | ||
* @param {Function} task | ||
* @param {Object} context | ||
*/ | ||
Blast.nextTick = function nextTick(task, context) { | ||
setImmediate = function setImmediateMessageChannel() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
channel.port2.postMessage(handle); | ||
return handle; | ||
}; | ||
} | ||
var args = [], | ||
i; | ||
function installReadyStateChangeImplementation() { | ||
var html = doc.documentElement; | ||
setImmediate = function setImmediateStatechange() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted | ||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. | ||
var script = doc.createElement("script"); | ||
script.onreadystatechange = function onreadystatechange() { | ||
runIfPresent(handle); | ||
script.onreadystatechange = null; | ||
html.removeChild(script); | ||
script = null; | ||
}; | ||
html.appendChild(script); | ||
return handle; | ||
}; | ||
} | ||
if (arguments.length > 2) { | ||
for (i = 2; i < arguments.length; i++) { | ||
args.push(arguments[i]); | ||
} | ||
} | ||
function installSetTimeoutImplementation() { | ||
setImmediate = function setImmediateTimeout() { | ||
var handle = addFromSetImmediateArguments(arguments); | ||
setTimeout(partiallyApplied(runIfPresent, handle), 0); | ||
return handle; | ||
}; | ||
} | ||
return realNextTick.call(global, function doTask() { | ||
task.apply(context, args); | ||
}); | ||
}; | ||
// Don't get fooled by e.g. browserify environments. | ||
if ({}.toString.call(global.process) === "[object process]") { | ||
// For Node.js before 0.9 | ||
installNextTickImplementation(); | ||
/** | ||
* A setImmediate that can set the context | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @since 0.5.1 | ||
* @version 0.5.1 | ||
* | ||
* @param {Function} task | ||
* @param {Object} context | ||
*/ | ||
Blast.setImmediate = function setImmediate(task, context) { | ||
} else if (canUsePostMessage()) { | ||
// For non-IE10 modern browsers | ||
installPostMessageImplementation(); | ||
var args = [], | ||
i; | ||
} else if (global.MessageChannel) { | ||
// For web workers, where supported | ||
installMessageChannelImplementation(); | ||
if (arguments.length > 2) { | ||
for (i = 2; i < arguments.length; i++) { | ||
args.push(arguments[i]); | ||
} | ||
} | ||
} else if (doc && "onreadystatechange" in doc.createElement("script")) { | ||
// For IE 6–8 | ||
installReadyStateChangeImplementation(); | ||
} else { | ||
// For older browsers | ||
installSetTimeoutImplementation(); | ||
return realSetImmediate.call(global, function doTask() { | ||
task.apply(context, args); | ||
}); | ||
} | ||
Blast.defineGlobal('setImmediate', setImmediate); | ||
Blast.defineGlobal('clearImmediate', clearImmediate); | ||
}; |
{ | ||
"name": "protoblast", | ||
"description": "Native object expansion library", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"author": "Jelle De Loecker <jelle@develry.be>", | ||
@@ -15,3 +15,3 @@ "keywords": [ | ||
"dependencies": { | ||
"json-dry" : "~1.0.0" | ||
"json-dry" : "~1.0.3" | ||
}, | ||
@@ -24,3 +24,3 @@ "repository": "skerit/protoblast", | ||
"coverage" : "./node_modules/istanbul/lib/cli.js cover _mocha", | ||
"report-coverage" : "cat ./coverage/lcov.info | coveralls" | ||
"report-coverage" : "cat ./coverage/lcov.info | codecov" | ||
}, | ||
@@ -30,7 +30,7 @@ "main": "lib/init.js", | ||
"browserify" : "5.11.0", | ||
"coveralls" : "^2.11.6", | ||
"codecov" : "~3.0.0", | ||
"git-rev" : "0.2.1", | ||
"istanbul" : "^0.4.5", | ||
"matcha" : "skerit/matcha", | ||
"mocha" : "1.20.x", | ||
"mocha" : "^5.0.1", | ||
"uglify-js" : "3.2.0", | ||
@@ -42,2 +42,2 @@ "wd" : "1.4.1" | ||
} | ||
} | ||
} |
@@ -1,10 +0,53 @@ | ||
# ![protoblast](https://protoblast.develry.be/media/static/protoblast-small.png?width=30) Protoblast | ||
<h1 align="center"> | ||
<img src="https://protoblast.develry.be/media/static/protoblast-small.png?width=30" alt="Protoblast logo"/> | ||
<b>Protoblast</b> | ||
</h1> | ||
<div align="center"> | ||
<!-- CI - TravisCI --> | ||
<a href="https://travis-ci.org/skerit/protoblast"> | ||
<img src="https://travis-ci.org/skerit/protoblast.svg?branch=master" alt="Mac/Linux Build Status" /> | ||
</a> | ||
[![NPM version](http://img.shields.io/npm/v/protoblast.svg)](https://npmjs.org/package/protoblast) | ||
[![Build Status](https://travis-ci.org/skerit/protoblast.svg?branch=master)](https://travis-ci.org/skerit/protoblast) | ||
[![Coverage Status](https://coveralls.io/repos/github/skerit/protoblast/badge.svg?branch=master)](https://coveralls.io/github/skerit/protoblast?branch=master) | ||
<!-- CI - AppVeyor --> | ||
<a href="https://ci.appveyor.com/project/skerit/protoblast"> | ||
<img src="https://img.shields.io/appveyor/ci/skerit/protoblast/master.svg?label=Windows" alt="Windows Build status" /> | ||
</a> | ||
Extend native objects with helpful methods to speed up development, | ||
or leave the native objects alone and use bound methods. | ||
<!-- Coverage - Codecov --> | ||
<a href="https://codecov.io/gh/skerit/protoblast"> | ||
<img src="https://img.shields.io/codecov/c/github/skerit/protoblast/master.svg" alt="Codecov Coverage report" /> | ||
</a> | ||
<!-- DM - Snyk --> | ||
<a href="https://snyk.io/test/github/skerit/protoblast?targetFile=package.json"> | ||
<img src="https://snyk.io/test/github/skerit/protoblast/badge.svg?targetFile=package.json" alt="Known Vulnerabilities" /> | ||
</a> | ||
<!-- DM - David --> | ||
<a href="https://david-dm.org/skerit/protoblast"> | ||
<img src="https://david-dm.org/skerit/protoblast/status.svg" alt="Dependency Status" /> | ||
</a> | ||
</div> | ||
<div align="center"> | ||
<!-- Version - npm --> | ||
<a href="https://www.npmjs.com/package/protoblast"> | ||
<img src="https://img.shields.io/npm/v/protoblast.svg" alt="Latest version on npm" /> | ||
</a> | ||
<!-- License - MIT --> | ||
<a href="https://github.com/skerit/protoblast#license"> | ||
<img src="https://img.shields.io/github/license/skerit/protoblast.svg" alt="Project license" /> | ||
</a> | ||
</div> | ||
<br> | ||
<div align="center"> | ||
Extend native objects with helpful methods to speed up development | ||
</div> | ||
<div align="center"> | ||
<sub> | ||
Coded with ❤️ by <a href="#authors">Jelle De Loecker</a>. | ||
</sub> | ||
</div> | ||
## Installation | ||
@@ -55,2 +98,2 @@ | ||
// ' we want' | ||
``` | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
487942
43
20162
99
17
Updatedjson-dry@~1.0.3