Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dispatchr

Package Overview
Dependencies
Maintainers
4
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dispatchr - npm Package Compare versions

Comparing version 0.0.12 to 0.1.0

525

lib/dispatcher.js

@@ -7,299 +7,302 @@ /**

var Promise = global.Promise || require('es6-promise').Promise,
debug = require('debug')('Dispatchr:dispatcher');
var Promise = global.Promise || require('es6-promise').Promise;
/**
* @class Dispatcher
* @param {Object} context The context to be used for store instances
* @constructor
*/
function Dispatcher (context) {
this.context = context || {};
this.storeInstances = {};
this.currentAction = null;
this.actionQueue = [];
}
module.exports = function () {
var debug = require('debug')('Dispatchr:dispatcher');
Dispatcher.stores = {};
Dispatcher.handlers = {};
/**
* Registers a store so that it can handle actions.
* @method registerStore
* @static
* @param {Object} store A store class to be registered. The store should have a static
* `name` property so that it can be loaded later.
*/
Dispatcher.registerStore = function (store) {
var storeName = Dispatcher.getStoreName(store);
if (!storeName) {
throw new Error('Store is required to have a `storeName` property.');
/**
* @class Dispatcher
* @param {Object} context The context to be used for store instances
* @constructor
*/
function Dispatcher (context) {
this.context = context || {};
this.storeInstances = {};
this.currentAction = null;
this.actionQueue = [];
}
if (Dispatcher.stores[storeName]) {
throw new Error('Store `' + storeName + '` is already registerd.');
}
Dispatcher.stores[storeName] = store;
if (store.handlers) {
Object.keys(store.handlers).forEach(function (action) {
var handler = store.handlers[action];
Dispatcher.registerHandler(action, storeName, handler);
});
}
return Dispatcher.stores[storeName];
};
/**
* Method to discover if a storeName has been registered
* @param {Object|String} store The store to check
* @returns {boolean}
*/
Dispatcher.isRegistered = function (store) {
var storeName = Dispatcher.getStoreName(store),
storeInstance = Dispatcher.stores[storeName];
Dispatcher.stores = {};
Dispatcher.handlers = {};
if (!storeInstance) {
return false;
}
/**
* Registers a store so that it can handle actions.
* @method registerStore
* @static
* @param {Object} store A store class to be registered. The store should have a static
* `name` property so that it can be loaded later.
*/
Dispatcher.registerStore = function (store) {
var storeName = Dispatcher.getStoreName(store);
if (!storeName) {
throw new Error('Store is required to have a `storeName` property.');
}
if (Dispatcher.stores[storeName]) {
throw new Error('Store `' + storeName + '` is already registerd.');
}
Dispatcher.stores[storeName] = store;
if (store.handlers) {
Object.keys(store.handlers).forEach(function (action) {
var handler = store.handlers[action];
Dispatcher.registerHandler(action, storeName, handler);
});
}
return Dispatcher.stores[storeName];
};
if ('function' === typeof store) {
if (store !== storeInstance) {
/**
* Method to discover if a storeName has been registered
* @param {Object|String} store The store to check
* @returns {boolean}
*/
Dispatcher.isRegistered = function (store) {
var storeName = Dispatcher.getStoreName(store),
storeInstance = Dispatcher.stores[storeName];
if (!storeInstance) {
return false;
}
}
return true;
};
/**
* Gets a name from a store
* @param {String|Object} store The store name or class from which to extract
* the name
* @returns {String}
*/
Dispatcher.getStoreName = function (store) {
if ('string' === typeof store) {
return store;
}
return store.storeName;
};
if ('function' === typeof store) {
if (store !== storeInstance) {
return false;
}
}
return true;
};
/**
* Adds a handler function to be called for the given action
* @method registerHandler
* @private
* @static
* @param {String} action Name of the action
* @param {String} name Name of the store that handles the action
* @param {String} handler Name of the function that handles the action
* @returns {number}
*/
Dispatcher.registerHandler = function (action, name, handler) {
Dispatcher.handlers[action] = Dispatcher.handlers[action] || [];
Dispatcher.handlers[action].push({
name: Dispatcher.getStoreName(name),
handler: handler
});
return Dispatcher.handlers.length - 1;
};
/**
* Gets a name from a store
* @param {String|Object} store The store name or class from which to extract
* the name
* @returns {String}
*/
Dispatcher.getStoreName = function (store) {
if ('string' === typeof store) {
return store;
}
return store.storeName;
};
/**
* Returns a single store instance and creates one if it doesn't already exist
* @method getStore
* @param {String} name The name of the instance
* @param {Object} initialState Initial state of the store used for rehydration
* @returns {Object} The store instance
*/
Dispatcher.prototype.getStore = function (name, initialState) {
var storeName = Dispatcher.getStoreName(name);
if (!this.storeInstances[storeName]) {
var Store = Dispatcher.stores[storeName];
if (!Store) {
throw new Error('Store ' + storeName + ' was not registered.');
/**
* Adds a handler function to be called for the given action
* @method registerHandler
* @private
* @static
* @param {String} action Name of the action
* @param {String} name Name of the store that handles the action
* @param {String} handler Name of the function that handles the action
* @returns {number}
*/
Dispatcher.registerHandler = function (action, name, handler) {
Dispatcher.handlers[action] = Dispatcher.handlers[action] || [];
Dispatcher.handlers[action].push({
name: Dispatcher.getStoreName(name),
handler: handler
});
return Dispatcher.handlers.length - 1;
};
/**
* Returns a single store instance and creates one if it doesn't already exist
* @method getStore
* @param {String} name The name of the instance
* @param {Object} initialState Initial state of the store used for rehydration
* @returns {Object} The store instance
*/
Dispatcher.prototype.getStore = function (name, initialState) {
var storeName = Dispatcher.getStoreName(name);
if (!this.storeInstances[storeName]) {
var Store = Dispatcher.stores[storeName];
if (!Store) {
throw new Error('Store ' + storeName + ' was not registered.');
}
this.storeInstances[storeName] = new (Dispatcher.stores[storeName])(this.context, initialState);
if (this.storeInstances[storeName].setDispatcher) {
this.storeInstances[storeName].setDispatcher(this);
}
}
this.storeInstances[storeName] = new (Dispatcher.stores[storeName])(this.context, initialState);
if (this.storeInstances[storeName].setDispatcher) {
this.storeInstances[storeName].setDispatcher(this);
return this.storeInstances[storeName];
};
/**
* Dispatches a new action or queues it up if one is already in progress
* @method dispatch
* @param {String} actionName Name of the action to be dispatched
* @param {Object} payload Parameters to describe the action
* @param {Function} callback Function to be called upon completion of
* the action.
*/
Dispatcher.prototype.dispatch = function (actionName, payload, callback) {
if (!Dispatcher.handlers[actionName]) {
setImmediate(callback);
return;
}
}
return this.storeInstances[storeName];
};
/**
* Dispatches a new action or queues it up if one is already in progress
* @method dispatch
* @param {String} actionName Name of the action to be dispatched
* @param {Object} payload Parameters to describe the action
* @param {Function} callback Function to be called upon completion of
* the action.
*/
Dispatcher.prototype.dispatch = function (actionName, payload, callback) {
if (!Dispatcher.handlers[actionName]) {
setImmediate(callback);
return;
}
this.actionQueue.push({
name: actionName,
payload: payload,
callback: callback,
actionPromise: null,
handlerPromises: {},
waiting: {}
});
debug('action ' + actionName + ' added to queue');
return this.next();
};
this.actionQueue.push({
name: actionName,
payload: payload,
callback: callback,
actionPromise: null,
handlerPromises: {},
waiting: {}
});
debug('action ' + actionName + ' added to queue');
return this.next();
};
/**
* Handles the next Action in the queue if another Action is not in progress
* @method next
* @private
* @returns {Object}
*/
Dispatcher.prototype.next = function () {
if (this.currentAction) {
return this.currentAction;
}
/**
* Handles the next Action in the queue if another Action is not in progress
* @method next
* @private
* @returns {Object}
*/
Dispatcher.prototype.next = function () {
if (this.currentAction) {
return this.currentAction;
}
var self = this,
nextAction = self.actionQueue.shift();
var self = this,
nextAction = self.actionQueue.shift();
if (nextAction) {
self.currentAction = nextAction;
if (nextAction) {
self.currentAction = nextAction;
var actionPromise = self.handleAction(nextAction);
actionPromise.then(function (result) {
debug('finished ' + nextAction.name);
self.currentAction = null;
if (nextAction.callback) {
setImmediate(function () {
nextAction.callback(null, result);
});
}
setImmediate(self.next.bind(self));
})['catch'](function (err) {
debug('finished with error ' + nextAction.name);
self.currentAction = null;
if (nextAction.callback) {
setImmediate(function () {
nextAction.callback(err);
});
}
setImmediate(self.next.bind(self));
});
}
var actionPromise = self.handleAction(nextAction);
actionPromise.then(function (result) {
debug('finished ' + nextAction.name);
self.currentAction = null;
if (nextAction.callback) {
setImmediate(function () {
nextAction.callback(null, result);
});
}
setImmediate(self.next.bind(self));
})['catch'](function (err) {
debug('finished with error ' + nextAction.name);
self.currentAction = null;
if (nextAction.callback) {
setImmediate(function () {
nextAction.callback(err);
});
}
setImmediate(self.next.bind(self));
});
}
return self.currentAction;
};
return self.currentAction;
};
/**
* Calls the handler functions for all stores that have registered for
* the given event.
* @method handleAction
* @private
* @param {Object} action Action object
* @param {String} action.name Name of the action to be handled
* @param {Object} action.payload Parameters to describe the action
* @returns {Promise}
*/
Dispatcher.prototype.handleAction = function (action) {
var self = this,
name = action.name,
payload = action.payload,
handlerPromises = [];
/**
* Calls the handler functions for all stores that have registered for
* the given event.
* @method handleAction
* @private
* @param {Object} action Action object
* @param {String} action.name Name of the action to be handled
* @param {Object} action.payload Parameters to describe the action
* @returns {Promise}
*/
Dispatcher.prototype.handleAction = function (action) {
var self = this,
name = action.name,
payload = action.payload,
handlerPromises = [];
debug('handling ' + name);
Dispatcher.handlers[name].forEach(function (store) {
var handlerPromise = new Promise(function(resolve, reject) {
var storeInstance = self.getStore(store.name);
debug('handling ' + name);
Dispatcher.handlers[name].forEach(function (store) {
var handlerPromise = new Promise(function(resolve, reject) {
var storeInstance = self.getStore(store.name);
setImmediate(function () {
storeInstance[store.handler](payload, function storeHandlerDone(err) {
if (err) {
reject(err);
return;
}
resolve();
setImmediate(function () {
storeInstance[store.handler](payload, function storeHandlerDone(err) {
if (err) {
reject(err);
return;
}
resolve();
});
});
});
handlerPromises.push(handlerPromise);
action.handlerPromises[store.name] = handlerPromise;
});
handlerPromises.push(handlerPromise);
action.handlerPromises[store.name] = handlerPromise;
});
return Promise.all(handlerPromises);
};
return Promise.all(handlerPromises);
};
/**
* Waits until all stores have finished handling an actionand then calls
* the callback
* @param {String|Array} stores An array of stores as strings to wait for
* @param {Function} callback Called after all stores have completed handling their actions
*/
Dispatcher.prototype.waitFor = function (stores, callback) {
var currentAction = this.currentAction,
waitHandlers = [];
/**
* Waits until all stores have finished handling an actionand then calls
* the callback
* @param {String|Array} stores An array of stores as strings to wait for
* @param {Function} callback Called after all stores have completed handling their actions
*/
Dispatcher.prototype.waitFor = function (stores, callback) {
var currentAction = this.currentAction,
waitHandlers = [];
if (!currentAction) {
throw new Error('waitFor called even though there is no action being handled!');
}
if (!currentAction) {
throw new Error('waitFor called even though there is no action being handled!');
}
if (!Array.isArray(stores)) {
stores = [stores];
}
stores.forEach(function (store) {
var storeName = Dispatcher.getStoreName(store),
actionHandler = currentAction.handlerPromises[storeName];
if (actionHandler) {
waitHandlers.push(actionHandler);
if (!Array.isArray(stores)) {
stores = [stores];
}
});
Promise.all(waitHandlers).then(function (result) {
setImmediate(function () {
callback(null, result);
stores.forEach(function (store) {
var storeName = Dispatcher.getStoreName(store),
actionHandler = currentAction.handlerPromises[storeName];
if (actionHandler) {
waitHandlers.push(actionHandler);
}
});
})['catch'](function (err) {
callback(err);
});
};
/**
* Returns a raw data object representation of the current state of the
* dispatcher and all store instances
* @returns {Object} dehydrated dispatcher data
*/
Dispatcher.prototype.toJSON = function () {
var self = this,
stores = {};
Object.keys(self.storeInstances).forEach(function (storeName) {
var store = self.storeInstances[storeName];
if (store.toJSON) {
stores[storeName] = store.toJSON();
} else {
stores[storeName] = store.getState();
Promise.all(waitHandlers).then(function (result) {
setImmediate(function () {
callback(null, result);
});
})['catch'](function (err) {
callback(err);
});
};
/**
* Returns a raw data object representation of the current state of the
* dispatcher and all store instances
* @returns {Object} dehydrated dispatcher data
*/
Dispatcher.prototype.toJSON = function () {
var self = this,
stores = {};
Object.keys(self.storeInstances).forEach(function (storeName) {
var store = self.storeInstances[storeName];
if (store.toJSON) {
stores[storeName] = store.toJSON();
} else {
stores[storeName] = store.getState();
}
});
return {
context: self.context,
stores: stores
};
};
/**
* Takes a raw data object and rehydrates the dispatcher and store instances
* @param {Object} dispatcherState raw state typically retrieved from `toJSON`
* method
*/
Dispatcher.prototype.rehydrate = function (dispatcherState) {
var self = this;
self.context = dispatcherState.context || {};
if (dispatcherState.stores) {
Object.keys(dispatcherState.stores).forEach(function (storeName) {
var state = dispatcherState.stores[storeName];
self.getStore(storeName, state);
});
}
});
return {
context: self.context,
stores: stores
};
};
/**
* Takes a raw data object and rehydrates the dispatcher and store instances
* @param {Object} dispatcherState raw state typically retrieved from `toJSON`
* method
*/
Dispatcher.prototype.rehydrate = function (dispatcherState) {
var self = this;
self.context = dispatcherState.context || {};
if (dispatcherState.stores) {
Object.keys(dispatcherState.stores).forEach(function (storeName) {
var state = dispatcherState.stores[storeName];
self.getStore(storeName, state);
});
}
return Dispatcher;
};
module.exports = Dispatcher;
{
"name": "dispatchr",
"version": "0.0.12",
"version": "0.1.0",
"description": "A Flux dispatcher for applications that run on the server and the client.",

@@ -8,3 +8,3 @@ "main": "index.js",

"type": "git",
"url": "git://github.com/ouchtown/dispatchr.git"
"url": "git://github.com/yahoo/dispatchr.git"
},

@@ -20,3 +20,3 @@ "scripts": {

"type": "BSD",
"url": "https://github.com/ouchtown/dispatchr/blob/master/LICENSE.md"
"url": "https://github.com/yahoo/dispatchr/blob/master/LICENSE.md"
}

@@ -39,2 +39,3 @@ ],

"keywords": [
"yahoo",
"flux",

@@ -41,0 +42,0 @@ "react",

@@ -1,2 +0,2 @@

# Dispatchr [![Build Status](https://travis-ci.org/ouchtown/dispatchr.svg?branch=master)](https://travis-ci.org/ouchtown/dispatchr) [![Dependency Status](https://david-dm.org/ouchtown/dispatchr.svg)](https://david-dm.org/ouchtown/dispatchr)
# Dispatchr [![Build Status](https://travis-ci.org/yahoo/dispatchr.svg?branch=master)](https://travis-ci.org/yahoo/dispatchr) [![Dependency Status](https://david-dm.org/yahoo/dispatchr.svg)](https://david-dm.org/yahoo/dispatchr)

@@ -7,6 +7,6 @@ A [Flux](http://facebook.github.io/react/docs/flux-overview.html) dispatcher for applications that run on the server and the client.

For a more detailed example, see our [example application](https://github.com/ouchtown/flux-example).
For a more detailed example, see our [example application](https://github.com/yahoo/flux-example).
```js
var Dispatchr = require('dispatchr'),
var Dispatchr = require('dispatchr')(),
ExampleStore = require('./example-store.js'),

@@ -149,2 +149,2 @@ context = {};

[LICENSE file]: https://github.com/ouchtown/dispatchr/blob/master/LICENSE.md
[LICENSE file]: https://github.com/yahoo/dispatchr/blob/master/LICENSE.md

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc