Comparing version 5.0.3 to 5.0.4
269
index.js
@@ -1,206 +0,145 @@ | ||
/** | ||
* Module dependences | ||
*/ | ||
const debug = require('debug')('barracks') | ||
const assert = require('assertf') | ||
const series = require('run-series') | ||
var debug = require('debug')('barracks'); | ||
var assert = require('assertf'); | ||
var async = require('async'); | ||
module.exports = Dispatcher | ||
/** | ||
* Exports | ||
*/ | ||
// initialize the dispatcher with actions | ||
// obj -> fn | ||
function Dispatcher (actions) { | ||
if (!(this instanceof Dispatcher)) return new Dispatcher(actions) | ||
module.exports = Dispatcher; | ||
assert(actions, "an 'actions' object should be passed as an argument") | ||
assert.equal(typeof actions, 'object', 'actions should be an object') | ||
_assertActionsObject(actions) | ||
/** | ||
* Dispatcher prototype | ||
*/ | ||
this.locals = {} | ||
this.payload = null | ||
var dispatcher = Dispatcher.prototype; | ||
this._current = [] | ||
this._isPending = {} | ||
this._isHandled = {} | ||
this._actions = actions | ||
this._isDispatching = false | ||
/** | ||
* Initialize the dispatcher with an | ||
* 'actions' object. | ||
* | ||
* @return {Object} | ||
* @api public | ||
*/ | ||
return this.dispatch.bind(this) | ||
} | ||
function Dispatcher(actions) { | ||
// dispatch event to stores | ||
// str, obj|[obj] -> fn | ||
Dispatcher.prototype.dispatch = function (action, payload) { | ||
assert.equal(typeof action, 'string', "action '%s' should be a string", action) | ||
assert(!this._isDispatching, "cannot dispatch '%s' in the middle of a dispatch", action) | ||
if (!(this instanceof Dispatcher)) return new Dispatcher(actions); | ||
this._current.push(action) | ||
this._isDispatching = true | ||
assert(actions, 'an \'actions\' object should be passed as an argument'); | ||
assert.equal(typeof actions, 'object', 'actions should be an object'); | ||
_assertActionsObject(actions); | ||
this._isPending = {} | ||
this._isPending[action] = true | ||
this.locals = {}; | ||
this.payload = null; | ||
this._isHandled = {} | ||
this._isHandled[action] = false | ||
this._current = []; | ||
this._isPending = {}; | ||
this._isHandled = {}; | ||
this._actions = actions; | ||
this._isDispatching = false; | ||
this.locals = {} | ||
this.payload = payload | ||
return this.dispatch.bind(this); | ||
}; | ||
/** | ||
* Dispatch event to stores. | ||
* | ||
* @param {String} action | ||
* @param {Object | Object[]} data | ||
* @return {Function[]} | ||
* @api public | ||
*/ | ||
dispatcher.dispatch = function(action, payload) { | ||
assert.equal(typeof action, 'string', 'action \'%s\' should be a string', action); | ||
assert(!this._isDispatching, 'cannot dispatch \'%s\' in the middle of a dispatch', action); | ||
this._current.push(action); | ||
this._isDispatching = true; | ||
this._isPending = {}; | ||
this._isPending[action] = true; | ||
this._isHandled = {}; | ||
this._isHandled[action] = false; | ||
this.locals = {}; | ||
this.payload = payload; | ||
try { | ||
var fn = _getAction.call(this, action); | ||
var fn = _getAction.call(this, action) | ||
} catch (e) { | ||
_stopDispatching.call(this); | ||
throw e; | ||
_stopDispatching.call(this) | ||
throw e | ||
} | ||
debug('dispatch \'%s\'', action); | ||
fn.call(this, _stopDispatching.bind(this)); | ||
}; | ||
debug("dispatch '%s'", action) | ||
fn.call(this, _stopDispatching.bind(this)) | ||
} | ||
/** | ||
* Expose a delegation method to the registered actions. Calls `async.series()` | ||
* under the hood. Sets a 'pending' state to | ||
* | ||
* @param {String[] |} ids | ||
* @param {Function} done | ||
* @api public | ||
*/ | ||
// expose a delegation method to the registered | ||
// actions. Calls `run-series()` under the hood | ||
// str|[str], fn -> null | ||
Dispatcher.prototype.waitFor = function (actions, done) { | ||
done = done || function () {} | ||
assert.equal(typeof done, 'function', 'callback should be a function') | ||
dispatcher.waitFor = function(actions, done) { | ||
done = done || function() {}; | ||
assert.equal(typeof done, 'function', 'callback should be a function'); | ||
actions = Array.isArray(actions) ? actions : [actions] | ||
const ctx = this | ||
actions = Array.isArray(actions) ? actions : [actions]; | ||
const arr = actions.map(function (action) { | ||
const fn = _getAction.call(ctx, action) | ||
const nwFn = _thunkify.call(ctx, fn, action) | ||
return nwFn.bind(ctx) | ||
}) | ||
var arr = actions.map(function(action) { | ||
const nwArr = arr.concat(done.bind(this)) | ||
series(nwArr) | ||
} | ||
var fn = _getAction.call(this, action); | ||
var nwFn = _thunkify.call(this, fn, action); | ||
return nwFn.bind(this); | ||
}.bind(this)); | ||
var nwArr = arr.concat(done.bind(this)); | ||
async.series(nwArr); | ||
}; | ||
/** | ||
* Deep assert if the passed actions object is correct. | ||
* | ||
* @param {Object} actions | ||
* @api private | ||
*/ | ||
function _assertActionsObject(actions) { | ||
Object.keys(actions).forEach(function(key) { | ||
var action = actions[key]; | ||
if ('object' == typeof action) return _assertActionsObject(action); | ||
assert.equal(typeof action, 'function', 'action should be a function'); | ||
}); | ||
// deep assert the actions object | ||
// obj -> null | ||
function _assertActionsObject (actions) { | ||
Object.keys(actions).forEach(function (key) { | ||
const action = actions[key] | ||
if (typeof action === 'object') return _assertActionsObject(action) | ||
assert.equal(typeof action, 'function', 'action should be a function') | ||
}) | ||
} | ||
/** | ||
* Thunkify a function to properly set | ||
* `this._isHandled[action] = true` when | ||
* done executing. | ||
* | ||
* @param {Function} fn | ||
* @param {Function} isHandled | ||
* @return {Function} | ||
*/ | ||
function _thunkify(fn, action) { | ||
return function(done) { | ||
// wrap function to set | ||
// `this._isHandled[action]` on end | ||
// fn, fn -> fn | ||
function _thunkify (fn, action) { | ||
return function (done) { | ||
try { | ||
assert.equal(typeof action, 'string', '.waitFor(): requires a string or array of strings'); | ||
assert.equal(typeof action, 'string', '.waitFor(): requires a string or array of strings') | ||
if (this._isPending[action]) { | ||
assert(this._isHandled[action], 'circular dependency detected while waiting for \'%s\'', action); | ||
assert(this._isHandled[action], "circular dependency detected while waiting for '%s'", action) | ||
} | ||
} catch(e) { | ||
_stopDispatching.call(this); | ||
throw e; | ||
_stopDispatching.call(this) | ||
throw e | ||
} | ||
this._isPending[action] = true; | ||
this._isHandled[action] = false; | ||
this._isPending[action] = true | ||
this._isHandled[action] = false | ||
function fin() { | ||
this._current.pop(); | ||
this._isHandled[action] = true; | ||
done(); | ||
function fin () { | ||
this._current.pop() | ||
this._isHandled[action] = true | ||
done() | ||
} | ||
this._current.push(action); | ||
debug('\'%s\' -> \'%s\'', this._current[this._current.length - 2], action); | ||
fn(fin.bind(this)); | ||
this._current.push(action) | ||
debug("'%s' -> '%s'", this._current[this._current.length - 2], action) | ||
fn(fin.bind(this)) | ||
} | ||
} | ||
/** | ||
* Get the dispatched action. Traverses the call stack | ||
* recursively until a function is found. | ||
* | ||
* @param {String[]} arr | ||
* @param {String} action | ||
* @return {Function} | ||
* @api private | ||
*/ | ||
// get the dispatched action recursively | ||
// [str], str -> fn | ||
function _getAction (action, arr, index) { | ||
arr = arr || action.split('_') | ||
index = index || 0 | ||
const val = arr[index] | ||
function _getAction(action, arr, index) { | ||
arr = arr || action.split('_'); | ||
index = index || 0; | ||
var val = arr[index]; | ||
if (typeof val === 'object') return _getAction.call(this, action, arr, index++) | ||
if ('object' == typeof val) return _getAction.call(this, action, arr, index++); | ||
var fn = this._actions | ||
arr.forEach(function (obj, i) { | ||
assert(fn[arr[i]], "action '%s' is not registered", action) | ||
fn = fn[arr[i]] | ||
}) | ||
var fn = this._actions; | ||
arr.forEach(function(obj, i) { | ||
assert(fn[arr[i]], 'action \'%s\' is not registered', action); | ||
fn = fn[arr[i]]; | ||
}.bind(this)); | ||
assert.equal(typeof fn, 'function', 'action \'%s\' is not registered', action); | ||
return fn.bind(this); | ||
assert.equal(typeof fn, 'function', "action '%s' is not registered", action) | ||
return fn.bind(this) | ||
} | ||
/** | ||
* Clear bookkeeping. | ||
* | ||
* @api private | ||
*/ | ||
function _stopDispatching() { | ||
this._isDispatching = false; | ||
this._isPending = {}; | ||
this._isHandled = {}; | ||
this.payload = null; | ||
this._current = []; | ||
this.locals = {}; | ||
// reset internal state | ||
// null -> null | ||
function _stopDispatching () { | ||
this._isDispatching = false | ||
this._isPending = {} | ||
this._isHandled = {} | ||
this.payload = null | ||
this._current = [] | ||
this.locals = {} | ||
} |
{ | ||
"name": "barracks", | ||
"version": "5.0.3", | ||
"version": "5.0.4", | ||
"description": "An event dispatcher for the flux architecture", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "make test" | ||
"lint": "eslint .", | ||
"test": "NODE_ENV=test node test | colortape", | ||
"test-cov": "NODE_ENV=test istanbul cover test.js" | ||
}, | ||
"repository": "yoshuawuyts/barracks", | ||
"keywords": [ | ||
"react-component", | ||
"dispatcher", | ||
"flux", | ||
"react" | ||
"react", | ||
"react-component" | ||
], | ||
"license": "MIT", | ||
"devDependencies": { | ||
"colortape": "^0.1.1", | ||
"coveralls": "~2.10.0", | ||
"eslint": "^0.11.0", | ||
"istanbul": "~0.2.10", | ||
"make-lint": "^1.0.1", | ||
"mocha": "~1.19.0", | ||
"should": "~3.3.2" | ||
"tape": "^3.0.3" | ||
}, | ||
"dependencies": { | ||
"assertf": "^1.0.0", | ||
"async": "^0.9.0", | ||
"debug": "^2.0.0" | ||
"debug": "^2.0.0", | ||
"run-series": "^1.1.2" | ||
}, | ||
"files": [ | ||
"index.js", | ||
"HISTORY.md", | ||
"LICENSE", | ||
"HISTORY.md" | ||
"index.js" | ||
] | ||
} |
104
README.md
@@ -41,2 +41,3 @@ # barracks | ||
} | ||
}, | ||
courses: { | ||
@@ -62,4 +63,3 @@ get: function(next) { | ||
#### dispatcher = barracks(actions) | ||
Initialize a new `barracks` instance. The `actions` object should contain | ||
functions, namespaced at most one level deep. Returns a function. | ||
Initialize a new `barracks` instance. Returns a function. | ||
```js | ||
@@ -107,55 +107,38 @@ // Initialize without namespaces. | ||
call `this.waitFor` to access the function from within a registered callback. | ||
In the example below `users_initalize` will delegate execution to `user_add` and | ||
`user_listen` before proceeding to execute its own code. | ||
```js | ||
var userStore = require('simple-store')('user'); | ||
var socket = require('sockjs-client'); | ||
var request = require('request'); | ||
// Initialize dispatcher. | ||
var dispatcher = barracks({ | ||
users: { | ||
initialize: function(next) { | ||
var arr = ['user_add', 'user_listen']; | ||
this.waitFor(arr, function() { | ||
console.log('initialized'); | ||
next(); | ||
}); | ||
}, | ||
add: function(next) { | ||
request('myapi.co/api/users', function(err, res) { | ||
userStore.set(res); | ||
next(); | ||
}); | ||
}, | ||
listen: function(next) { | ||
var sock = new socket('myapi.co/api/socket'); | ||
sock.onMessage(console.log); | ||
init: function(next) { | ||
console.log('1'); | ||
this.waitFor(['add', 'listen'], function() { | ||
console.log('4'); | ||
next(); | ||
} | ||
}); | ||
}, | ||
add: function(next) { | ||
setTimeout(function() { | ||
console.log('2'); | ||
done(); | ||
}, 10); | ||
}, | ||
listen: function(next) { | ||
console.log('3'); | ||
next(); | ||
} | ||
}); | ||
// Initialize the users store. | ||
dispatcher('users_initialize'); | ||
dispatcher('init'); | ||
// => 1 2 3 | ||
``` | ||
#### ctx.payload | ||
`ctx.payload` contains the data provided by `dispatcher()`. | ||
`this.payload` contains the data provided by `dispatcher()`. | ||
```js | ||
var dispatcher = barracks({ | ||
users: { | ||
init: function(next) { | ||
console.log(this.payload); | ||
} | ||
init: function(next) { | ||
console.log(this.payload); | ||
} | ||
}); | ||
// Initialize the users store. | ||
dispatcher('users_init', 'fooBar'); | ||
// -> console.log: 'fooBar' | ||
dispatcher('init', 'fooBar'); | ||
// => 'fooBar' | ||
``` | ||
@@ -170,31 +153,18 @@ | ||
```js | ||
var request = require('request'); | ||
// Initialize dispatcher. | ||
var dispatcher = barracks({ | ||
users: { | ||
add: function(next) { | ||
request('myapi.co/api/auth', function(err, res) { | ||
this.locals.token = res.token; | ||
next(); | ||
}); | ||
}, | ||
fetch: function(next) { | ||
this.waitFor(['user_add'], function() { | ||
var url = 'myapi.co/me?token=' + this.locals.token; | ||
request(url, handleRequest); | ||
}); | ||
function handleRequest(err, res) { | ||
console.log(res); | ||
next(); | ||
} | ||
} | ||
add: function(next) { | ||
this.locals.token = 'asdf12345'; | ||
next(); | ||
}); | ||
}, | ||
fetch: function(next) { | ||
this.waitFor(['add'], function() { | ||
console.log(this.locals.token); | ||
next(); | ||
}); | ||
} | ||
}); | ||
// Get user data from server. | ||
dispatcher('user_fetch'); | ||
dispatcher('fetch'); | ||
// => 'asdf12345' | ||
``` | ||
@@ -207,3 +177,3 @@ | ||
[npm-url]: https://npmjs.org/package/barracks | ||
[travis-image]: https://img.shields.io/travis/yoshuawuyts/barracks.svg?style=flat-square | ||
[travis-image]: https://img.shields.io/travis/yoshuawuyts/barracks/master.svg?style=flat-square | ||
[travis-url]: https://travis-ci.org/yoshuawuyts/barracks | ||
@@ -210,0 +180,0 @@ [coveralls-image]: https://img.shields.io/coveralls/yoshuawuyts/barracks.svg?style=flat-square |
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
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
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
30
10944
6
4
118
182
1
+ Addedrun-series@^1.1.2
+ Addedrun-series@1.1.9(transitive)
- Removedasync@^0.9.0
- Removedasync@0.9.2(transitive)