Comparing version
128
index.js
@@ -1,50 +0,104 @@ | ||
"use strict"; | ||
'use strict'; | ||
var EventEmitter = require('events').EventEmitter; | ||
const EventEmitter = require('events').EventEmitter; | ||
const ANY_EVENT = 0xFF; // A representative for any event | ||
function ExecStack() { | ||
this._stack = []; | ||
this._config = { | ||
'strict': false | ||
class ExecStack { | ||
/** | ||
* @author schroffl | ||
* | ||
* @constructor | ||
* | ||
* @returns A new instance of ExecStack | ||
*/ | ||
constructor() { | ||
this._stack = []; | ||
} | ||
for(var prop in arguments[0]) this._config[prop] = arguments[0][prop]; | ||
ExecStack.prototype.push = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var event = typeof args[0] === 'string' ? args.shift() : '<all>'; | ||
/** | ||
* Push a middleware to the stack | ||
* | ||
* @author schroffl | ||
* | ||
* @param {String} [event=ANY_EVENT] - The specific event to listen for | ||
* @param {Function} callback - A function to be called on execution of the stack | ||
* | ||
* @returns The position of the middleware in the stack | ||
*/ | ||
use() { | ||
const args = Array.from(arguments); | ||
for(var i=0; i<1; i++) { | ||
var callback = typeof args[i] === 'function' ? args[i] : function(){}; | ||
return (this._stack.push({'event': event, 'callback': callback}) - 1); | ||
} | ||
let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift(), | ||
callback = typeof args[0] === 'function' ? args.shift() : () => {}; | ||
return this._stack.push({ event, callback }); | ||
} | ||
ExecStack.prototype.remove = function() { | ||
/** | ||
* Remove a middleware from the stack | ||
* | ||
* @author schroffl | ||
* | ||
* @param {Number} position - The position of the middleware in the stack | ||
*/ | ||
unuse() { | ||
this._stack.splice(arguments[0], 1); | ||
} | ||
ExecStack.prototype.execute = function(event, callbackFunction) { | ||
var args = Array.prototype.slice.call(arguments); | ||
var controller = new EventEmitter(); | ||
var event = typeof args[0] === 'string' ? args.shift() : '<all>'; | ||
var callbackFunction = typeof args[0] === 'function' ? args.shift() : function(){}; | ||
var self = this; | ||
controller.on('next', function(i) { | ||
if(i > self._stack.length) return callbackFunction(); | ||
else if(typeof self._stack[i] === 'undefined') return controller.emit('next', i + 1); | ||
else if((self._stack[i].event !== event && (self._config.strict ? true : self._stack[i].event !== '<all>')) || typeof self._stack[i].callback !== 'function') return controller.emit('next', i + 1); | ||
var currArgs = args.slice(); | ||
var context = typeof args[0] === 'object' ? currArgs.shift() : {}; | ||
currArgs.push(function() { | ||
controller.emit('next', i + 1); | ||
/** | ||
* Execute the stack | ||
* | ||
* @author schroffl | ||
* | ||
* @param {String} [event=ANY_EVENT] - The event to propagate | ||
* | ||
* @returns A promise being resolved when the stack has been fully traversed | ||
*/ | ||
run() { | ||
const args = Array.from(arguments), | ||
controller = new EventEmitter(); | ||
let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift(), | ||
resolve = null, | ||
reject = null, | ||
promise = new Promise((res, rej) => { | ||
resolve = res; | ||
reject = rej; | ||
}); | ||
self._stack[i].callback.apply(context, currArgs); | ||
controller.on('next', i => { | ||
let current = this._stack[i]; | ||
// If i exceeds the amount of functions on the stack => abort | ||
if(i > this._stack.length) | ||
return resolve(); | ||
else if(!current) | ||
return controller.emit('next', i + 1); | ||
// If the middleware is neither listening for all events nor the specified one => continue | ||
else if(current.event !== ANY_EVENT && current.event !== event) | ||
return controller.emit('next', i + 1); | ||
let passArgs = args.slice(); | ||
// If the middleware is listening for all events tell it what it's getting notified about | ||
if(current.event === ANY_EVENT) passArgs.unshift(event); | ||
const next = () => controller.emit('next', i + 1); | ||
next.throw = err => reject(err); | ||
// Push the "next" function | ||
passArgs.push(next); | ||
current.callback.apply({}, passArgs); | ||
}); | ||
// Start the snowball | ||
controller.emit('next', 0); | ||
return promise; | ||
} | ||
@@ -51,0 +105,0 @@ } |
{ | ||
"name": "exec-stack", | ||
"version": "0.1.2", | ||
"version": "1.0.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -11,46 +11,43 @@ # ExecStack [](https://badge.fury.io/js/exec-stack) | ||
```javascript | ||
var ExecStack = require('exec-stack'); | ||
const ExecStack = require('exec-stack'); | ||
``` | ||
```javascript | ||
var stack = new ExecStack(); | ||
const stack = new ExecStack(); | ||
stack.push(function(next) { | ||
console.log('This is called for every execution of the stack!'); | ||
next(); | ||
stack.use('cars', next => { | ||
console.log('I\'m specifically interested in cars'); | ||
next(); | ||
}); | ||
stack.push('event', function(next) { | ||
console.log('This is called whenever `event` is being executed!'); | ||
next(); | ||
stack.use((event, next) => { | ||
console.log('I\'m generic. Hence interested in anything, also', event); | ||
next(); | ||
}); | ||
stack.execute(); | ||
// OUTPUT: This is called for every execution of the stack! | ||
stack.run('cars'); | ||
stack.run('bikes').then(console.log('Done!')); | ||
``` | ||
stack.execute('event'); | ||
// OUTPUT: This is called for every execution of the stack! | ||
// OUTPUT: This is called whenever `event` is being executed! | ||
Output: | ||
``` | ||
I'm specifically interested in cars | ||
I'm generic. Hence interested in anything, also cars | ||
I'm generic. Hence interested in anything, also bikes | ||
Done! | ||
``` | ||
## <a name="options"></a> Options | ||
Options are passed to the constructor. | ||
### <a name="option-strict"></a> strict (*false*) | ||
If true, **only** functions subscribed to the executed event are being called by [.execute()](#method-execute). | ||
## <a name="methods"></a> Methods | ||
Optional arguments are written in *cursive*. | ||
### <a name="method-push"></a> .push(*event*, callback) | ||
Push a function on the stack. If *event* is ommited, the callback will be called for every execution of the stack. | ||
Returns the position of the item in the stack. | ||
### <a name="method-push"></a> .use(*event*, callback) | ||
Push a middleware to the stack. If *event* is ommited, the callback will be called for every execution of the stack. | ||
Returns the position of the middleware in the stack. | ||
### <a name="method-remove"></a> .remove(item) | ||
Removes a specified item from the stack. | ||
The item is being referenced by a number representing its position, just like in an array. | ||
### <a name="method-remove"></a> .unuse(position) | ||
Removes a specified middleware from the stack. | ||
The middleware is being referenced by a number representing its position in the stack. | ||
### <a name="method-execute"></a> .execute(*event*, *callback*, *context*, [...]) | ||
Execute the stack in the given context (context is set to an empty object by default). | ||
If *callback* is a function, it will be called when the stack has finished. | ||
Any other argument that is given to `.execute()` will also be passed to the functions in the stack. | ||
### <a name="method-execute"></a> .run(*event*, ...args) | ||
Any other argument that is given to `.execute()` will also be passed to the functions in the stack. | ||
Returns a promise that is being resolved after the execution |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
83
45.61%0
-100%0
-100%6140
-86.48%4
-69.23%53
-5.36%