Comparing version 0.1.15 to 0.2.0
{ | ||
"name": "reflux", | ||
"version": "0.1.15", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/spoike/reflux", | ||
@@ -5,0 +5,0 @@ "authors": [ |
@@ -5,2 +5,14 @@ # Changelog | ||
## v0.2.0 | ||
* Breaking change: Set initial state before componentDidMount (in `Reflux.connect`) [#117](https://github.com/spoike/refluxjs/pull/117) | ||
* Allow extension of actions and stores (with `Reflux.ActionMethods` and `Reflux.StoreMethods`) [#121](https://github.com/spoike/refluxjs/pull/121) | ||
* Automatically bind store methods [#100](https://github.com/spoike/refluxjs/pull/100) | ||
* Bugfix: Connect and listenermixin combo [#131](https://github.com/spoike/refluxjs/pull/131) | ||
## v0.1.14, v0.1.15 | ||
* You may now stop listening to joined listenables individually [#96](https://github.com/spoike/refluxjs/pull/96). | ||
* Reflux will now throw an error if you attempt to join less than two listenables [#97](https://github.com/spoike/refluxjs/pull/97). | ||
## v0.1.13 | ||
@@ -7,0 +19,0 @@ |
@@ -208,2 +208,10 @@ !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.Reflux=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){ | ||
},{}],2:[function(_dereq_,module,exports){ | ||
/** | ||
* A module of methods that you want to include in all actions. | ||
* This module is consumed by `createAction`. | ||
*/ | ||
module.exports = { | ||
}; | ||
},{}],3:[function(_dereq_,module,exports){ | ||
exports.createdStores = []; | ||
@@ -222,3 +230,3 @@ | ||
},{}],3:[function(_dereq_,module,exports){ | ||
},{}],4:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'), | ||
@@ -298,3 +306,3 @@ maker = _dereq_('./joins').instanceJoinCreator; | ||
_.throwIf(this.validateListening(listenable)); | ||
this.fetchDefaultData(listenable, defaultCallback); | ||
this.fetchInitialState(listenable, defaultCallback); | ||
desub = listenable.listen(this[callback]||callback, this); | ||
@@ -346,11 +354,11 @@ unsubscriber = function() { | ||
/** | ||
* Used in `listenTo`. Fetches initial data from a publisher if it has a `getDefaultData` method. | ||
* @param {Action|Store} listenable The publisher we want to get default data from | ||
* Used in `listenTo`. Fetches initial data from a publisher if it has a `getInitialState` method. | ||
* @param {Action|Store} listenable The publisher we want to get initial state from | ||
* @param {Function|String} defaultCallback The method to receive the data | ||
*/ | ||
fetchDefaultData: function (listenable, defaultCallback) { | ||
fetchInitialState: function (listenable, defaultCallback) { | ||
defaultCallback = (defaultCallback && this[defaultCallback]) || defaultCallback; | ||
var me = this; | ||
if (_.isFunction(defaultCallback) && _.isFunction(listenable.getDefaultData)) { | ||
data = listenable.getDefaultData(); | ||
if (_.isFunction(defaultCallback) && _.isFunction(listenable.getInitialState)) { | ||
data = listenable.getInitialState(); | ||
if (data && _.isFunction(data.then)) { | ||
@@ -403,4 +411,3 @@ data.then(function() { | ||
},{"./joins":10,"./utils":13}],4:[function(_dereq_,module,exports){ | ||
},{"./joins":13,"./utils":16}],5:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'), | ||
@@ -412,2 +419,4 @@ ListenerMethods = _dereq_('./ListenerMethods'); | ||
* `ListenerMethods` mixin and takes care of teardown of subscriptions. | ||
* Note that if you're using the `connect` mixin you don't need this mixin, as connect will | ||
* import everything this mixin contains! | ||
*/ | ||
@@ -423,3 +432,3 @@ module.exports = _.extend({ | ||
},{"./ListenerMethods":3,"./utils":13}],5:[function(_dereq_,module,exports){ | ||
},{"./ListenerMethods":4,"./utils":16}],6:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'); | ||
@@ -491,3 +500,26 @@ | ||
},{"./utils":13}],6:[function(_dereq_,module,exports){ | ||
},{"./utils":16}],7:[function(_dereq_,module,exports){ | ||
/** | ||
* A module of methods that you want to include in all stores. | ||
* This module is consumed by `createStore`. | ||
*/ | ||
module.exports = { | ||
}; | ||
},{}],8:[function(_dereq_,module,exports){ | ||
module.exports = function(store, definition) { | ||
for (var name in definition) { | ||
var property = definition[name]; | ||
if (typeof property !== 'function' || !definition.hasOwnProperty(name)) { | ||
continue; | ||
} | ||
store[name] = property.bind(store); | ||
} | ||
return store; | ||
}; | ||
},{}],9:[function(_dereq_,module,exports){ | ||
var Reflux = _dereq_('../src'), | ||
@@ -498,13 +530,27 @@ _ = _dereq_('./utils'); | ||
return { | ||
getInitialState: function(){ | ||
if (!_.isFunction(listenable.getInitialState)) { | ||
return {}; | ||
} else if (key === undefined) { | ||
return listenable.getInitialState(); | ||
} else { | ||
return _.object([key],[listenable.getInitialState()]); | ||
} | ||
}, | ||
componentDidMount: function(){ | ||
var warned = false; | ||
for(var m in Reflux.ListenerMethods){ | ||
if (this[m] !== Reflux.ListenerMethods[m]){ | ||
if (this[m]){ | ||
throw "Can't have other property '"+m+"' when using Reflux.listenTo!"; | ||
} | ||
this[m] = Reflux.ListenerMethods[m]; | ||
if (this[m] && typeof console && typeof console.warn === "function" && !warned ){ | ||
console.warn( | ||
"Component using Reflux.connect already had property '"+m+"'. "+ | ||
"Either you had your own property with that name which was now overridden, "+ | ||
"or you combined connect with ListenerMixin which is unnecessary as connect "+ | ||
"will include the ListenerMixin methods automatically." | ||
); | ||
warned = true; | ||
} | ||
this[m] = Reflux.ListenerMethods[m]; | ||
} | ||
var me = this, cb = (key === undefined ? this.setState : function(v){me.setState(_.object([key],[v]));}); | ||
this.listenTo(listenable,cb,cb); | ||
this.listenTo(listenable,cb); | ||
}, | ||
@@ -515,3 +561,3 @@ componentWillUnmount: Reflux.ListenerMixin.componentWillUnmount | ||
},{"../src":9,"./utils":13}],7:[function(_dereq_,module,exports){ | ||
},{"../src":12,"./utils":16}],10:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'), | ||
@@ -533,2 +579,10 @@ Reflux = _dereq_('../src'), | ||
for(var a in Reflux.ActionMethods){ | ||
if (!allowed[a] && Reflux.PublisherMethods[a]) { | ||
throw new Error("Cannot override API method " + a + | ||
" in Reflux.ActionMethods. Use another method name or override it on Reflux.PublisherMethods instead." | ||
); | ||
} | ||
} | ||
for(var d in definition){ | ||
@@ -546,3 +600,3 @@ if (!allowed[d] && Reflux.PublisherMethods[d]) { | ||
_isAction: true | ||
},Reflux.PublisherMethods,definition); | ||
}, Reflux.PublisherMethods, Reflux.ActionMethods, definition); | ||
@@ -561,7 +615,8 @@ var functor = function() { | ||
},{"../src":9,"./Keep":2,"./utils":13}],8:[function(_dereq_,module,exports){ | ||
},{"../src":12,"./Keep":3,"./utils":16}],11:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'), | ||
Reflux = _dereq_('../src'), | ||
Keep = _dereq_('./Keep'), | ||
allowed = {preEmit:1,shouldEmit:1}; | ||
allowed = {preEmit:1,shouldEmit:1}, | ||
bindMethods = _dereq_('./bindMethods'); | ||
@@ -580,2 +635,10 @@ /** | ||
for(var a in Reflux.StoreMethods){ | ||
if (!allowed[a] && (Reflux.PublisherMethods[a] || Reflux.ListenerMethods[a])){ | ||
throw new Error("Cannot override API method " + a + | ||
" in Reflux.StoreMethods. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead." | ||
); | ||
} | ||
} | ||
for(var d in definition){ | ||
@@ -605,5 +668,6 @@ if (!allowed[d] && (Reflux.PublisherMethods[d] || Reflux.ListenerMethods[d])){ | ||
_.extend(Store.prototype, Reflux.ListenerMethods, Reflux.PublisherMethods, definition); | ||
_.extend(Store.prototype, Reflux.ListenerMethods, Reflux.PublisherMethods, Reflux.StoreMethods, definition); | ||
var store = new Store(); | ||
bindMethods(store, definition); | ||
Keep.createdStores.push(store); | ||
@@ -614,3 +678,5 @@ | ||
},{"../src":9,"./Keep":2,"./utils":13}],9:[function(_dereq_,module,exports){ | ||
},{"../src":12,"./Keep":3,"./bindMethods":8,"./utils":16}],12:[function(_dereq_,module,exports){ | ||
exports.ActionMethods = _dereq_('./ActionMethods'); | ||
exports.ListenerMethods = _dereq_('./ListenerMethods'); | ||
@@ -620,2 +686,4 @@ | ||
exports.StoreMethods = _dereq_('./StoreMethods'); | ||
exports.createAction = _dereq_('./createAction'); | ||
@@ -680,4 +748,15 @@ | ||
},{"./Keep":2,"./ListenerMethods":3,"./ListenerMixin":4,"./PublisherMethods":5,"./connect":6,"./createAction":7,"./createStore":8,"./joins":10,"./listenTo":11,"./listenToMany":12,"./utils":13}],10:[function(_dereq_,module,exports){ | ||
/** | ||
* Warn if Function.prototype.bind not available | ||
*/ | ||
if (!Function.prototype.bind) { | ||
console.error( | ||
'Function.prototype.bind not available. ' + | ||
'ES5 shim required. ' + | ||
'https://github.com/spoike/refluxjs#es5' | ||
); | ||
} | ||
},{"./ActionMethods":2,"./Keep":3,"./ListenerMethods":4,"./ListenerMixin":5,"./PublisherMethods":6,"./StoreMethods":7,"./connect":9,"./createAction":10,"./createStore":11,"./joins":13,"./listenTo":14,"./listenToMany":15,"./utils":16}],13:[function(_dereq_,module,exports){ | ||
/** | ||
* Internal module used to create static and instance join methods | ||
@@ -789,3 +868,3 @@ */ | ||
},{"./createStore":8,"./utils":13}],11:[function(_dereq_,module,exports){ | ||
},{"./createStore":11,"./utils":16}],14:[function(_dereq_,module,exports){ | ||
var Reflux = _dereq_('../src'); | ||
@@ -828,3 +907,3 @@ | ||
},{"../src":9}],12:[function(_dereq_,module,exports){ | ||
},{"../src":12}],15:[function(_dereq_,module,exports){ | ||
var Reflux = _dereq_('../src'); | ||
@@ -864,3 +943,3 @@ | ||
},{"../src":9}],13:[function(_dereq_,module,exports){ | ||
},{"../src":12}],16:[function(_dereq_,module,exports){ | ||
/* | ||
@@ -922,4 +1001,4 @@ * isObject, extend, isFunction, isArguments are taken from undescore/lodash in | ||
},{"eventemitter3":1}]},{},[9]) | ||
(9) | ||
},{"eventemitter3":1}]},{},[12]) | ||
(12) | ||
}); |
@@ -1,1 +0,1 @@ | ||
!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.Reflux=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){"use strict";function c(a,b,c){this.fn=a,this.context=b,this.once=c||!1}function d(){}d.prototype._events=void 0,d.prototype.listeners=function(a){if(!this._events||!this._events[a])return[];for(var b=0,c=this._events[a].length,d=[];c>b;b++)d.push(this._events[a][b].fn);return d},d.prototype.emit=function(a,b,c,d,e,f){if(!this._events||!this._events[a])return!1;var g,h,i,j=this._events[a],k=j.length,l=arguments.length,m=j[0];if(1===k){switch(m.once&&this.removeListener(a,m.fn,!0),l){case 1:return m.fn.call(m.context),!0;case 2:return m.fn.call(m.context,b),!0;case 3:return m.fn.call(m.context,b,c),!0;case 4:return m.fn.call(m.context,b,c,d),!0;case 5:return m.fn.call(m.context,b,c,d,e),!0;case 6:return m.fn.call(m.context,b,c,d,e,f),!0}for(h=1,g=new Array(l-1);l>h;h++)g[h-1]=arguments[h];m.fn.apply(m.context,g)}else for(h=0;k>h;h++)switch(j[h].once&&this.removeListener(a,j[h].fn,!0),l){case 1:j[h].fn.call(j[h].context);break;case 2:j[h].fn.call(j[h].context,b);break;case 3:j[h].fn.call(j[h].context,b,c);break;default:if(!g)for(i=1,g=new Array(l-1);l>i;i++)g[i-1]=arguments[i];j[h].fn.apply(j[h].context,g)}return!0},d.prototype.on=function(a,b,d){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),this._events[a].push(new c(b,d||this)),this},d.prototype.once=function(a,b,d){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),this._events[a].push(new c(b,d||this,!0)),this},d.prototype.removeListener=function(a,b,c){if(!this._events||!this._events[a])return this;var d=this._events[a],e=[];if(b)for(var f=0,g=d.length;g>f;f++)d[f].fn!==b&&d[f].once!==c&&e.push(d[f]);return this._events[a]=e.length?e:null,this},d.prototype.removeAllListeners=function(a){return this._events?(a?this._events[a]=null:this._events={},this):this},d.prototype.off=d.prototype.removeListener,d.prototype.addListener=d.prototype.on,d.prototype.setMaxListeners=function(){return this},d.EventEmitter=d,d.EventEmitter2=d,d.EventEmitter3=d,"object"==typeof b&&b.exports&&(b.exports=d)},{}],2:[function(a,b,c){c.createdStores=[],c.createdActions=[],c.reset=function(){for(;c.createdStores.length;)c.createdStores.pop();for(;c.createdActions.length;)c.createdActions.pop()}},{}],3:[function(a,b){var c=a("./utils"),d=a("./joins").instanceJoinCreator;b.exports={hasListener:function(a){for(var b,c,d,e=0;e<(this.subscriptions||[]).length;++e)for(d=[].concat(this.subscriptions[e].listenable),b=0;b<d.length;b++)if(c=d[b],c===a||c.hasListener&&c.hasListener(a))return!0;return!1},listenToMany:function(a){for(var b in a){var d=c.callbackName(b),e=this[d]?d:this[b]?b:void 0;e&&this.listenTo(a[b],e,this[d+"Default"]||this[e+"Default"]||e)}},validateListening:function(a){return a===this?"Listener is not able to listen to itself":c.isFunction(a.listen)?a.hasListener&&a.hasListener(this)?"Listener cannot listen to this listenable because of circular loop":void 0:a+" is missing a listen method"},listenTo:function(a,b,d){var e,f,g,h=this.subscriptions=this.subscriptions||[];return c.throwIf(this.validateListening(a)),this.fetchDefaultData(a,d),e=a.listen(this[b]||b,this),f=function(){var a=h.indexOf(g);c.throwIf(-1===a,"Tried to remove listen already gone from subscriptions list!"),h.splice(a,1),e()},g={stop:f,listenable:a},h.push(g),g},stopListeningTo:function(a){for(var b,d=0,e=this.subscriptions||[];d<e.length;d++)if(b=e[d],b.listenable===a)return b.stop(),c.throwIf(-1!==e.indexOf(b),"Failed to remove listen from subscriptions list!"),!0;return!1},stopListeningToAll:function(){for(var a,b=this.subscriptions||[];a=b.length;)b[0].stop(),c.throwIf(b.length!==a-1,"Failed to remove listen from subscriptions list!")},fetchDefaultData:function(a,b){b=b&&this[b]||b;var d=this;c.isFunction(b)&&c.isFunction(a.getDefaultData)&&(data=a.getDefaultData(),data&&c.isFunction(data.then)?data.then(function(){b.apply(d,arguments)}):b.call(this,data))},joinTrailing:d("last"),joinLeading:d("first"),joinConcat:d("all"),joinStrict:d("strict")}},{"./joins":10,"./utils":13}],4:[function(a,b){var c=a("./utils"),d=a("./ListenerMethods");b.exports=c.extend({componentWillUnmount:d.stopListeningToAll},d)},{"./ListenerMethods":3,"./utils":13}],5:[function(a,b){var c=a("./utils");b.exports={preEmit:function(){},shouldEmit:function(){return!0},listen:function(a,b){var c=function(c){a.apply(b,c)},d=this;return this.emitter.addListener(this.eventLabel,c),function(){d.emitter.removeListener(d.eventLabel,c)}},trigger:function(){var a=arguments,b=this.preEmit.apply(this,a);a=void 0===b?a:c.isArguments(b)?b:[].concat(b),this.shouldEmit.apply(this,a)&&this.emitter.emit(this.eventLabel,a)},triggerAsync:function(){var a=arguments,b=this;c.nextTick(function(){b.trigger.apply(b,a)})}}},{"./utils":13}],6:[function(a,b){var c=a("../src"),d=a("./utils");b.exports=function(a,b){return{componentDidMount:function(){for(var e in c.ListenerMethods)if(this[e]!==c.ListenerMethods[e]){if(this[e])throw"Can't have other property '"+e+"' when using Reflux.listenTo!";this[e]=c.ListenerMethods[e]}var f=this,g=void 0===b?this.setState:function(a){f.setState(d.object([b],[a]))};this.listenTo(a,g,g)},componentWillUnmount:c.ListenerMixin.componentWillUnmount}}},{"../src":9,"./utils":13}],7:[function(a,b){var c=a("./utils"),d=a("../src"),e=a("./Keep"),f={preEmit:1,shouldEmit:1};b.exports=function(a){a=a||{};for(var b in a)if(!f[b]&&d.PublisherMethods[b])throw new Error("Cannot override API method "+b+" in action creation. Use another method name or override it on Reflux.PublisherMethods instead.");var g=c.extend({eventLabel:"action",emitter:new c.EventEmitter,_isAction:!0},d.PublisherMethods,a),h=function(){h[h.sync?"trigger":"triggerAsync"].apply(h,arguments)};return c.extend(h,g),e.createdActions.push(h),h}},{"../src":9,"./Keep":2,"./utils":13}],8:[function(a,b){var c=a("./utils"),d=a("../src"),e=a("./Keep"),f={preEmit:1,shouldEmit:1};b.exports=function(a){function b(){var a,b=0;if(this.subscriptions=[],this.emitter=new c.EventEmitter,this.eventLabel="change",this.init&&c.isFunction(this.init)&&this.init(),this.listenables)for(a=[].concat(this.listenables);b<a.length;b++)this.listenToMany(a[b])}a=a||{};for(var g in a)if(!f[g]&&(d.PublisherMethods[g]||d.ListenerMethods[g]))throw new Error("Cannot override API method "+g+" in store creation. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead.");c.extend(b.prototype,d.ListenerMethods,d.PublisherMethods,a);var h=new b;return e.createdStores.push(h),h}},{"../src":9,"./Keep":2,"./utils":13}],9:[function(a,b,c){c.ListenerMethods=a("./ListenerMethods"),c.PublisherMethods=a("./PublisherMethods"),c.createAction=a("./createAction"),c.createStore=a("./createStore"),c.connect=a("./connect"),c.ListenerMixin=a("./ListenerMixin"),c.listenTo=a("./listenTo"),c.listenToMany=a("./listenToMany");var d=a("./joins").staticJoinCreator;c.joinTrailing=c.all=d("last"),c.joinLeading=d("first"),c.joinStrict=d("strict"),c.joinConcat=d("all"),c.createActions=function(a){for(var b=0,d={};b<a.length;b++)d[a[b]]=c.createAction();return d},c.setEventEmitter=function(b){var c=a("./utils");c.EventEmitter=b},c.nextTick=function(b){var c=a("./utils");c.nextTick=b},c.__keep=a("./Keep")},{"./Keep":2,"./ListenerMethods":3,"./ListenerMixin":4,"./PublisherMethods":5,"./connect":6,"./createAction":7,"./createStore":8,"./joins":10,"./listenTo":11,"./listenToMany":12,"./utils":13}],10:[function(a,b,c){function d(a,b,c){return function(){var d,e=c.subscriptions;for(index=e?e.indexOf(a):-1,i.throwIf(-1===index,"Tried to remove join already gone from subscriptions list!"),d=0;d<b.length;d++)b[d]();e.splice(index,1)}}function e(a){a.listenablesEmitted=new Array(a.numberOfListenables),a.args=new Array(a.numberOfListenables)}function f(a,b){return function(){var c=h.call(arguments);if(b.listenablesEmitted[a])switch(b.strategy){case"strict":throw new Error("Strict join failed because listener triggered twice.");case"last":b.args[a]=c;break;case"all":b.args[a].push(c)}else b.listenablesEmitted[a]=!0,b.args[a]="all"===b.strategy?[c]:c;g(b)}}function g(a){for(var b=0;b<a.numberOfListenables;b++)if(!a.listenablesEmitted[b])return;a.callback.apply(a.listener,a.args),e(a)}var h=Array.prototype.slice,i=a("./utils"),j=a("./createStore"),k={strict:"joinStrict",first:"joinLeading",last:"joinTrailing",all:"joinConcat"};c.staticJoinCreator=function(a){return function(){var b=h.call(arguments);return j({init:function(){this[k[a]].apply(this,b.concat("triggerAsync"))}})}},c.instanceJoinCreator=function(a){return function(){i.throwIf(arguments.length<3,"Cannot create a join with less than 2 listenables!");var b,c,g=h.call(arguments),j=g.pop(),k=g.length,l={numberOfListenables:k,callback:this[j]||j,listener:this,strategy:a},m=[];for(b=0;k>b;b++)i.throwIf(this.validateListening(g[b]));for(b=0;k>b;b++)m.push(g[b].listen(f(b,l),this));return e(l),c={listenable:g},c.stop=d(c,m,this),this.subscriptions=(this.subscriptions||[]).concat(c),c}}},{"./createStore":8,"./utils":13}],11:[function(a,b){var c=a("../src");b.exports=function(a,b,d){return{componentDidMount:function(){for(var e in c.ListenerMethods)if(this[e]!==c.ListenerMethods[e]){if(this[e])throw"Can't have other property '"+e+"' when using Reflux.listenTo!";this[e]=c.ListenerMethods[e]}this.listenTo(a,b,d)},componentWillUnmount:c.ListenerMethods.stopListeningToAll}}},{"../src":9}],12:[function(a,b){var c=a("../src");b.exports=function(a){return{componentDidMount:function(){for(var b in c.ListenerMethods)if(this[b]!==c.ListenerMethods[b]){if(this[b])throw"Can't have other property '"+b+"' when using Reflux.listenToMany!";this[b]=c.ListenerMethods[b]}this.listenToMany(a)},componentWillUnmount:c.ListenerMethods.stopListeningToAll}}},{"../src":9}],13:[function(a,b,c){var d=c.isObject=function(a){var b=typeof a;return"function"===b||"object"===b&&!!a};c.extend=function(a){if(!d(a))return a;for(var b,c,e=1,f=arguments.length;f>e;e++){b=arguments[e];for(c in b)a[c]=b[c]}return a},c.isFunction=function(a){return"function"==typeof a},c.EventEmitter=a("eventemitter3"),c.nextTick=function(a){setTimeout(a,0)},c.callbackName=function(a){return"on"+a.charAt(0).toUpperCase()+a.slice(1)},c.object=function(a,b){for(var c={},d=0;d<a.length;d++)c[a[d]]=b[d];return c},c.isArguments=function(a){return a&&"object"==typeof a&&"number"==typeof a.length&&("[object Arguments]"===toString.call(a)||hasOwnProperty.call(a,"callee"&&!propertyIsEnumerable.call(a,"callee")))||!1},c.throwIf=function(a,b){if(a)throw Error(b||a)}},{eventemitter3:1}]},{},[9])(9)}); | ||
!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.Reflux=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){"use strict";function c(a,b,c){this.fn=a,this.context=b,this.once=c||!1}function d(){}d.prototype._events=void 0,d.prototype.listeners=function(a){if(!this._events||!this._events[a])return[];for(var b=0,c=this._events[a].length,d=[];c>b;b++)d.push(this._events[a][b].fn);return d},d.prototype.emit=function(a,b,c,d,e,f){if(!this._events||!this._events[a])return!1;var g,h,i,j=this._events[a],k=j.length,l=arguments.length,m=j[0];if(1===k){switch(m.once&&this.removeListener(a,m.fn,!0),l){case 1:return m.fn.call(m.context),!0;case 2:return m.fn.call(m.context,b),!0;case 3:return m.fn.call(m.context,b,c),!0;case 4:return m.fn.call(m.context,b,c,d),!0;case 5:return m.fn.call(m.context,b,c,d,e),!0;case 6:return m.fn.call(m.context,b,c,d,e,f),!0}for(h=1,g=new Array(l-1);l>h;h++)g[h-1]=arguments[h];m.fn.apply(m.context,g)}else for(h=0;k>h;h++)switch(j[h].once&&this.removeListener(a,j[h].fn,!0),l){case 1:j[h].fn.call(j[h].context);break;case 2:j[h].fn.call(j[h].context,b);break;case 3:j[h].fn.call(j[h].context,b,c);break;default:if(!g)for(i=1,g=new Array(l-1);l>i;i++)g[i-1]=arguments[i];j[h].fn.apply(j[h].context,g)}return!0},d.prototype.on=function(a,b,d){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),this._events[a].push(new c(b,d||this)),this},d.prototype.once=function(a,b,d){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),this._events[a].push(new c(b,d||this,!0)),this},d.prototype.removeListener=function(a,b,c){if(!this._events||!this._events[a])return this;var d=this._events[a],e=[];if(b)for(var f=0,g=d.length;g>f;f++)d[f].fn!==b&&d[f].once!==c&&e.push(d[f]);return this._events[a]=e.length?e:null,this},d.prototype.removeAllListeners=function(a){return this._events?(a?this._events[a]=null:this._events={},this):this},d.prototype.off=d.prototype.removeListener,d.prototype.addListener=d.prototype.on,d.prototype.setMaxListeners=function(){return this},d.EventEmitter=d,d.EventEmitter2=d,d.EventEmitter3=d,"object"==typeof b&&b.exports&&(b.exports=d)},{}],2:[function(a,b){b.exports={}},{}],3:[function(a,b,c){c.createdStores=[],c.createdActions=[],c.reset=function(){for(;c.createdStores.length;)c.createdStores.pop();for(;c.createdActions.length;)c.createdActions.pop()}},{}],4:[function(a,b){var c=a("./utils"),d=a("./joins").instanceJoinCreator;b.exports={hasListener:function(a){for(var b,c,d,e=0;e<(this.subscriptions||[]).length;++e)for(d=[].concat(this.subscriptions[e].listenable),b=0;b<d.length;b++)if(c=d[b],c===a||c.hasListener&&c.hasListener(a))return!0;return!1},listenToMany:function(a){for(var b in a){var d=c.callbackName(b),e=this[d]?d:this[b]?b:void 0;e&&this.listenTo(a[b],e,this[d+"Default"]||this[e+"Default"]||e)}},validateListening:function(a){return a===this?"Listener is not able to listen to itself":c.isFunction(a.listen)?a.hasListener&&a.hasListener(this)?"Listener cannot listen to this listenable because of circular loop":void 0:a+" is missing a listen method"},listenTo:function(a,b,d){var e,f,g,h=this.subscriptions=this.subscriptions||[];return c.throwIf(this.validateListening(a)),this.fetchInitialState(a,d),e=a.listen(this[b]||b,this),f=function(){var a=h.indexOf(g);c.throwIf(-1===a,"Tried to remove listen already gone from subscriptions list!"),h.splice(a,1),e()},g={stop:f,listenable:a},h.push(g),g},stopListeningTo:function(a){for(var b,d=0,e=this.subscriptions||[];d<e.length;d++)if(b=e[d],b.listenable===a)return b.stop(),c.throwIf(-1!==e.indexOf(b),"Failed to remove listen from subscriptions list!"),!0;return!1},stopListeningToAll:function(){for(var a,b=this.subscriptions||[];a=b.length;)b[0].stop(),c.throwIf(b.length!==a-1,"Failed to remove listen from subscriptions list!")},fetchInitialState:function(a,b){b=b&&this[b]||b;var d=this;c.isFunction(b)&&c.isFunction(a.getInitialState)&&(data=a.getInitialState(),data&&c.isFunction(data.then)?data.then(function(){b.apply(d,arguments)}):b.call(this,data))},joinTrailing:d("last"),joinLeading:d("first"),joinConcat:d("all"),joinStrict:d("strict")}},{"./joins":13,"./utils":16}],5:[function(a,b){var c=a("./utils"),d=a("./ListenerMethods");b.exports=c.extend({componentWillUnmount:d.stopListeningToAll},d)},{"./ListenerMethods":4,"./utils":16}],6:[function(a,b){var c=a("./utils");b.exports={preEmit:function(){},shouldEmit:function(){return!0},listen:function(a,b){var c=function(c){a.apply(b,c)},d=this;return this.emitter.addListener(this.eventLabel,c),function(){d.emitter.removeListener(d.eventLabel,c)}},trigger:function(){var a=arguments,b=this.preEmit.apply(this,a);a=void 0===b?a:c.isArguments(b)?b:[].concat(b),this.shouldEmit.apply(this,a)&&this.emitter.emit(this.eventLabel,a)},triggerAsync:function(){var a=arguments,b=this;c.nextTick(function(){b.trigger.apply(b,a)})}}},{"./utils":16}],7:[function(a,b){b.exports={}},{}],8:[function(a,b){b.exports=function(a,b){for(var c in b){var d=b[c];"function"==typeof d&&b.hasOwnProperty(c)&&(a[c]=d.bind(a))}return a}},{}],9:[function(a,b){var c=a("../src"),d=a("./utils");b.exports=function(a,b){return{getInitialState:function(){return d.isFunction(a.getInitialState)?void 0===b?a.getInitialState():d.object([b],[a.getInitialState()]):{}},componentDidMount:function(){var e=!1;for(var f in c.ListenerMethods)this[f]&&"function"==typeof console.warn&&!e&&(console.warn("Component using Reflux.connect already had property '"+f+"'. Either you had your own property with that name which was now overridden, or you combined connect with ListenerMixin which is unnecessary as connect will include the ListenerMixin methods automatically."),e=!0),this[f]=c.ListenerMethods[f];var g=this,h=void 0===b?this.setState:function(a){g.setState(d.object([b],[a]))};this.listenTo(a,h)},componentWillUnmount:c.ListenerMixin.componentWillUnmount}}},{"../src":12,"./utils":16}],10:[function(a,b){var c=a("./utils"),d=a("../src"),e=a("./Keep"),f={preEmit:1,shouldEmit:1};b.exports=function(a){a=a||{};for(var b in d.ActionMethods)if(!f[b]&&d.PublisherMethods[b])throw new Error("Cannot override API method "+b+" in Reflux.ActionMethods. Use another method name or override it on Reflux.PublisherMethods instead.");for(var g in a)if(!f[g]&&d.PublisherMethods[g])throw new Error("Cannot override API method "+g+" in action creation. Use another method name or override it on Reflux.PublisherMethods instead.");var h=c.extend({eventLabel:"action",emitter:new c.EventEmitter,_isAction:!0},d.PublisherMethods,d.ActionMethods,a),i=function(){i[i.sync?"trigger":"triggerAsync"].apply(i,arguments)};return c.extend(i,h),e.createdActions.push(i),i}},{"../src":12,"./Keep":3,"./utils":16}],11:[function(a,b){var c=a("./utils"),d=a("../src"),e=a("./Keep"),f={preEmit:1,shouldEmit:1},g=a("./bindMethods");b.exports=function(a){function b(){var a,b=0;if(this.subscriptions=[],this.emitter=new c.EventEmitter,this.eventLabel="change",this.init&&c.isFunction(this.init)&&this.init(),this.listenables)for(a=[].concat(this.listenables);b<a.length;b++)this.listenToMany(a[b])}a=a||{};for(var h in d.StoreMethods)if(!f[h]&&(d.PublisherMethods[h]||d.ListenerMethods[h]))throw new Error("Cannot override API method "+h+" in Reflux.StoreMethods. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead.");for(var i in a)if(!f[i]&&(d.PublisherMethods[i]||d.ListenerMethods[i]))throw new Error("Cannot override API method "+i+" in store creation. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead.");c.extend(b.prototype,d.ListenerMethods,d.PublisherMethods,d.StoreMethods,a);var j=new b;return g(j,a),e.createdStores.push(j),j}},{"../src":12,"./Keep":3,"./bindMethods":8,"./utils":16}],12:[function(a,b,c){c.ActionMethods=a("./ActionMethods"),c.ListenerMethods=a("./ListenerMethods"),c.PublisherMethods=a("./PublisherMethods"),c.StoreMethods=a("./StoreMethods"),c.createAction=a("./createAction"),c.createStore=a("./createStore"),c.connect=a("./connect"),c.ListenerMixin=a("./ListenerMixin"),c.listenTo=a("./listenTo"),c.listenToMany=a("./listenToMany");var d=a("./joins").staticJoinCreator;c.joinTrailing=c.all=d("last"),c.joinLeading=d("first"),c.joinStrict=d("strict"),c.joinConcat=d("all"),c.createActions=function(a){for(var b=0,d={};b<a.length;b++)d[a[b]]=c.createAction();return d},c.setEventEmitter=function(b){var c=a("./utils");c.EventEmitter=b},c.nextTick=function(b){var c=a("./utils");c.nextTick=b},c.__keep=a("./Keep"),Function.prototype.bind||console.error("Function.prototype.bind not available. ES5 shim required. https://github.com/spoike/refluxjs#es5")},{"./ActionMethods":2,"./Keep":3,"./ListenerMethods":4,"./ListenerMixin":5,"./PublisherMethods":6,"./StoreMethods":7,"./connect":9,"./createAction":10,"./createStore":11,"./joins":13,"./listenTo":14,"./listenToMany":15,"./utils":16}],13:[function(a,b,c){function d(a,b,c){return function(){var d,e=c.subscriptions;for(index=e?e.indexOf(a):-1,i.throwIf(-1===index,"Tried to remove join already gone from subscriptions list!"),d=0;d<b.length;d++)b[d]();e.splice(index,1)}}function e(a){a.listenablesEmitted=new Array(a.numberOfListenables),a.args=new Array(a.numberOfListenables)}function f(a,b){return function(){var c=h.call(arguments);if(b.listenablesEmitted[a])switch(b.strategy){case"strict":throw new Error("Strict join failed because listener triggered twice.");case"last":b.args[a]=c;break;case"all":b.args[a].push(c)}else b.listenablesEmitted[a]=!0,b.args[a]="all"===b.strategy?[c]:c;g(b)}}function g(a){for(var b=0;b<a.numberOfListenables;b++)if(!a.listenablesEmitted[b])return;a.callback.apply(a.listener,a.args),e(a)}var h=Array.prototype.slice,i=a("./utils"),j=a("./createStore"),k={strict:"joinStrict",first:"joinLeading",last:"joinTrailing",all:"joinConcat"};c.staticJoinCreator=function(a){return function(){var b=h.call(arguments);return j({init:function(){this[k[a]].apply(this,b.concat("triggerAsync"))}})}},c.instanceJoinCreator=function(a){return function(){i.throwIf(arguments.length<3,"Cannot create a join with less than 2 listenables!");var b,c,g=h.call(arguments),j=g.pop(),k=g.length,l={numberOfListenables:k,callback:this[j]||j,listener:this,strategy:a},m=[];for(b=0;k>b;b++)i.throwIf(this.validateListening(g[b]));for(b=0;k>b;b++)m.push(g[b].listen(f(b,l),this));return e(l),c={listenable:g},c.stop=d(c,m,this),this.subscriptions=(this.subscriptions||[]).concat(c),c}}},{"./createStore":11,"./utils":16}],14:[function(a,b){var c=a("../src");b.exports=function(a,b,d){return{componentDidMount:function(){for(var e in c.ListenerMethods)if(this[e]!==c.ListenerMethods[e]){if(this[e])throw"Can't have other property '"+e+"' when using Reflux.listenTo!";this[e]=c.ListenerMethods[e]}this.listenTo(a,b,d)},componentWillUnmount:c.ListenerMethods.stopListeningToAll}}},{"../src":12}],15:[function(a,b){var c=a("../src");b.exports=function(a){return{componentDidMount:function(){for(var b in c.ListenerMethods)if(this[b]!==c.ListenerMethods[b]){if(this[b])throw"Can't have other property '"+b+"' when using Reflux.listenToMany!";this[b]=c.ListenerMethods[b]}this.listenToMany(a)},componentWillUnmount:c.ListenerMethods.stopListeningToAll}}},{"../src":12}],16:[function(a,b,c){var d=c.isObject=function(a){var b=typeof a;return"function"===b||"object"===b&&!!a};c.extend=function(a){if(!d(a))return a;for(var b,c,e=1,f=arguments.length;f>e;e++){b=arguments[e];for(c in b)a[c]=b[c]}return a},c.isFunction=function(a){return"function"==typeof a},c.EventEmitter=a("eventemitter3"),c.nextTick=function(a){setTimeout(a,0)},c.callbackName=function(a){return"on"+a.charAt(0).toUpperCase()+a.slice(1)},c.object=function(a,b){for(var c={},d=0;d<a.length;d++)c[a[d]]=b[d];return c},c.isArguments=function(a){return a&&"object"==typeof a&&"number"==typeof a.length&&("[object Arguments]"===toString.call(a)||hasOwnProperty.call(a,"callee"&&!propertyIsEnumerable.call(a,"callee")))||!1},c.throwIf=function(a,b){if(a)throw Error(b||a)}},{eventemitter3:1}]},{},[12])(12)}); |
@@ -16,2 +16,3 @@ module.exports = function(config) { | ||
files: [ | ||
'test/shims/phantomjs-shims.js', | ||
'test/*.spec.js' | ||
@@ -18,0 +19,0 @@ ], |
{ | ||
"name": "reflux", | ||
"version": "0.1.15", | ||
"version": "0.2.0", | ||
"description": "A simple library for uni-directional dataflow application architecture inspired by ReactJS Flux", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -73,2 +73,6 @@ # RefluxJS | ||
### ES5 | ||
Like React, Reflux depends on an es5-shim for older browsers. The es5-shim.js from [kriskowal's es5-shim](https://github.com/kriskowal/es5-shim) provides everything required. | ||
## Usage | ||
@@ -113,3 +117,3 @@ | ||
There are a couple of hooks avaiable for each action. | ||
There are a couple of hooks available for each action. | ||
@@ -142,2 +146,15 @@ * `preEmit` - Is called before the action emits an event. It receives the arguments from the action invocation. If it returns something other than undefined, that will be used as arguments for `shouldEmit` and subsequent emission. | ||
#### Reflux.ActionMethods | ||
If you would like to have a common set of methods available to all actions you can extend the `Reflux.ActionMethods` object, which is mixed into the actions when they are created. | ||
Example usage: | ||
```javascript | ||
Reflux.ActionMethods.exampleMethod = function() { console.log(arguments); }; | ||
Actions.statusUpdate.exampleMethod('arg1'); | ||
// Should output: 'arg1' | ||
``` | ||
### Creating data stores | ||
@@ -173,2 +190,15 @@ | ||
#### Reflux.StoreMethods | ||
If you would like to have a common set of methods available to all stores you can extend the `Reflux.StoreMethods` object, which is mixed into the stores when they are created. | ||
Example usage: | ||
```javascript | ||
Reflux.StoreMethods.exampleMethod = function() { console.log(arguments); }; | ||
statusStore.exampleMethod('arg1'); | ||
// Should output: 'arg1' | ||
``` | ||
#### Listening to many actions at once | ||
@@ -435,3 +465,3 @@ | ||
All objects using the listener API (stores, React components using `ListenerMixin`, or other components using the `ListenerMethods`) gain access to the four join instance methods, named after the argument strategy. Here's an example saving the last emission from each publisher: | ||
All objects using the listener API (stores, React components using `ListenerMixin`, or other components using the `ListenerMethods`) gain access to the four join instance methods, named after the argument strategy. Here's an example saving the last emission from each publisher: | ||
@@ -460,5 +490,5 @@ ```javascript | ||
### Sending default data with the listenTo function | ||
### Sending initial state with the listenTo function | ||
The `listenTo` function provided by the `Store` and the `ListenerMixin` has a third parameter that accepts a callback. This callback will be invoked when the listener is registered with whatever the `getDefaultData` is returning. | ||
The `listenTo` function provided by the `Store` and the `ListenerMixin` has a third parameter that accepts a callback. This callback will be invoked when the listener is registered with whatever the `getInitialState` is returning. | ||
@@ -468,3 +498,3 @@ ```javascript | ||
init: function() {}, | ||
getDefaultData: function() { | ||
getInitialState: function() { | ||
return "the initial data"; | ||
@@ -480,3 +510,3 @@ } | ||
Remember the `listenToMany` method? In case you use that with other stores, it supports `getDefaultData`. That data is sent to the normal listening callback, or a `this.on<Listenablename>Default` method if that exists. | ||
Remember the `listenToMany` method? In case you use that with other stores, it supports `getInitialState`. That data is sent to the normal listening callback, or a `this.on<Listenablename>Default` method if that exists. | ||
@@ -483,0 +513,0 @@ ## Colophon |
@@ -6,13 +6,27 @@ var Reflux = require('../src'), | ||
return { | ||
getInitialState: function(){ | ||
if (!_.isFunction(listenable.getInitialState)) { | ||
return {}; | ||
} else if (key === undefined) { | ||
return listenable.getInitialState(); | ||
} else { | ||
return _.object([key],[listenable.getInitialState()]); | ||
} | ||
}, | ||
componentDidMount: function(){ | ||
var warned = false; | ||
for(var m in Reflux.ListenerMethods){ | ||
if (this[m] !== Reflux.ListenerMethods[m]){ | ||
if (this[m]){ | ||
throw "Can't have other property '"+m+"' when using Reflux.listenTo!"; | ||
} | ||
this[m] = Reflux.ListenerMethods[m]; | ||
if (this[m] && typeof console && typeof console.warn === "function" && !warned ){ | ||
console.warn( | ||
"Component using Reflux.connect already had property '"+m+"'. "+ | ||
"Either you had your own property with that name which was now overridden, "+ | ||
"or you combined connect with ListenerMixin which is unnecessary as connect "+ | ||
"will include the ListenerMixin methods automatically." | ||
); | ||
warned = true; | ||
} | ||
this[m] = Reflux.ListenerMethods[m]; | ||
} | ||
var me = this, cb = (key === undefined ? this.setState : function(v){me.setState(_.object([key],[v]));}); | ||
this.listenTo(listenable,cb,cb); | ||
this.listenTo(listenable,cb); | ||
}, | ||
@@ -19,0 +33,0 @@ componentWillUnmount: Reflux.ListenerMixin.componentWillUnmount |
@@ -17,2 +17,10 @@ var _ = require('./utils'), | ||
for(var a in Reflux.ActionMethods){ | ||
if (!allowed[a] && Reflux.PublisherMethods[a]) { | ||
throw new Error("Cannot override API method " + a + | ||
" in Reflux.ActionMethods. Use another method name or override it on Reflux.PublisherMethods instead." | ||
); | ||
} | ||
} | ||
for(var d in definition){ | ||
@@ -30,3 +38,3 @@ if (!allowed[d] && Reflux.PublisherMethods[d]) { | ||
_isAction: true | ||
},Reflux.PublisherMethods,definition); | ||
}, Reflux.PublisherMethods, Reflux.ActionMethods, definition); | ||
@@ -33,0 +41,0 @@ var functor = function() { |
var _ = require('./utils'), | ||
Reflux = require('../src'), | ||
Keep = require('./Keep'), | ||
allowed = {preEmit:1,shouldEmit:1}; | ||
allowed = {preEmit:1,shouldEmit:1}, | ||
bindMethods = require('./bindMethods'); | ||
@@ -18,2 +19,10 @@ /** | ||
for(var a in Reflux.StoreMethods){ | ||
if (!allowed[a] && (Reflux.PublisherMethods[a] || Reflux.ListenerMethods[a])){ | ||
throw new Error("Cannot override API method " + a + | ||
" in Reflux.StoreMethods. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead." | ||
); | ||
} | ||
} | ||
for(var d in definition){ | ||
@@ -43,5 +52,6 @@ if (!allowed[d] && (Reflux.PublisherMethods[d] || Reflux.ListenerMethods[d])){ | ||
_.extend(Store.prototype, Reflux.ListenerMethods, Reflux.PublisherMethods, definition); | ||
_.extend(Store.prototype, Reflux.ListenerMethods, Reflux.PublisherMethods, Reflux.StoreMethods, definition); | ||
var store = new Store(); | ||
bindMethods(store, definition); | ||
Keep.createdStores.push(store); | ||
@@ -48,0 +58,0 @@ |
@@ -0,1 +1,3 @@ | ||
exports.ActionMethods = require('./ActionMethods'); | ||
exports.ListenerMethods = require('./ListenerMethods'); | ||
@@ -5,2 +7,4 @@ | ||
exports.StoreMethods = require('./StoreMethods'); | ||
exports.createAction = require('./createAction'); | ||
@@ -64,1 +68,12 @@ | ||
exports.__keep = require('./Keep'); | ||
/** | ||
* Warn if Function.prototype.bind not available | ||
*/ | ||
if (!Function.prototype.bind) { | ||
console.error( | ||
'Function.prototype.bind not available. ' + | ||
'ES5 shim required. ' + | ||
'https://github.com/spoike/refluxjs#es5' | ||
); | ||
} |
@@ -75,3 +75,3 @@ var _ = require('./utils'), | ||
_.throwIf(this.validateListening(listenable)); | ||
this.fetchDefaultData(listenable, defaultCallback); | ||
this.fetchInitialState(listenable, defaultCallback); | ||
desub = listenable.listen(this[callback]||callback, this); | ||
@@ -123,11 +123,11 @@ unsubscriber = function() { | ||
/** | ||
* Used in `listenTo`. Fetches initial data from a publisher if it has a `getDefaultData` method. | ||
* @param {Action|Store} listenable The publisher we want to get default data from | ||
* Used in `listenTo`. Fetches initial data from a publisher if it has a `getInitialState` method. | ||
* @param {Action|Store} listenable The publisher we want to get initial state from | ||
* @param {Function|String} defaultCallback The method to receive the data | ||
*/ | ||
fetchDefaultData: function (listenable, defaultCallback) { | ||
fetchInitialState: function (listenable, defaultCallback) { | ||
defaultCallback = (defaultCallback && this[defaultCallback]) || defaultCallback; | ||
var me = this; | ||
if (_.isFunction(defaultCallback) && _.isFunction(listenable.getDefaultData)) { | ||
data = listenable.getDefaultData(); | ||
if (_.isFunction(defaultCallback) && _.isFunction(listenable.getInitialState)) { | ||
data = listenable.getInitialState(); | ||
if (data && _.isFunction(data.then)) { | ||
@@ -179,2 +179,1 @@ data.then(function() { | ||
}; | ||
@@ -7,2 +7,4 @@ var _ = require('./utils'), | ||
* `ListenerMethods` mixin and takes care of teardown of subscriptions. | ||
* Note that if you're using the `connect` mixin you don't need this mixin, as connect will | ||
* import everything this mixin contains! | ||
*/ | ||
@@ -9,0 +11,0 @@ module.exports = _.extend({ |
@@ -32,2 +32,24 @@ var chai = require('chai'), | ||
describe('Reflux.ActionMethods', function() { | ||
afterEach(function(){ | ||
Reflux.ActionMethods = {}; | ||
}); | ||
it("should copy properties from Reflux.ActionMethods into the action",function(){ | ||
Reflux.ActionMethods = {preEmit: function() {}, exampleFn: function() {}}; | ||
var action = Reflux.createAction(); | ||
assert.equal(action.preEmit, Reflux.ActionMethods.preEmit); | ||
assert.equal(action.exampleFn, Reflux.ActionMethods.exampleFn); | ||
}); | ||
it("should throw an error if you overwrite any API other than preEmit and shouldEmit in Reflux.ActionMethods",function(){ | ||
Reflux.ActionMethods.listen = "FOO"; | ||
assert.throws(function(){ | ||
Reflux.createAction({}); | ||
}); | ||
}); | ||
}); | ||
var action, | ||
@@ -122,3 +144,3 @@ testArgs; | ||
validateListening:function(){}, | ||
fetchDefaultData:function(){} | ||
fetchInitialState:function(){} | ||
}; | ||
@@ -125,0 +147,0 @@ |
@@ -19,2 +19,4 @@ var chai = require('chai'), | ||
beforeEach(function() { | ||
Reflux.StoreMethods = {}; | ||
promise = Q.Promise(function(resolve) { | ||
@@ -181,18 +183,18 @@ action = Reflux.createAction(); | ||
it('should get default data from getDefaultData()', function() { | ||
it('should get initial state from getInitialState()', function() { | ||
var store = Reflux.createStore(_.extend(baseDefinition, { | ||
getDefaultData: function () { | ||
return ['default data']; | ||
getInitialState: function () { | ||
return ['initial state']; | ||
} | ||
})); | ||
var promise = createPromiseForTest(store); | ||
return assert.eventually.equal(promise, '[...] default data'); | ||
return assert.eventually.equal(promise, '[...] initial state'); | ||
}); | ||
it('should get default data from getDefaultData() returned promise', function() { | ||
it('should get initial state from getInitialState() returned promise', function() { | ||
var store = Reflux.createStore(_.extend(baseDefinition, { | ||
getDefaultData: function () { | ||
getInitialState: function () { | ||
return Q.Promise(function (resolve) { | ||
setTimeout(function () { | ||
resolve(['default data']); | ||
resolve(['initial state']); | ||
}, 20); | ||
@@ -203,3 +205,3 @@ }); | ||
var promise = createPromiseForTest(store); | ||
return assert.eventually.equal(promise, '[...] default data'); | ||
return assert.eventually.equal(promise, '[...] initial state'); | ||
}); | ||
@@ -212,4 +214,4 @@ | ||
describe("when given a single object",function(){ | ||
var defaultbardata = "DEFAULTBARDATA", | ||
defaultbazdata = "DEFAULTBAZDATA", | ||
var initialbarstate = "DEFAULTBARDATA", | ||
initialbazstate = "DEFAULTBAZDATA", | ||
listenables = { | ||
@@ -219,7 +221,7 @@ foo: {listen:sinon.spy()}, | ||
listen:sinon.spy(), | ||
getDefaultData:sinon.stub().returns(defaultbardata) | ||
getInitialState:sinon.stub().returns(initialbarstate) | ||
}, | ||
baz: { | ||
listen:sinon.spy(), | ||
getDefaultData:sinon.stub().returns(defaultbazdata) | ||
getInitialState:sinon.stub().returns(initialbazstate) | ||
}, | ||
@@ -249,11 +251,11 @@ missing: { | ||
it("should call main callback if listenable has getDefaultData but listener has no default-specific cb",function(){ | ||
assert.equal(listenables.bar.getDefaultData.callCount,1); | ||
assert.equal(def.bar.firstCall.args[0],defaultbardata); | ||
it("should call main callback if listenable has getInitialState but listener has no default-specific cb",function(){ | ||
assert.equal(listenables.bar.getInitialState.callCount,1); | ||
assert.equal(def.bar.firstCall.args[0],initialbarstate); | ||
}); | ||
it("should call default callback if exist and listenable has getDefaultData",function(){ | ||
assert.equal(listenables.baz.getDefaultData.callCount,1); | ||
it("should call default callback if exist and listenable has getInitialState",function(){ | ||
assert.equal(listenables.baz.getInitialState.callCount,1); | ||
assert.equal(def.onBaz.callCount,0); | ||
assert.equal(def.onBazDefault.firstCall.args[0],defaultbazdata); | ||
assert.equal(def.onBazDefault.firstCall.args[0],initialbazstate); | ||
}); | ||
@@ -307,2 +309,16 @@ }); | ||
it("should copy properties from Reflux.StoreMethods into the store",function(){ | ||
Reflux.StoreMethods = {preEmit: function() {}, exampleFn: function() {}}; | ||
var store = Reflux.createStore(); | ||
assert.equal(store.preEmit, Reflux.StoreMethods.preEmit); | ||
assert.equal(store.exampleFn, Reflux.StoreMethods.exampleFn); | ||
}); | ||
it("should fail when trying to override API methods in Reflux.StoreMethods",function(){ | ||
Reflux.StoreMethods = { listen: "BAR" }; | ||
assert.throws(function(){ | ||
Reflux.createStore({}); | ||
}); | ||
}); | ||
it("should not mix in its own methods into ListenerMethods",function(){ | ||
@@ -313,2 +329,18 @@ assert.isUndefined(Reflux.ListenerMethods.listen); | ||
describe('store methods', function() { | ||
var store; | ||
beforeEach(function() { | ||
store = Reflux.createStore({ | ||
reflect: function() { | ||
return this; | ||
} | ||
}); | ||
}); | ||
it('should be bound to store instance', function() { | ||
var reflect = store.reflect; | ||
return assert.equal(store, reflect()); | ||
}); | ||
}); | ||
}); |
@@ -11,6 +11,6 @@ var assert = require('chai').assert, | ||
var unsubscriber = sinon.spy(), | ||
defaultdata = "DATA", | ||
initialstate = "DATA", | ||
listenable = { | ||
listen: sinon.stub().returns(unsubscriber), | ||
getDefaultData: sinon.stub().returns(defaultdata) | ||
getInitialState: sinon.stub().returns(initialstate) | ||
}, | ||
@@ -44,6 +44,6 @@ initial = sinon.spy(), | ||
it("should send listenable default data to initial (via listenTo)",function(){ | ||
assert.equal(listenable.getDefaultData.callCount,1); | ||
it("should send listenable initial state to initial cb (via listenTo)",function(){ | ||
assert.equal(listenable.getInitialState.callCount,1); | ||
assert.equal(initial.callCount,1); | ||
assert.equal(initial.firstCall.args[0],defaultdata); | ||
assert.equal(initial.firstCall.args[0],initialstate); | ||
}); | ||
@@ -50,0 +50,0 @@ }); |
@@ -13,7 +13,19 @@ var assert = require('chai').assert, | ||
describe("when calling with action",function() { | ||
var listenable = { | ||
listen: sinon.spy() | ||
}, | ||
context = {setState: sinon.spy()}; | ||
_.extend(context,connect(listenable)); | ||
it("should pass empty object to state",function(){ | ||
assert.deepEqual({},context.getInitialState()); | ||
}); | ||
}); | ||
describe("when calling without key",function(){ | ||
var defaultdata = "DEFAULTDATA", | ||
var initialstate = "DEFAULTDATA", | ||
listenable = { | ||
listen: sinon.spy(), | ||
getDefaultData: sinon.stub().returns(defaultdata) | ||
getInitialState: sinon.stub().returns(initialstate) | ||
}, | ||
@@ -23,3 +35,4 @@ context = {setState: sinon.spy()}, | ||
it("should add componentDidMount and WillUnmount",function(){ | ||
it("should add getInitialState and componentDidMount and WillUnmount",function(){ | ||
assert.isFunction(context.getInitialState); | ||
assert.isFunction(context.componentDidMount); | ||
@@ -30,2 +43,6 @@ assert.isFunction(context.componentWillUnmount); | ||
it("should pass initial state to state",function(){ | ||
assert.deepEqual(initialstate,context.getInitialState()); | ||
}); | ||
result.componentDidMount(); | ||
@@ -39,6 +56,2 @@ | ||
it("should pass default data to state",function(){ | ||
assert.deepEqual([defaultdata],context.setState.firstCall.args); | ||
}); | ||
it("should store the subscription object correctly",function(){ | ||
@@ -51,3 +64,3 @@ assert.equal(listenable,context.subscriptions[0].listenable); | ||
describe("when calling with key",function(){ | ||
var defaultdata = "DEFAULTDATA", | ||
var initialstate = "DEFAULTDATA", | ||
triggerdata = "TRIGGERDATA", | ||
@@ -57,3 +70,3 @@ key = "KEY", | ||
listen: sinon.spy(), | ||
getDefaultData: sinon.stub().returns(defaultdata) | ||
getInitialState: sinon.stub().returns(initialstate) | ||
}, | ||
@@ -63,2 +76,6 @@ context = {setState: sinon.spy()}, | ||
it("should pass initial state to state correctly",function(){ | ||
assert.deepEqual({KEY:initialstate},context.getInitialState()); | ||
}); | ||
result.componentDidMount(); | ||
@@ -72,9 +89,5 @@ | ||
it("should pass default data to state correctly",function(){ | ||
assert.deepEqual([{KEY:defaultdata}],context.setState.firstCall.args); | ||
}); | ||
it("should send listenable callback which calls setState correctly",function(){ | ||
listenable.listen.firstCall.args[0](triggerdata); | ||
assert.deepEqual([_.object([key],[triggerdata])],context.setState.secondCall.args); | ||
assert.deepEqual([_.object([key],[triggerdata])],context.setState.firstCall.args); | ||
}); | ||
@@ -94,2 +107,13 @@ }); | ||
}); | ||
describe("together with ListenerMixin in a React component",function(){ | ||
var store = Reflux.createStore({}), | ||
def = {setState:function(){}}, | ||
fakecomponent = _.extend(def,Reflux.connect(store),Reflux.ListenerMethods); | ||
it("should log a warning)",function(){ | ||
sinon.spy(console,"warn"); | ||
fakecomponent.componentDidMount(); | ||
assert(console.warn.calledOnce); | ||
console.warn.restore(); | ||
}); | ||
}); | ||
}); |
@@ -49,3 +49,3 @@ var chai = require('chai'), | ||
validateListening: function(){}, | ||
fetchDefaultData: sinon.stub() | ||
fetchInitialState: sinon.stub() | ||
}, | ||
@@ -62,4 +62,4 @@ subobj = listenTo.call(context,listenable,callback,defaultcallback); | ||
it("tries to get default data correctly",function(){ | ||
assert.deepEqual(context.fetchDefaultData.firstCall.args,[listenable,defaultcallback]); | ||
it("tries to get initial state correctly",function(){ | ||
assert.deepEqual(context.fetchInitialState.firstCall.args,[listenable,defaultcallback]); | ||
}); | ||
@@ -85,8 +85,8 @@ | ||
describe('the fetchDefaultData method',function(){ | ||
describe('the fetchInitialState method',function(){ | ||
describe('when called with method name and publisher with getDefaultData method',function(){ | ||
var defaultdata = "DEFAULTDATA", | ||
describe('when called with method name and publisher with getInitialState method',function(){ | ||
var initialstate = "DEFAULTDATA", | ||
listenable = { | ||
getDefaultData: sinon.stub().returns(defaultdata) | ||
getInitialState: sinon.stub().returns(initialstate) | ||
}, | ||
@@ -96,10 +96,10 @@ context = { | ||
}; | ||
ListenerMethods.fetchDefaultData.call(context,listenable,"defcb"); | ||
ListenerMethods.fetchInitialState.call(context,listenable,"defcb"); | ||
it("calls getDefaultData on the publisher",function(){ | ||
assert.equal(listenable.getDefaultData.callCount,1); | ||
it("calls getInitialState on the publisher",function(){ | ||
assert.equal(listenable.getInitialState.callCount,1); | ||
}); | ||
it("passes the returned data to the named method",function(){ | ||
assert.deepEqual(context.defcb.firstCall.args,[defaultdata]); | ||
assert.deepEqual(context.defcb.firstCall.args,[initialstate]); | ||
}); | ||
@@ -106,0 +106,0 @@ }); |
@@ -57,3 +57,3 @@ var chai = require('chai'), | ||
describe('get default data', function () { | ||
describe('get initial state', function () { | ||
beforeEach(function() { | ||
@@ -73,18 +73,18 @@ component.componentWillUnmount(); | ||
it('should get default data from getDefaultData()', function () { | ||
it('should get initial state from getInitialState()', function () { | ||
store = Reflux.createStore({ | ||
getDefaultData: function () { | ||
return 'default data'; | ||
getInitialState: function () { | ||
return 'initial state'; | ||
} | ||
}); | ||
mountComponent(); | ||
return assert.eventually.equal(promise, 'default data'); | ||
return assert.eventually.equal(promise, 'initial state'); | ||
}); | ||
it('should get default data from getDefaultData() returned promise', function () { | ||
it('should get initial state from getInitialState() returned promise', function () { | ||
store = Reflux.createStore({ | ||
getDefaultData: function () { | ||
getInitialState: function () { | ||
return Q.Promise(function (resolve) { | ||
setTimeout(function () { | ||
resolve('default data'); | ||
resolve('initial state'); | ||
}, 20); | ||
@@ -95,3 +95,3 @@ }); | ||
mountComponent(); | ||
return assert.eventually.equal(promise, 'default data'); | ||
return assert.eventually.equal(promise, 'initial state'); | ||
}); | ||
@@ -98,0 +98,0 @@ }); |
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
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
182226
50
3575
525