Skip to content

Instantly share code, notes, and snippets.

@jessegrosjean
Last active December 23, 2015 01:03
Show Gist options
  • Save jessegrosjean/0db6f14c4160ca757a8c to your computer and use it in GitHub Desktop.
Save jessegrosjean/0db6f14c4160ca757a8c to your computer and use it in GitHub Desktop.
Reflux style wrapper around Flux
var copyProperties = require('react/lib/copyProperties'),
Dispatcher = require('flux').Dispatcher,
util = require('util');
function AppDispatcher() {
Dispatcher.call(this);
this._queue = [];
}
util.inherits(AppDispatcher, Dispatcher);
AppDispatcher.prototype.dispatch = function(payload) {
AppDispatcher.super_.prototype.dispatch.call(this, payload);
var queue = this._queue,
queuedPayload = queue.shift();
while (queuedPayload) {
AppDispatcher.super_.prototype.dispatch.call(this, queuedPayload);
queuedPayload = queue.shift();
}
}
AppDispatcher.prototype.queueDispatch = function(payload) {
if (this.isDispatching()) {
this._queue.push(payload);
} else {
this.dispatch(payload);
}
}
module.exports = new AppDispatcher();
var copyProperties = require('react/lib/copyProperties'),
EventEmitter = require('events').EventEmitter,
AppDispatcher = require('./AppDispatcher');
function createAction(name) {
var type = 'ACTION_' + name,
functor;
functor = function() {
AppDispatcher.dispatch({
type: type,
args: Array.prototype.slice.call(arguments)
});
};
functor.type = type;
functor.queue = function() {
AppDispatcher.queueDispatch({
type: type,
args: Array.prototype.slice.call(arguments)
});
};
return functor;
}
function createActions(actions) {
var result = {};
actions.forEach(function (each) {
result[each] = createAction(each);
});
return result;
}
function createStore(definition) {
function Store() {
var outerThis = this;
this._actionHandlers = {};
this._eventEmitter = new EventEmitter();
this.dispatchToken = AppDispatcher.register(function(action) {
var handler = outerThis._actionHandlers[action.type];
if (handler) {
handler.apply(outerThis, action.args);
}
});
this._emitAction = createAction(this.dispatchToken);
this.init();
}
Store.prototype.init = function() {
}
Store.prototype.onAction = function(action, callback) {
this._actionHandlers[action.type] = callback;
}
Store.prototype.onEmitAction = function(store, callback) {
this.onAction(store._emitAction, callback);
}
Store.prototype.waitFor = function() {
AppDispatcher.waitFor(Array.prototype.slice.call(arguments).map(function (each) {
return each.dispatchToken;
}))
}
Store.prototype.emit = function() {
var args = Array.prototype.slice.call(arguments);
this._emitAction.queue.apply(this._emitAction, args);
args.unshift('Change');
this._eventEmitter.emit.apply(this._eventEmitter, args);
}
Store.prototype.listen = function(callback) {
var outerThis = this;
this._eventEmitter.on('Change', callback);
return function () {
outerThis._eventEmitter.removeListener('Change', callback);
}
}
copyProperties(Store.prototype, definition);
return new Store();
};
module.exports = {
createAction: createAction,
createActions: createActions,
createStore: createStore
};
var Flux = require('./Flux');
var Actions = Flux.createActions([
'create',
'select',
'destroy',
...
]);
var TodoStore = Flux.createStore({
init: function() {
this._todos = {};
this._selected = null;
this.onAction(Actions.create, this.onCreate);
this.onAction(Actions.select, this.onSelect);
this.onAction(Actions.destroy, this.onDestroy);
this.onEmitAction(OtherStore, this.onOtherStoreChanged)
},
onCreate: function(text) {
var id = Date.now();
this._todos[id] = {
id: id,
complete: false,
text: text
}
Actions.select(id);
this.emit();
},
onSelect: function(id) {
this._selected = id;
this.emit();
},
onDestroy: function(id) {
delete this._todos[id];
if (id === this._selected) {
this._selected = null;
}
this.emit();
},
onWaitForExample: function(data) {
this.waitFor(OtherStore1, OtherStore2);
...
},
onOtherStoreChanged: function() {
...
}
});
// Later...
Actions.create('Hello world!');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment