delorean.js
Advanced tools
Comparing version 0.4.10 to 0.5.0
{ | ||
"name": "delorean.js", | ||
"version": "0.4.10", | ||
"version": "0.5.0", | ||
"homepage": "http://deloreanjs.com", | ||
@@ -25,3 +25,2 @@ "authors": [ | ||
"tests", | ||
"**/*.coffee", | ||
"src", | ||
@@ -28,0 +27,0 @@ "example" |
@@ -1,13 +0,269 @@ | ||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.DeLorean=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
/*! delorean.js - v0.4.9 - 2014-08-25 */ | ||
(function (DeLorean) { | ||
'use strict'; | ||
// Helper functions | ||
function _generateActionName(name) { | ||
return "action:" + name; | ||
} | ||
function _hasOwn(object, prop) { | ||
return Object.prototype.hasOwnProperty.call(object, prop); | ||
} | ||
function _argsShift(args, from) { | ||
return Array.prototype.slice.call(args, from); | ||
} | ||
// Dispatcher | ||
var Dispatcher = (function () { | ||
function Dispatcher(stores) { | ||
var self = this; | ||
this.listener = new DeLorean.EventEmitter(); | ||
this.stores = stores; | ||
} | ||
Dispatcher.prototype.dispatch = function (actionName, data) { | ||
var self = this; | ||
var stores = (function () { | ||
var stores = []; | ||
for (var storeName in self.stores) { | ||
var store = self.stores[storeName]; | ||
if (!store instanceof Store) { | ||
throw 'Given store is not a store instance'; | ||
} | ||
stores.push(store); | ||
} | ||
return stores; | ||
}()); | ||
var deferred = this.waitFor(stores); | ||
for (var storeName in self.stores) { | ||
self.stores[storeName].dispatchAction(actionName, data); | ||
}; | ||
return deferred; | ||
}; | ||
Dispatcher.prototype.waitFor = function (stores) { | ||
var self = this; | ||
var promises = (function () { | ||
var _promises = []; | ||
for (var i in stores) { | ||
var promise = (function (store) { | ||
return new DeLorean.Promise(function (resolve, reject) { | ||
store.listener.once('change', resolve); | ||
}); | ||
})(stores[i]); | ||
_promises.push(promise); | ||
} | ||
return _promises; | ||
}()); | ||
return DeLorean.Promise.all(promises).then(function () { | ||
self.listener.emit('change:all'); | ||
}); | ||
}; | ||
Dispatcher.prototype.registerAction = function (action, callback) { | ||
if (typeof callback === 'function') { | ||
this[action] = callback.bind(this.stores); | ||
} else { | ||
throw 'Action callback should be a function.' | ||
} | ||
}; | ||
Dispatcher.prototype.on = function () { | ||
return this.listener.on.apply(this.listener, arguments); | ||
}; | ||
Dispatcher.prototype.off = function () { | ||
return this.listener.removeListener.apply(this.listener, arguments); | ||
}; | ||
return Dispatcher; | ||
}()); | ||
// Store | ||
var Store = (function () { | ||
function Store(store) { | ||
if (typeof store !== 'object') { | ||
throw 'Stores should be defined by passing the definition to the constructor'; | ||
} | ||
this.listener = new DeLorean.EventEmitter(); | ||
this.store = store; | ||
this.bindActions(); | ||
if (typeof store.initialize === 'function') { | ||
var args = _argsShift(arguments, 1); | ||
store.initialize.apply(this.store, args); | ||
} | ||
} | ||
Store.prototype.bindActions = function () { | ||
this.store.emit = this.listener.emit.bind(this.listener); | ||
this.store.listenChanges = this.listenChanges.bind(this); | ||
for (var actionName in this.store.actions) { | ||
if (_hasOwn(this.store.actions, actionName)) { | ||
var callback = this.store.actions[actionName]; | ||
if (typeof this.store[callback] !== 'function') { | ||
throw 'Callback should be a method!'; | ||
} | ||
this.listener.on(_generateActionName(actionName), | ||
this.store[callback].bind(this.store)); | ||
} | ||
} | ||
}; | ||
Store.prototype.dispatchAction = function (actionName, data) { | ||
this.listener.emit(_generateActionName(actionName) , data) | ||
}; | ||
Store.prototype.onChange = function (callback) { | ||
this.listener.on('change', callback); | ||
}; | ||
Store.prototype.listenChanges = function (object) { | ||
if (!Object.observe) { | ||
console.error('Store#listenChanges method uses Object.observe, you should fire changes manually.'); | ||
return; | ||
} | ||
var self = this; | ||
var observer = Array.isArray(object) ? Array.observe : Object.observe; | ||
observer(object, function () { | ||
self.listener.emit('change'); | ||
}); | ||
}; | ||
return Store; | ||
}()); | ||
// Flux | ||
DeLorean.Flux = { | ||
createStore: function (factoryDefinition) { | ||
return function () { | ||
return new Store(factoryDefinition); | ||
} | ||
}, | ||
createDispatcher: function (actionsToDispatch) { | ||
if (typeof actionsToDispatch.getStores === 'function') { | ||
var actionsOfStores = actionsToDispatch.getStores(); | ||
} | ||
var dispatcher = new Dispatcher(actionsOfStores || {}); | ||
for (var actionName in actionsToDispatch) { | ||
if (_hasOwn(actionsToDispatch, actionName)) { | ||
if (actionName !== 'getStores') { | ||
var callback = actionsToDispatch[actionName]; | ||
dispatcher.registerAction(actionName, callback.bind(dispatcher)); | ||
} | ||
} | ||
} | ||
return dispatcher; | ||
}, | ||
// Helper | ||
define: function (key, value) { | ||
DeLorean[key] = value; | ||
} | ||
}; | ||
// Module Registration | ||
DeLorean.Dispatcher = Dispatcher; | ||
DeLorean.Store = Store; | ||
// React Mixin | ||
DeLorean.Flux.mixins = { | ||
// It should be inserted to the React components which | ||
// used in Flux. | ||
// Simply `mixin: [Flux.mixins.storeListener]` will work. | ||
storeListener: { | ||
// After the component mounted, listen changes of the related stores | ||
componentDidMount: function () { | ||
var self = this; | ||
for (var storeName in this.stores) { | ||
if (_hasOwn(this.stores, storeName)) { | ||
var store = this.stores[storeName]; | ||
store.onChange(function () { | ||
// call the components `storeDidChanged` method | ||
if (self.storeDidChange) { | ||
self.storeDidChange(storeName); | ||
} | ||
// change state | ||
if (typeof store.store.getState === 'function') { | ||
var state = store.store.getState(); | ||
self.state.stores[storeName] = state; | ||
self.forceUpdate(); | ||
} | ||
}); | ||
} | ||
} | ||
}, | ||
getInitialState: function () { | ||
var self = this; | ||
function _findDispatcher(view) { | ||
if (!view.props.dispatcher) { | ||
return _findDispatcher(view._owner); | ||
} else { | ||
return view.props.dispatcher; | ||
} | ||
} | ||
// some shortcuts | ||
this.dispatcher = _findDispatcher(this); | ||
if (this.storesDidChange) { | ||
this.dispatcher.on('change:all', function () { | ||
self.storesDidChange(); | ||
}); | ||
} | ||
this.stores = this.dispatcher.stores; | ||
var state = {stores: {}}; | ||
// more shortcuts for the state | ||
for (var storeName in this.stores) { | ||
if (_hasOwn(this.stores, storeName)) { | ||
if (this.stores[storeName] | ||
&& this.stores[storeName].store | ||
&& this.stores[storeName].store.getState) { | ||
state.stores[storeName] = this.stores[storeName].store.getState(); | ||
} | ||
} | ||
} | ||
return state; | ||
} | ||
} | ||
}; | ||
// Module export | ||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { | ||
DeLorean.Flux.define('EventEmitter', require('events').EventEmitter); | ||
DeLorean.Flux.define('Promise', require('es6-promise').Promise); | ||
module.exports = DeLorean; | ||
} else { | ||
if (typeof define === 'function' && define.amd) { | ||
define([], function() { | ||
return DeLorean; | ||
}); | ||
} else { | ||
window.DeLorean = DeLorean; | ||
} | ||
} | ||
})({}); | ||
;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
"use strict"; | ||
var Promise = _dereq_("./promise/promise").Promise; | ||
var polyfill = _dereq_("./promise/polyfill").polyfill; | ||
var Promise = require("./promise/promise").Promise; | ||
var polyfill = require("./promise/polyfill").polyfill; | ||
exports.Promise = Promise; | ||
exports.polyfill = polyfill; | ||
},{"./promise/polyfill":5,"./promise/promise":6}],2:[function(_dereq_,module,exports){ | ||
},{"./promise/polyfill":5,"./promise/promise":6}],2:[function(require,module,exports){ | ||
"use strict"; | ||
/* global toString */ | ||
var isArray = _dereq_("./utils").isArray; | ||
var isFunction = _dereq_("./utils").isFunction; | ||
var isArray = require("./utils").isArray; | ||
var isFunction = require("./utils").isFunction; | ||
@@ -101,3 +357,3 @@ /** | ||
exports.all = all; | ||
},{"./utils":10}],3:[function(_dereq_,module,exports){ | ||
},{"./utils":10}],3:[function(require,module,exports){ | ||
(function (process,global){ | ||
@@ -165,4 +421,4 @@ "use strict"; | ||
exports.asap = asap; | ||
}).call(this,_dereq_("JkpR2F"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | ||
},{"JkpR2F":12}],4:[function(_dereq_,module,exports){ | ||
}).call(this,require("JkpR2F"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | ||
},{"JkpR2F":12}],4:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -183,8 +439,8 @@ var config = { | ||
exports.configure = configure; | ||
},{}],5:[function(_dereq_,module,exports){ | ||
},{}],5:[function(require,module,exports){ | ||
(function (global){ | ||
"use strict"; | ||
/*global self*/ | ||
var RSVPPromise = _dereq_("./promise").Promise; | ||
var isFunction = _dereq_("./utils").isFunction; | ||
var RSVPPromise = require("./promise").Promise; | ||
var isFunction = require("./utils").isFunction; | ||
@@ -225,14 +481,14 @@ function polyfill() { | ||
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | ||
},{"./promise":6,"./utils":10}],6:[function(_dereq_,module,exports){ | ||
},{"./promise":6,"./utils":10}],6:[function(require,module,exports){ | ||
"use strict"; | ||
var config = _dereq_("./config").config; | ||
var configure = _dereq_("./config").configure; | ||
var objectOrFunction = _dereq_("./utils").objectOrFunction; | ||
var isFunction = _dereq_("./utils").isFunction; | ||
var now = _dereq_("./utils").now; | ||
var all = _dereq_("./all").all; | ||
var race = _dereq_("./race").race; | ||
var staticResolve = _dereq_("./resolve").resolve; | ||
var staticReject = _dereq_("./reject").reject; | ||
var asap = _dereq_("./asap").asap; | ||
var config = require("./config").config; | ||
var configure = require("./config").configure; | ||
var objectOrFunction = require("./utils").objectOrFunction; | ||
var isFunction = require("./utils").isFunction; | ||
var now = require("./utils").now; | ||
var all = require("./all").all; | ||
var race = require("./race").race; | ||
var staticResolve = require("./resolve").resolve; | ||
var staticReject = require("./reject").reject; | ||
var asap = require("./asap").asap; | ||
@@ -438,6 +694,6 @@ var counter = 0; | ||
exports.Promise = Promise; | ||
},{"./all":2,"./asap":3,"./config":4,"./race":7,"./reject":8,"./resolve":9,"./utils":10}],7:[function(_dereq_,module,exports){ | ||
},{"./all":2,"./asap":3,"./config":4,"./race":7,"./reject":8,"./resolve":9,"./utils":10}],7:[function(require,module,exports){ | ||
"use strict"; | ||
/* global toString */ | ||
var isArray = _dereq_("./utils").isArray; | ||
var isArray = require("./utils").isArray; | ||
@@ -529,3 +785,3 @@ /** | ||
exports.race = race; | ||
},{"./utils":10}],8:[function(_dereq_,module,exports){ | ||
},{"./utils":10}],8:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -578,3 +834,3 @@ /** | ||
exports.reject = reject; | ||
},{}],9:[function(_dereq_,module,exports){ | ||
},{}],9:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -595,3 +851,3 @@ function resolve(value) { | ||
exports.resolve = resolve; | ||
},{}],10:[function(_dereq_,module,exports){ | ||
},{}],10:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -619,3 +875,3 @@ function objectOrFunction(x) { | ||
exports.now = now; | ||
},{}],11:[function(_dereq_,module,exports){ | ||
},{}],11:[function(require,module,exports){ | ||
// Copyright Joyent, Inc. and other Node contributors. | ||
@@ -925,3 +1181,3 @@ // | ||
},{}],12:[function(_dereq_,module,exports){ | ||
},{}],12:[function(require,module,exports){ | ||
// shim for using process in browser | ||
@@ -991,252 +1247,8 @@ | ||
},{}],13:[function(_dereq_,module,exports){ | ||
var DeLorean; | ||
},{}],13:[function(require,module,exports){ | ||
// Imports from Node modules. | ||
DeLorean = { | ||
Flux: _dereq_('./flux.coffee') | ||
}; | ||
DeLorean.Flux.define('EventEmitter', require('events').EventEmitter); | ||
DeLorean.Flux.define('Promise', require('es6-promise').Promise); | ||
module.exports = DeLorean; | ||
},{"./flux.coffee":15}],14:[function(_dereq_,module,exports){ | ||
var Dispatcher, EventEmitter, Promise, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
EventEmitter = _dereq_('events').EventEmitter; | ||
Promise = _dereq_('es6-promise').Promise; | ||
Dispatcher = (function(_super) { | ||
__extends(Dispatcher, _super); | ||
function Dispatcher(stores) { | ||
this.stores = stores; | ||
} | ||
Dispatcher.prototype.dispatch = function(actionName, data) { | ||
var deferred, store, storeName, _ref; | ||
deferred = this.waitFor((function() { | ||
var _ref, _results; | ||
_ref = this.stores; | ||
_results = []; | ||
for (storeName in _ref) { | ||
store = _ref[storeName]; | ||
_results.push(store); | ||
} | ||
return _results; | ||
}).call(this)); | ||
_ref = this.stores; | ||
for (storeName in _ref) { | ||
if (!__hasProp.call(_ref, storeName)) continue; | ||
store = _ref[storeName]; | ||
store.dispatchAction(actionName, data); | ||
} | ||
return deferred; | ||
}; | ||
Dispatcher.prototype.waitFor = function(stores) { | ||
var promises, store; | ||
promises = (function() { | ||
var _i, _len, _results; | ||
_results = []; | ||
for (_i = 0, _len = stores.length; _i < _len; _i++) { | ||
store = stores[_i]; | ||
_results.push(new Promise(function(resolve, reject) { | ||
return store.once('change', resolve); | ||
})); | ||
} | ||
return _results; | ||
})(); | ||
return Promise.all(promises).then((function(_this) { | ||
return function() { | ||
return _this.emit('change:all'); | ||
}; | ||
})(this)); | ||
}; | ||
Dispatcher.prototype.registerAction = function(actionName, callback) { | ||
return this[actionName] = callback.bind(this); | ||
}; | ||
return Dispatcher; | ||
})(EventEmitter); | ||
module.exports = Dispatcher; | ||
},{"es6-promise":1,"events":11}],15:[function(_dereq_,module,exports){ | ||
var Dispatcher, Flux, Store, | ||
__slice = [].slice, | ||
__hasProp = {}.hasOwnProperty; | ||
Store = _dereq_('./store.coffee'); | ||
Dispatcher = _dereq_('./dispatcher.coffee'); | ||
Flux = (function() { | ||
function Flux() {} | ||
Flux.createStore = function(store) { | ||
return function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return (function(func, args, ctor) { | ||
ctor.prototype = func.prototype; | ||
var child = new ctor, result = func.apply(child, args); | ||
return Object(result) === result ? result : child; | ||
})(Store, [store].concat(__slice.call(args)), function(){}); | ||
}; | ||
}; | ||
Flux.createDispatcher = function(actions) { | ||
var action, callback, dispatcher; | ||
dispatcher = new Dispatcher(typeof actions.getStores === "function" ? actions.getStores() : void 0); | ||
for (action in actions) { | ||
if (!__hasProp.call(actions, action)) continue; | ||
callback = actions[action]; | ||
if (action !== 'getStores') { | ||
dispatcher.registerAction(action, callback); | ||
} | ||
} | ||
return dispatcher; | ||
}; | ||
return Flux; | ||
})(); | ||
Flux.mixins = _dereq_('./mixin.coffee'); | ||
module.exports = Flux; | ||
},{"./dispatcher.coffee":14,"./mixin.coffee":16,"./store.coffee":17}],16:[function(_dereq_,module,exports){ | ||
var __hasProp = {}.hasOwnProperty; | ||
module.exports = { | ||
storeListener: { | ||
componentDidMount: function() { | ||
var store, storeName, _ref, _results; | ||
_ref = this.stores; | ||
_results = []; | ||
for (storeName in _ref) { | ||
if (!__hasProp.call(_ref, storeName)) continue; | ||
store = _ref[storeName]; | ||
_results.push((function(_this) { | ||
return function(store, storeName) { | ||
return store.onChange(function() { | ||
var state, _base; | ||
if (typeof _this.storeDidChange === "function") { | ||
_this.storeDidChange(storeName); | ||
} | ||
if (state = typeof (_base = store.store).getState === "function" ? _base.getState() : void 0) { | ||
_this.state.stores[storeName] = state; | ||
return _this.forceUpdate(); | ||
} | ||
}); | ||
}; | ||
})(this)(store, storeName)); | ||
} | ||
return _results; | ||
}, | ||
getInitialState: function() { | ||
var findDispatcher, state, storeName, _ref, _ref1, _ref2; | ||
findDispatcher = function(view) { | ||
if (!view.props.dispatcher) { | ||
return findDispatcher(view._owner); | ||
} else { | ||
return view.props.dispatcher; | ||
} | ||
}; | ||
this.dispatcher = findDispatcher(this); | ||
this.dispatcher.on('change:all', (function(_this) { | ||
return function() { | ||
return typeof _this.storesDidChange === "function" ? _this.storesDidChange() : void 0; | ||
}; | ||
})(this)); | ||
this.stores = this.dispatcher.stores; | ||
state = { | ||
stores: {} | ||
}; | ||
_ref = this.stores; | ||
for (storeName in _ref) { | ||
if (!__hasProp.call(_ref, storeName)) continue; | ||
state.stores[storeName] = (_ref1 = this.stores[storeName]) != null ? (_ref2 = _ref1.store) != null ? typeof _ref2.getState === "function" ? _ref2.getState() : void 0 : void 0 : void 0; | ||
} | ||
return state; | ||
} | ||
} | ||
}; | ||
},{}],17:[function(_dereq_,module,exports){ | ||
var EventEmitter, Store, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | ||
__slice = [].slice; | ||
EventEmitter = _dereq_('events').EventEmitter; | ||
Store = (function(_super) { | ||
__extends(Store, _super); | ||
function Store() { | ||
var args, store, _ref; | ||
store = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | ||
this.store = store; | ||
Store.__super__.constructor.apply(this, arguments); | ||
this.bindActions(store.actions); | ||
if ((_ref = this.store.initialize) != null) { | ||
_ref.call.apply(_ref, [this.store].concat(__slice.call(args))); | ||
} | ||
} | ||
Store.prototype.bindActions = function(actions) { | ||
var actionName, callback, _results; | ||
this.store.emit = this.emit.bind(this); | ||
this.store.listenChanges = this.listenChanges.bind(this); | ||
_results = []; | ||
for (actionName in actions) { | ||
if (!__hasProp.call(actions, actionName)) continue; | ||
callback = actions[actionName]; | ||
_results.push(this.on("action:" + actionName, this.store[callback].bind(this.store))); | ||
} | ||
return _results; | ||
}; | ||
Store.prototype.dispatchAction = function(actionName, data) { | ||
return this.emit("action:" + actionName, data); | ||
}; | ||
Store.prototype.onChange = function(callback) { | ||
return this.on('change', callback); | ||
}; | ||
Store.prototype.listenChanges = function(object) { | ||
var observer; | ||
observer = Array.isArray(object) ? Array.observe : Object.observe; | ||
return observer(object, (function(_this) { | ||
return function() { | ||
return _this.emit('change'); | ||
}; | ||
})(this)); | ||
}; | ||
return Store; | ||
})(EventEmitter); | ||
module.exports = Store; | ||
},{"events":11}]},{},[13]) | ||
(13) | ||
}); | ||
},{"es6-promise":1,"events":11}]},{},[13]); |
@@ -1,1 +0,2 @@ | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.DeLorean=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d=a("./promise/promise").Promise,e=a("./promise/polyfill").polyfill;c.Promise=d,c.polyfill=e},{"./promise/polyfill":5,"./promise/promise":6}],2:[function(a,b,c){"use strict";function d(a){var b=this;if(!e(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){e(a,b)}}function e(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&f(g.then)?g.then(d(j),c):e(j,g)})}var e=a("./utils").isArray,f=a("./utils").isFunction;c.all=d},{"./utils":10}],3:[function(a,b,c){(function(a,b){"use strict";function d(){return function(){a.nextTick(g)}}function e(){var a=0,b=new k(g),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function f(){return function(){l.setTimeout(g,1)}}function g(){for(var a=0;a<m.length;a++){var b=m[a],c=b[0],d=b[1];c(d)}m=[]}function h(a,b){var c=m.push([a,b]);1===c&&i()}var i,j="undefined"!=typeof window?window:{},k=j.MutationObserver||j.WebKitMutationObserver,l="undefined"!=typeof b?b:void 0===this?window:this,m=[];i="undefined"!=typeof a&&"[object process]"==={}.toString.call(a)?d():k?e():f(),c.asap=h}).call(this,a("JkpR2F"),"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{JkpR2F:12}],4:[function(a,b,c){"use strict";function d(a,b){return 2!==arguments.length?e[a]:void(e[a]=b)}var e={instrument:!1};c.config=e,c.configure=d},{}],5:[function(a,b,c){(function(b){"use strict";function d(){var a;a="undefined"!=typeof b?b:"undefined"!=typeof window&&window.document?window:self;var c="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();c||(a.Promise=e)}var e=a("./promise").Promise,f=a("./utils").isFunction;c.polyfill=d}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./promise":6,"./utils":10}],6:[function(a,b,c){"use strict";function d(a){if(!q(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof d))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],e(a,this)}function e(a,b){function c(a){j(b,a)}function d(a){l(b,a)}try{a(c,d)}catch(e){d(e)}}function f(a,b,c,d){var e,f,g,h,k=q(c);if(k)try{e=c(d),g=!0}catch(m){h=!0,f=m}else e=d,g=!0;i(b,e)||(k&&g?j(b,e):h?l(b,f):a===y?j(b,e):a===z&&l(b,e))}function g(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+y]=c,e[f+z]=d}function h(a,b){for(var c,d,e=a._subscribers,g=a._detail,h=0;h<e.length;h+=3)c=e[h],d=e[h+b],f(b,c,d,g);a._subscribers=null}function i(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(p(b)&&(d=b.then,q(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?j(a,d):k(a,d)))},function(b){return c?!0:(c=!0,void l(a,b))}),!0}catch(e){return c?!0:(l(a,e),!0)}return!1}function j(a,b){a===b?k(a,b):i(a,b)||k(a,b)}function k(a,b){a._state===w&&(a._state=x,a._detail=b,o.async(m,a))}function l(a,b){a._state===w&&(a._state=x,a._detail=b,o.async(n,a))}function m(a){h(a,a._state=y)}function n(a){h(a,a._state=z)}var o=a("./config").config,p=(a("./config").configure,a("./utils").objectOrFunction),q=a("./utils").isFunction,r=(a("./utils").now,a("./all").all),s=a("./race").race,t=a("./resolve").resolve,u=a("./reject").reject,v=a("./asap").asap;o.async=v;var w=void 0,x=0,y=1,z=2;d.prototype={constructor:d,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;o.async(function(){f(c._state,d,e[c._state-1],c._detail)})}else g(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},d.all=r,d.race=s,d.resolve=t,d.reject=u,c.Promise=d},{"./all":2,"./asap":3,"./config":4,"./race":7,"./reject":8,"./resolve":9,"./utils":10}],7:[function(a,b,c){"use strict";function d(a){var b=this;if(!e(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var e=a("./utils").isArray;c.race=d},{"./utils":10}],8:[function(a,b,c){"use strict";function d(a){var b=this;return new b(function(b,c){c(a)})}c.reject=d},{}],9:[function(a,b,c){"use strict";function d(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}c.resolve=d},{}],10:[function(a,b,c){"use strict";function d(a){return e(a)||"object"==typeof a&&null!==a}function e(a){return"function"==typeof a}function f(a){return"[object Array]"===Object.prototype.toString.call(a)}var g=Date.now||function(){return(new Date).getTime()};c.objectOrFunction=d,c.isFunction=e,c.isArray=f,c.now=g},{}],11:[function(a,b){function c(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function d(a){return"function"==typeof a}function e(a){return"number"==typeof a}function f(a){return"object"==typeof a&&null!==a}function g(a){return void 0===a}b.exports=c,c.EventEmitter=c,c.prototype._events=void 0,c.prototype._maxListeners=void 0,c.defaultMaxListeners=10,c.prototype.setMaxListeners=function(a){if(!e(a)||0>a||isNaN(a))throw TypeError("n must be a positive number");return this._maxListeners=a,this},c.prototype.emit=function(a){var b,c,e,h,i,j;if(this._events||(this._events={}),"error"===a&&(!this._events.error||f(this._events.error)&&!this._events.error.length))throw b=arguments[1],b instanceof Error?b:TypeError('Uncaught, unspecified "error" event.');if(c=this._events[a],g(c))return!1;if(d(c))switch(arguments.length){case 1:c.call(this);break;case 2:c.call(this,arguments[1]);break;case 3:c.call(this,arguments[1],arguments[2]);break;default:for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];c.apply(this,h)}else if(f(c)){for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];for(j=c.slice(),e=j.length,i=0;e>i;i++)j[i].apply(this,h)}return!0},c.prototype.addListener=function(a,b){var e;if(!d(b))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",a,d(b.listener)?b.listener:b),this._events[a]?f(this._events[a])?this._events[a].push(b):this._events[a]=[this._events[a],b]:this._events[a]=b,f(this._events[a])&&!this._events[a].warned){var e;e=g(this._maxListeners)?c.defaultMaxListeners:this._maxListeners,e&&e>0&&this._events[a].length>e&&(this._events[a].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[a].length),"function"==typeof console.trace&&console.trace())}return this},c.prototype.on=c.prototype.addListener,c.prototype.once=function(a,b){function c(){this.removeListener(a,c),e||(e=!0,b.apply(this,arguments))}if(!d(b))throw TypeError("listener must be a function");var e=!1;return c.listener=b,this.on(a,c),this},c.prototype.removeListener=function(a,b){var c,e,g,h;if(!d(b))throw TypeError("listener must be a function");if(!this._events||!this._events[a])return this;if(c=this._events[a],g=c.length,e=-1,c===b||d(c.listener)&&c.listener===b)delete this._events[a],this._events.removeListener&&this.emit("removeListener",a,b);else if(f(c)){for(h=g;h-->0;)if(c[h]===b||c[h].listener&&c[h].listener===b){e=h;break}if(0>e)return this;1===c.length?(c.length=0,delete this._events[a]):c.splice(e,1),this._events.removeListener&&this.emit("removeListener",a,b)}return this},c.prototype.removeAllListeners=function(a){var b,c;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[a]&&delete this._events[a],this;if(0===arguments.length){for(b in this._events)"removeListener"!==b&&this.removeAllListeners(b);return this.removeAllListeners("removeListener"),this._events={},this}if(c=this._events[a],d(c))this.removeListener(a,c);else for(;c.length;)this.removeListener(a,c[c.length-1]);return delete this._events[a],this},c.prototype.listeners=function(a){var b;return b=this._events&&this._events[a]?d(this._events[a])?[this._events[a]]:this._events[a].slice():[]},c.listenerCount=function(a,b){var c;return c=a._events&&a._events[b]?d(a._events[b])?1:a._events[b].length:0}},{}],12:[function(a,b){function c(){}var d=b.exports={};d.nextTick=function(){var a="undefined"!=typeof window&&window.setImmediate,b="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(a)return function(a){return window.setImmediate(a)};if(b){var c=[];return window.addEventListener("message",function(a){var b=a.source;if((b===window||null===b)&&"process-tick"===a.data&&(a.stopPropagation(),c.length>0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),d.title="browser",d.browser=!0,d.env={},d.argv=[],d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(){throw new Error("process.chdir is not supported")}},{}],13:[function(a,b){var c;c={Flux:a("./flux.coffee")},b.exports=c},{"./flux.coffee":15}],14:[function(a,b){var c,d,e,f={}.hasOwnProperty,g=function(a,b){function c(){this.constructor=a}for(var d in b)f.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};d=a("events").EventEmitter,e=a("es6-promise").Promise,c=function(a){function b(a){this.stores=a}return g(b,a),b.prototype.dispatch=function(a,b){var c,d,e,g;c=this.waitFor(function(){var a,b;a=this.stores,b=[];for(e in a)d=a[e],b.push(d);return b}.call(this)),g=this.stores;for(e in g)f.call(g,e)&&(d=g[e],d.dispatchAction(a,b));return c},b.prototype.waitFor=function(a){var b,c;return b=function(){var b,d,f;for(f=[],b=0,d=a.length;d>b;b++)c=a[b],f.push(new e(function(a){return c.once("change",a)}));return f}(),e.all(b).then(function(a){return function(){return a.emit("change:all")}}(this))},b.prototype.registerAction=function(a,b){return this[a]=b.bind(this)},b}(d),b.exports=c},{"es6-promise":1,events:11}],15:[function(a,b){var c,d,e,f=[].slice,g={}.hasOwnProperty;e=a("./store.coffee"),c=a("./dispatcher.coffee"),d=function(){function a(){}return a.createStore=function(a){return function(){var b;return b=1<=arguments.length?f.call(arguments,0):[],function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(e,[a].concat(f.call(b)),function(){})}},a.createDispatcher=function(a){var b,d,e;e=new c("function"==typeof a.getStores?a.getStores():void 0);for(b in a)g.call(a,b)&&(d=a[b],"getStores"!==b&&e.registerAction(b,d));return e},a}(),d.mixins=a("./mixin.coffee"),b.exports=d},{"./dispatcher.coffee":14,"./mixin.coffee":16,"./store.coffee":17}],16:[function(a,b){var c={}.hasOwnProperty;b.exports={storeListener:{componentDidMount:function(){var a,b,d,e;d=this.stores,e=[];for(b in d)c.call(d,b)&&(a=d[b],e.push(function(a){return function(b,c){return b.onChange(function(){var d,e;return"function"==typeof a.storeDidChange&&a.storeDidChange(c),(d="function"==typeof(e=b.store).getState?e.getState():void 0)?(a.state.stores[c]=d,a.forceUpdate()):void 0})}}(this)(a,b)));return e},getInitialState:function(){var a,b,d,e,f,g;a=function(b){return b.props.dispatcher?b.props.dispatcher:a(b._owner)},this.dispatcher=a(this),this.dispatcher.on("change:all",function(a){return function(){return"function"==typeof a.storesDidChange?a.storesDidChange():void 0}}(this)),this.stores=this.dispatcher.stores,b={stores:{}},e=this.stores;for(d in e)c.call(e,d)&&(b.stores[d]=null!=(f=this.stores[d])&&null!=(g=f.store)&&"function"==typeof g.getState?g.getState():void 0);return b}}}},{}],17:[function(a,b){var c,d,e={}.hasOwnProperty,f=function(a,b){function c(){this.constructor=a}for(var d in b)e.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},g=[].slice;c=a("events").EventEmitter,d=function(a){function b(){var a,c,d;c=arguments[0],a=2<=arguments.length?g.call(arguments,1):[],this.store=c,b.__super__.constructor.apply(this,arguments),this.bindActions(c.actions),null!=(d=this.store.initialize)&&d.call.apply(d,[this.store].concat(g.call(a)))}return f(b,a),b.prototype.bindActions=function(a){var b,c,d;this.store.emit=this.emit.bind(this),this.store.listenChanges=this.listenChanges.bind(this),d=[];for(b in a)e.call(a,b)&&(c=a[b],d.push(this.on("action:"+b,this.store[c].bind(this.store))));return d},b.prototype.dispatchAction=function(a,b){return this.emit("action:"+a,b)},b.prototype.onChange=function(a){return this.on("change",a)},b.prototype.listenChanges=function(a){var b;return(b=Array.isArray(a)?Array.observe:Object.observe)(a,function(a){return function(){return a.emit("change")}}(this))},b}(c),b.exports=d},{events:11}]},{},[13])(13)}); | ||
!function(DeLorean){"use strict";function a(a){return"action:"+a}function b(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function c(a,b){return Array.prototype.slice.call(a,b)}var Dispatcher=function(){function Dispatcher(a){this.listener=new DeLorean.EventEmitter,this.stores=a}return Dispatcher.prototype.dispatch=function(a,b){var c=this,d=function(){var a=[];for(var b in c.stores){var d=c.stores[b];if(!d instanceof Store)throw"Given store is not a store instance";a.push(d)}return a}(),e=this.waitFor(d);for(var f in c.stores)c.stores[f].dispatchAction(a,b);return e},Dispatcher.prototype.waitFor=function(a){var b=this,c=function(){var b=[];for(var c in a){var d=function(a){return new DeLorean.Promise(function(b){a.listener.once("change",b)})}(a[c]);b.push(d)}return b}();return DeLorean.Promise.all(c).then(function(){b.listener.emit("change:all")})},Dispatcher.prototype.registerAction=function(a,b){if("function"!=typeof b)throw"Action callback should be a function.";this[a]=b.bind(this.stores)},Dispatcher.prototype.on=function(){return this.listener.on.apply(this.listener,arguments)},Dispatcher.prototype.off=function(){return this.listener.removeListener.apply(this.listener,arguments)},Dispatcher}(),Store=function(){function Store(a){if("object"!=typeof a)throw"Stores should be defined by passing the definition to the constructor";if(this.listener=new DeLorean.EventEmitter,this.store=a,this.bindActions(),"function"==typeof a.initialize){var b=c(arguments,1);a.initialize.apply(this.store,b)}}return Store.prototype.bindActions=function(){this.store.emit=this.listener.emit.bind(this.listener),this.store.listenChanges=this.listenChanges.bind(this);for(var c in this.store.actions)if(b(this.store.actions,c)){var d=this.store.actions[c];if("function"!=typeof this.store[d])throw"Callback should be a method!";this.listener.on(a(c),this.store[d].bind(this.store))}},Store.prototype.dispatchAction=function(b,c){this.listener.emit(a(b),c)},Store.prototype.onChange=function(a){this.listener.on("change",a)},Store.prototype.listenChanges=function(a){if(!Object.observe)return void console.error("Store#listenChanges method uses Object.observe, you should fire changes manually.");var b=this,c=Array.isArray(a)?Array.observe:Object.observe;c(a,function(){b.listener.emit("change")})},Store}();DeLorean.Flux={createStore:function(a){return function(){return new Store(a)}},createDispatcher:function(a){if("function"==typeof a.getStores)var c=a.getStores();var d=new Dispatcher(c||{});for(var e in a)if(b(a,e)&&"getStores"!==e){var f=a[e];d.registerAction(e,f.bind(d))}return d},define:function(a,b){DeLorean[a]=b}},DeLorean.Dispatcher=Dispatcher,DeLorean.Store=Store,DeLorean.Flux.mixins={storeListener:{componentDidMount:function(){var a=this;for(var c in this.stores)if(b(this.stores,c)){var d=this.stores[c];d.onChange(function(){if(a.storeDidChange&&a.storeDidChange(c),"function"==typeof d.store.getState){var b=d.store.getState();a.state.stores[c]=b,a.forceUpdate()}})}},getInitialState:function(){function a(b){return b.props.dispatcher?b.props.dispatcher:a(b._owner)}var c=this;this.dispatcher=a(this),this.storesDidChange&&this.dispatcher.on("change:all",function(){c.storesDidChange()}),this.stores=this.dispatcher.stores;var d={stores:{}};for(var e in this.stores)b(this.stores,e)&&this.stores[e]&&this.stores[e].store&&this.stores[e].store.getState&&(d.stores[e]=this.stores[e].store.getState());return d}}},"undefined"!=typeof module&&"undefined"!=typeof module.exports?(DeLorean.Flux.define("EventEmitter",require("events").EventEmitter),DeLorean.Flux.define("Promise",require("es6-promise").Promise),module.exports=DeLorean):"function"==typeof define&&define.amd?define([],function(){return DeLorean}):window.DeLorean=DeLorean}({}),function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d=a("./promise/promise").Promise,e=a("./promise/polyfill").polyfill;c.Promise=d,c.polyfill=e},{"./promise/polyfill":5,"./promise/promise":6}],2:[function(a,b,c){"use strict";function d(a){var b=this;if(!e(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){e(a,b)}}function e(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&f(g.then)?g.then(d(j),c):e(j,g)})}var e=a("./utils").isArray,f=a("./utils").isFunction;c.all=d},{"./utils":10}],3:[function(a,b,c){(function(a,b){"use strict";function d(){return function(){a.nextTick(g)}}function e(){var a=0,b=new k(g),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function f(){return function(){l.setTimeout(g,1)}}function g(){for(var a=0;a<m.length;a++){var b=m[a],c=b[0],d=b[1];c(d)}m=[]}function h(a,b){var c=m.push([a,b]);1===c&&i()}var i,j="undefined"!=typeof window?window:{},k=j.MutationObserver||j.WebKitMutationObserver,l="undefined"!=typeof b?b:void 0===this?window:this,m=[];i="undefined"!=typeof a&&"[object process]"==={}.toString.call(a)?d():k?e():f(),c.asap=h}).call(this,a("JkpR2F"),"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{JkpR2F:12}],4:[function(a,b,c){"use strict";function d(a,b){return 2!==arguments.length?e[a]:void(e[a]=b)}var e={instrument:!1};c.config=e,c.configure=d},{}],5:[function(a,b,c){(function(b){"use strict";function d(){var a;a="undefined"!=typeof b?b:"undefined"!=typeof window&&window.document?window:self;var c="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();c||(a.Promise=e)}var e=a("./promise").Promise,f=a("./utils").isFunction;c.polyfill=d}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./promise":6,"./utils":10}],6:[function(a,b,c){"use strict";function d(a){if(!q(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof d))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],e(a,this)}function e(a,b){function c(a){j(b,a)}function d(a){l(b,a)}try{a(c,d)}catch(e){d(e)}}function f(a,b,c,d){var e,f,g,h,k=q(c);if(k)try{e=c(d),g=!0}catch(m){h=!0,f=m}else e=d,g=!0;i(b,e)||(k&&g?j(b,e):h?l(b,f):a===y?j(b,e):a===z&&l(b,e))}function g(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+y]=c,e[f+z]=d}function h(a,b){for(var c,d,e=a._subscribers,g=a._detail,h=0;h<e.length;h+=3)c=e[h],d=e[h+b],f(b,c,d,g);a._subscribers=null}function i(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(p(b)&&(d=b.then,q(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?j(a,d):k(a,d)))},function(b){return c?!0:(c=!0,void l(a,b))}),!0}catch(e){return c?!0:(l(a,e),!0)}return!1}function j(a,b){a===b?k(a,b):i(a,b)||k(a,b)}function k(a,b){a._state===w&&(a._state=x,a._detail=b,o.async(m,a))}function l(a,b){a._state===w&&(a._state=x,a._detail=b,o.async(n,a))}function m(a){h(a,a._state=y)}function n(a){h(a,a._state=z)}var o=a("./config").config,p=(a("./config").configure,a("./utils").objectOrFunction),q=a("./utils").isFunction,r=(a("./utils").now,a("./all").all),s=a("./race").race,t=a("./resolve").resolve,u=a("./reject").reject,v=a("./asap").asap;o.async=v;var w=void 0,x=0,y=1,z=2;d.prototype={constructor:d,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;o.async(function(){f(c._state,d,e[c._state-1],c._detail)})}else g(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},d.all=r,d.race=s,d.resolve=t,d.reject=u,c.Promise=d},{"./all":2,"./asap":3,"./config":4,"./race":7,"./reject":8,"./resolve":9,"./utils":10}],7:[function(a,b,c){"use strict";function d(a){var b=this;if(!e(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var e=a("./utils").isArray;c.race=d},{"./utils":10}],8:[function(a,b,c){"use strict";function d(a){var b=this;return new b(function(b,c){c(a)})}c.reject=d},{}],9:[function(a,b,c){"use strict";function d(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}c.resolve=d},{}],10:[function(a,b,c){"use strict";function d(a){return e(a)||"object"==typeof a&&null!==a}function e(a){return"function"==typeof a}function f(a){return"[object Array]"===Object.prototype.toString.call(a)}var g=Date.now||function(){return(new Date).getTime()};c.objectOrFunction=d,c.isFunction=e,c.isArray=f,c.now=g},{}],11:[function(a,b){function c(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function d(a){return"function"==typeof a}function e(a){return"number"==typeof a}function f(a){return"object"==typeof a&&null!==a}function g(a){return void 0===a}b.exports=c,c.EventEmitter=c,c.prototype._events=void 0,c.prototype._maxListeners=void 0,c.defaultMaxListeners=10,c.prototype.setMaxListeners=function(a){if(!e(a)||0>a||isNaN(a))throw TypeError("n must be a positive number");return this._maxListeners=a,this},c.prototype.emit=function(a){var b,c,e,h,i,j;if(this._events||(this._events={}),"error"===a&&(!this._events.error||f(this._events.error)&&!this._events.error.length))throw b=arguments[1],b instanceof Error?b:TypeError('Uncaught, unspecified "error" event.');if(c=this._events[a],g(c))return!1;if(d(c))switch(arguments.length){case 1:c.call(this);break;case 2:c.call(this,arguments[1]);break;case 3:c.call(this,arguments[1],arguments[2]);break;default:for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];c.apply(this,h)}else if(f(c)){for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];for(j=c.slice(),e=j.length,i=0;e>i;i++)j[i].apply(this,h)}return!0},c.prototype.addListener=function(a,b){var e;if(!d(b))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",a,d(b.listener)?b.listener:b),this._events[a]?f(this._events[a])?this._events[a].push(b):this._events[a]=[this._events[a],b]:this._events[a]=b,f(this._events[a])&&!this._events[a].warned){var e;e=g(this._maxListeners)?c.defaultMaxListeners:this._maxListeners,e&&e>0&&this._events[a].length>e&&(this._events[a].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[a].length),"function"==typeof console.trace&&console.trace())}return this},c.prototype.on=c.prototype.addListener,c.prototype.once=function(a,b){function c(){this.removeListener(a,c),e||(e=!0,b.apply(this,arguments))}if(!d(b))throw TypeError("listener must be a function");var e=!1;return c.listener=b,this.on(a,c),this},c.prototype.removeListener=function(a,b){var c,e,g,h;if(!d(b))throw TypeError("listener must be a function");if(!this._events||!this._events[a])return this;if(c=this._events[a],g=c.length,e=-1,c===b||d(c.listener)&&c.listener===b)delete this._events[a],this._events.removeListener&&this.emit("removeListener",a,b);else if(f(c)){for(h=g;h-->0;)if(c[h]===b||c[h].listener&&c[h].listener===b){e=h;break}if(0>e)return this;1===c.length?(c.length=0,delete this._events[a]):c.splice(e,1),this._events.removeListener&&this.emit("removeListener",a,b)}return this},c.prototype.removeAllListeners=function(a){var b,c;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[a]&&delete this._events[a],this;if(0===arguments.length){for(b in this._events)"removeListener"!==b&&this.removeAllListeners(b);return this.removeAllListeners("removeListener"),this._events={},this}if(c=this._events[a],d(c))this.removeListener(a,c);else for(;c.length;)this.removeListener(a,c[c.length-1]);return delete this._events[a],this},c.prototype.listeners=function(a){var b;return b=this._events&&this._events[a]?d(this._events[a])?[this._events[a]]:this._events[a].slice():[]},c.listenerCount=function(a,b){var c;return c=a._events&&a._events[b]?d(a._events[b])?1:a._events[b].length:0}},{}],12:[function(a,b){function c(){}var d=b.exports={};d.nextTick=function(){var a="undefined"!=typeof window&&window.setImmediate,b="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(a)return function(a){return window.setImmediate(a)};if(b){var c=[];return window.addEventListener("message",function(a){var b=a.source;if((b===window||null===b)&&"process-tick"===a.data&&(a.stopPropagation(),c.length>0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),d.title="browser",d.browser=!0,d.env={},d.argv=[],d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(){throw new Error("process.chdir is not supported")}},{}],13:[function(a){DeLorean.Flux.define("EventEmitter",a("events").EventEmitter),DeLorean.Flux.define("Promise",a("es6-promise").Promise)},{"es6-promise":1,events:11}]},{},[13]); | ||
//# sourceMappingURL=delorean.min.js.map |
@@ -12,3 +12,6 @@ var Flux = DeLorean.Flux; | ||
var self = this; | ||
this.todos = this.todos.concat(todos); | ||
if (todos) { | ||
this.todos = this.todos.concat(todos); | ||
this.emit('change'); | ||
} | ||
@@ -19,3 +22,3 @@ // Auto change | ||
// }); | ||
this.listenChanges(this.todos); | ||
// this.listenChanges(this.todos); | ||
}, | ||
@@ -31,2 +34,3 @@ | ||
this.todos.push({text: todo.text}); | ||
this.emit('change'); | ||
}, | ||
@@ -38,3 +42,3 @@ | ||
}); | ||
this.listenChanges(filteredData); | ||
// this.listenChanges(filteredData); | ||
@@ -47,3 +51,3 @@ this.todos = filteredData; | ||
this.todos = todos; | ||
this.listenChanges(this.todos); | ||
// this.listenChanges(this.todos); | ||
this.emit('change'); | ||
@@ -50,0 +54,0 @@ } |
@@ -5,2 +5,3 @@ /** @jsx React.DOM */ | ||
var Flux = require('../../../../').Flux; | ||
var Router = require('director').Router; | ||
@@ -19,3 +20,5 @@ | ||
var self = this; | ||
this.todos = this.todos.concat(todos); | ||
if (todos) { | ||
this.todos = this.todos.concat(todos); | ||
} | ||
@@ -22,0 +25,0 @@ // Auto change |
@@ -5,2 +5,3 @@ /** @jsx React.DOM */ | ||
var Flux = require('../../../../').Flux; | ||
var Router = require('director').Router; | ||
@@ -19,3 +20,5 @@ | ||
var self = this; | ||
this.todos = this.todos.concat(todos); | ||
if (todos) { | ||
this.todos = this.todos.concat(todos); | ||
} | ||
@@ -22,0 +25,0 @@ // Auto change |
module.exports = function (grunt) { | ||
grunt.loadNpmTasks('grunt-karma'); | ||
grunt.loadNpmTasks('grunt-browserify'); | ||
grunt.loadNpmTasks('grunt-contrib-uglify'); | ||
grunt.loadNpmTasks('grunt-browserify'); | ||
grunt.loadNpmTasks('grunt-contrib-concat'); | ||
grunt.loadNpmTasks('grunt-contrib-connect'); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
grunt.loadNpmTasks('grunt-release'); | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
karma: { | ||
unit: { | ||
configFile: 'test/karma.conf.js', | ||
}, | ||
}, | ||
browserify: { | ||
dist: { | ||
files: { | ||
'dist/.tmp/delorean-requires.js': 'src/requires.js' | ||
} | ||
} | ||
}, | ||
concat: { | ||
options: { | ||
separator: ';', | ||
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + | ||
'<%= grunt.template.today("yyyy-mm-dd") %> */\n' | ||
}, | ||
build: { | ||
src: ['src/delorean.js', 'dist/.tmp/delorean-requires.js'], | ||
dest: 'dist/delorean.js', | ||
} | ||
}, | ||
uglify: { | ||
options: { | ||
sourceMap: true, | ||
mangle: { | ||
except: ['DeLorean', 'Store', 'Dispatcher', 'Flux'] | ||
} | ||
}, | ||
build: { | ||
@@ -14,15 +50,20 @@ files: { | ||
}, | ||
browserify: { | ||
coffeeify: { | ||
connect: { | ||
server: { | ||
options: { | ||
bundleOptions: { | ||
standalone: 'DeLorean' | ||
}, | ||
transform: ['coffeeify'] | ||
}, | ||
files: { | ||
'dist/delorean.js': ['src/delorean.coffee'] | ||
livereload: true, | ||
port: 9001, | ||
base: 'coverage/' | ||
} | ||
} | ||
}, | ||
watch: { | ||
development: { | ||
files: ['!src/index.js', 'src/**/*.js', 'test/**/*.js'], | ||
tasks: ['default'], | ||
options: { | ||
livereload: true | ||
}, | ||
}, | ||
}, | ||
release: { | ||
@@ -35,4 +76,5 @@ options: { | ||
grunt.registerTask('default', ['browserify:coffeeify', 'uglify']); | ||
grunt.registerTask('default', ['browserify', 'concat', 'uglify']); | ||
grunt.registerTask('dev', ['connect', 'watch']); | ||
}; |
{ | ||
"name": "delorean.js", | ||
"version": "0.4.10", | ||
"version": "0.5.0", | ||
"description": "Flux Library", | ||
"main": "dist/delorean.min.js", | ||
"main": "src/delorean.js", | ||
"scripts": { | ||
"test": "./node_modules/.bin/jest" | ||
"test": "./node_modules/.bin/grunt karma" | ||
}, | ||
@@ -12,9 +12,18 @@ "author": "Fatih Kadir Akin", | ||
"devDependencies": { | ||
"coffeeify": "^0.7.0", | ||
"grunt": "^0.4.5", | ||
"grunt-browserify": "^2.1.4", | ||
"grunt-contrib-concat": "^0.5.0", | ||
"grunt-contrib-connect": "^0.8.0", | ||
"grunt-contrib-uglify": "^0.5.1", | ||
"grunt-react": "^0.9.0", | ||
"grunt-contrib-watch": "^0.6.1", | ||
"grunt-karma": "^0.8.3", | ||
"grunt-livereload": "^0.1.3", | ||
"grunt-release": "git+https://github.com/f/grunt-release.git#c17216608469c5ecbb43458289763e09839932ba", | ||
"jest-cli": "^0.1.18" | ||
"grunt-requirejs": "^0.4.2", | ||
"jasmine": "^2.0.1", | ||
"karma": "^0.12.22", | ||
"karma-chrome-launcher": "^0.1.4", | ||
"karma-coverage": "^0.2.6", | ||
"karma-jasmine": "^0.1.5", | ||
"karma-phantomjs-launcher": "^0.1.4" | ||
}, | ||
@@ -21,0 +30,0 @@ "dependencies": { |
346
README.md
@@ -1,2 +0,2 @@ | ||
![DeLorean Logo](https://raw.githubusercontent.com/f/delorean/master/asset/delorean-logo.png) | ||
![DeLorean Logo](https://raw.githubusercontent.com/f/delorean/master/docs/asset/delorean-logo.png) | ||
@@ -6,13 +6,13 @@ # DeLorean.js | ||
[![NPM version](https://badge.fury.io/js/delorean.js.svg)](http://badge.fury.io/js/delorean.js) | ||
![Coverage](http://progressed.io/bar/26?title=coverage) | ||
DeLorean is a tiny Flux pattern implementation. | ||
- Unidirectional data flow, it makes your app logic simpler than MVC, | ||
- **Unidirectional data flow**, it makes your app logic **simpler than MVC**, | ||
- Automatically listens data changes and keeps your data updated, | ||
- It uses **`Object.observe`** to listen store changes, | ||
- Makes data more consistent in your whole application, | ||
- Makes data more **consistent** in your whole application, | ||
- Too easy to use with **React.js**; just add a mixin, | ||
- Too easy to use with **Flight.js** | ||
- Too easy to use with **Flight.js**; see the example | ||
- It's platform agnostic, completely. There's no dependency. | ||
- Too small, just **13K**. | ||
- Too small, just **4K** gzipped. | ||
@@ -23,11 +23,6 @@ ## Overview | ||
- [Try **Flight.js** example on JSFiddle](http://jsfiddle.net/fkadev/1cw9Leau/) | ||
- [Try **Ractive.js** example on JSFiddle](http://jsfiddle.net/PhilJ/2r1k2k90/2/) | ||
--- | ||
## What is Flux | ||
Data in a Flux application flows in a single direction, in a cycle: | ||
![Flux Diagram](https://raw.githubusercontent.com/f/delorean/master/asset/flux-diagram.png) | ||
## Install | ||
@@ -53,316 +48,13 @@ | ||
## Stores | ||
## Docs | ||
> Stores contain the application state and logic. Their role is somewhat similar | ||
> to a model in a traditional MVC, but they manage the state of many objects — | ||
> they are not instances of one object. Nor are they the same as Backbone's | ||
> collections. More than simply managing a collection of ORM-style objects, | ||
> stores manage the application state for a particular domain within the application. | ||
### Basic Concepts | ||
### `Flux.createStore` | ||
- [**Store**: A postbox](./docs/store.md) | ||
- [**Dispatcher**: The postman, drops mails to the postboxes](./docs/dispatcher.md) | ||
- [**View**: Box owner, checks box for the mail](./docs/views.md) | ||
- [**Action Creator**: The post office, manages postmans](./docs/actions.md) | ||
```js | ||
var TodoStore = Flux.createStore({ | ||
Or you can visit [documents](./docs) page. | ||
todos: [ | ||
{text: 'hello'}, | ||
{text: 'world'} | ||
], | ||
actions: { | ||
'todo:add': 'addTodo', | ||
'todo:remove': 'removeTodo' | ||
}, | ||
addTodo: function (todo) { | ||
this.todos.push({text: todo.text}); | ||
this.emit('change'); | ||
}, | ||
removeTodo: function (todoToComplete) { | ||
this.todos = this.todos.filter(function (todo) { | ||
return todoToComplete.text !== todo.text | ||
}); | ||
this.emit('change'); | ||
}, | ||
getState: function () { | ||
return { | ||
todos: this.todos | ||
} | ||
} | ||
}); | ||
``` | ||
### `initialize` | ||
You may define an `initialize` function to run something on construction. In construction | ||
status, you may **do server actions**. *But **action creators** are more simple entity to | ||
do server actions.* | ||
```javascript | ||
var TodoStore = Flux.createStore({ | ||
todos: [ | ||
{text: 'hello'}, | ||
{text: 'world'} | ||
], | ||
initialize: function (url) { | ||
var self = this; | ||
$.getJSON(url, {}, function (data) { | ||
self.todos = data.todos; | ||
self.emit('change'); | ||
}); | ||
} | ||
}); | ||
var myTodos = new TodoStore('/todos'); | ||
``` | ||
#### Using `Array.observe` and `Object.observe`, or `listenChanges` | ||
You don't have to call `emit('change')` everytime. You may use **`observe`** feature | ||
of **ES.next**. | ||
```javascript | ||
var TodoStore = Flux.createStore({ | ||
todos: [ | ||
{text: 'hello'}, | ||
{text: 'world'} | ||
], | ||
initialize: function (url) { | ||
var self = this; | ||
// It will update store and Views everytime | ||
// you changed the data. | ||
Array.observe(this.todos, function () { | ||
self.emit('change'); | ||
}); | ||
$.getJSON(url, {}, function (data) { | ||
self.todos = data.todos; | ||
// You don't have to emit 'change' event. | ||
}); | ||
} | ||
}); | ||
var myTodos = new TodoStore('/todos'); | ||
``` | ||
Also you may use **`listenChanges`** method which is doing `Array.observe` | ||
or `Object.observe` already for you. | ||
```javascript | ||
... | ||
initialize: function (url) { | ||
var self = this; | ||
// It will basically runs `Array.observe` or `Object.observe` | ||
this.listenChanges(this.todos); | ||
$.getJSON(url, {}, function (data) { | ||
self.todos = data.todos; | ||
}); | ||
} | ||
... | ||
``` | ||
## Dispatcher | ||
> The dispatcher is the central hub that manages all data flow in a Flux application. | ||
> It is essentially a registry of callbacks into the stores. Each store registers | ||
> itself and provides a callback. When the dispatcher responds to an action, | ||
> all stores in the application are sent the data payload provided by the | ||
> action via the callbacks in the registry. | ||
### `Flux.createDispatcher` | ||
```js | ||
var TodoListApp = Flux.createDispatcher({ | ||
removeTodo: function (todo) { | ||
if (confirm('Do you really want to delete this todo?')) { | ||
this.dispatch('todo:remove', todo); | ||
} | ||
}, | ||
getStores: function () { | ||
return { | ||
todoStore: myTodos | ||
} | ||
} | ||
}); | ||
``` | ||
#### Action `dispatch` | ||
When an action is dispatched, all the stores know about the status and they | ||
process the data asynchronously. When all of them are finished the dispatcher | ||
emits `change:all` event, also `dispatch` method returns a promise. | ||
```js | ||
var TodoListApp = Flux.createDispatcher({ | ||
removeTodo: function (todo) { | ||
if (confirm('Do you really want to delete this todo?')) { | ||
this.dispatch('todo:remove', todo) | ||
.then(function () { | ||
// All of the stores finished the process | ||
// about 'todo:remove' action | ||
alert('Item removed successfully'); | ||
}); | ||
} | ||
}, | ||
getStores: function () { | ||
return { | ||
todoStore: myTodos | ||
} | ||
} | ||
}); | ||
``` | ||
## Action Creators | ||
Action creators are the main controller of the app. **They are simply objects** that | ||
manages everything. It allows you to compose data and logic. | ||
```javascript | ||
var TodoActionCreator = { | ||
getAllTodos: function () { | ||
// It's an example for async requests. | ||
// You can do a server request. | ||
$.getJSON('/todos', function (data) { | ||
TodoListDispatcher.reset(data.todos); | ||
}); | ||
}, | ||
addTodo: function (todo) { | ||
// It statically calls dispatchers. | ||
TodoListDispatcher.addTodo(todo); | ||
}, | ||
removeTodo: function (todo) { | ||
TodoListDispatcher.removeTodo(todo); | ||
} | ||
}; | ||
``` | ||
Then you can just run `TodoActionCreator.getAllTodos()` function **to start Flux cycle**. | ||
## Combining to React | ||
You may bring all the flow together with the Views, actually *the Action generators*. | ||
You should use **`Flux.mixins.storeListener`** mixin to get a view into the Flux system. | ||
Also you should pass `dispatcher={DispatcherName}` attribute to *main* React view. It will | ||
pass dispatcher all the child views which have `storeListener` mixin. | ||
```js | ||
// Child views don't have to have storeListener. | ||
var TodoItemView = React.createClass({ | ||
render: function (todo) { | ||
return <li onClick={this.handleClick}>{this.props.todo.text}</li> | ||
}, | ||
handleClick: function () { | ||
TodoActionCreator.removeTodo(this.props.todo); | ||
// or, this.props.dispatcher.removeTodo(this.props.todo); | ||
} | ||
}); | ||
var TodoListView = React.createClass({ | ||
mixins: [Flux.mixins.storeListener], | ||
render: function () { | ||
var self = this; | ||
return <ul> | ||
{this.stores.todoStore.store.todos.map(function (todo) { | ||
return <TodoItemView todo={todo}></TodoItemView> | ||
})} | ||
</ul> | ||
} | ||
}); | ||
``` | ||
### `storeDidChange` and `storesDidChange` | ||
Two functions are triggered when a store changed and all stores are changed. You can use | ||
these functions if your application needs. | ||
```js | ||
var TodoListView = React.createClass({ | ||
mixins: [Flux.mixins.storeListener], | ||
// when all stores are updated | ||
storesDidChange: function () { | ||
console.log("All stores are now updated."); | ||
}, | ||
// when a store updates | ||
storeDidChange: function (storeName) { | ||
console.log(storeName + " store is now updated."); | ||
}, | ||
render: function () { | ||
// ... | ||
} | ||
}); | ||
``` | ||
## Combining to Flight.js | ||
Since DeLorean.Flux doesn't require React, you can use it everywhere. Also in **Flight.js** | ||
```javascript | ||
var TodoCountUI = flight.component(function () { | ||
this.render = function () { | ||
this.$node.html(TodoListDispatcher.stores.todoStore.store.todos.length); | ||
}; | ||
this.after('initialize', function() { | ||
// You should listen changes | ||
TodoListDispatcher.on('change:all', this.render.bind(this)); | ||
this.render(); | ||
}); | ||
}); | ||
``` | ||
## Routing | ||
You can use any Router tool with DeLorean. In the example I use `director` as the router. | ||
```js | ||
var Router = require('director').Router; | ||
``` | ||
You may trig the action from View. So you can just do something like that: | ||
```js | ||
var mainView = React.renderComponent(<ApplicationView dispatcher={TodoListDispatcher} />, | ||
document.getElementById('main')) | ||
var appRouter = new Router({ | ||
'/random': function () { | ||
TodoActionCreator.addTodo({text: Math.random()}); | ||
location.hash = '/'; | ||
} | ||
}); | ||
``` | ||
## Running the TodoMVC example | ||
@@ -378,12 +70,2 @@ | ||
## TODO | ||
- Split README file into chapters. | ||
- Fix English grammar mistakes in README. | ||
- Draw the flow with SVG or something else. | ||
- Build a webpage. | ||
- Build Backbone.js plugin. | ||
- Build Flight.js mixin. | ||
- Seperate React and Flight mixins from source. | ||
## Name | ||
@@ -390,0 +72,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
980111
34
20433
184
16
74