Comparing version 4.0.0-alpha to 4.0.0-alpha2
@@ -16,5 +16,7 @@ # Changelog | ||
- Async action handlers are sent a `dispatchId` as part of the payload. The dispatch id for a `begin` dispatch is equal to the id of the corresponding `success` or `error` dispatch. This enables fine-grained optimistic updates. | ||
- `Store#registerMatcher(matcher, handler)` calls a handler when the matcher function returns true for a dispatched payload. The handler is passed the payload. | ||
- `Store#registerMatch(matcher, handler)` calls a handler when the matcher function returns true for a dispatched payload. The handler is passed the payload. | ||
- Use `injectActions` prop of FluxComponent to pass actions to children as props. | ||
- **Breaking Change** | ||
- The arguments passed to async action handlers have been changed. The final argument passed to any action handler is the raw payload that is sent through the dispatcher. For example, "begin" handlers receive the payload as its sole argument. | ||
- Arguments sent to the `render` prop function of FluxComponent have been changed: `render(storeState, actions, flux)`. Notably, extra props added to FluxComponent are no longer combined with storeState, and `flux` is a separate parameter as well. | ||
- **Internal** | ||
@@ -21,0 +23,0 @@ - Cleaned up Store's `register` methods. Much simpler code paths now. |
@@ -73,2 +73,16 @@ 'use strict'; | ||
describe('#getActionsAsObject', function () { | ||
it('returns actions as plain object', function () { | ||
var actions = new TestActions(); | ||
expect(actions.getActionsAsObject()).to.deep.equal({ | ||
getFoo: actions.getFoo, | ||
getBar: actions.getBar, | ||
getBaz: actions.getBaz, | ||
asyncAction: actions.asyncAction, | ||
badAsyncAction: actions.badAsyncAction | ||
}); | ||
}); | ||
}); | ||
describe('#[methodName]', function () { | ||
@@ -75,0 +89,0 @@ it('calls Flux dispatcher', function () { |
@@ -49,7 +49,16 @@ 'use strict'; | ||
Actions.prototype._getActionMethodNames = function _getActionMethodNames(instance) { | ||
Actions.prototype.getActionsAsObject = function getActionsAsObject() { | ||
var _this2 = this; | ||
return this._getActionMethodNames().reduce(function (result, actionName) { | ||
result[actionName] = _this2[actionName]; | ||
return result; | ||
}, {}); | ||
}; | ||
Actions.prototype._getActionMethodNames = function _getActionMethodNames(instance) { | ||
var _this3 = this; | ||
return Object.getOwnPropertyNames(this.constructor.prototype).filter(function (name) { | ||
return name !== 'constructor' && typeof _this2[name] === 'function'; | ||
return name !== 'constructor' && typeof _this3[name] === 'function'; | ||
}); | ||
@@ -59,3 +68,3 @@ }; | ||
Actions.prototype._wrapAction = function _wrapAction(methodName) { | ||
var _this3 = this; | ||
var _this4 = this; | ||
@@ -70,9 +79,9 @@ var originalMethod = this[methodName]; | ||
var body = originalMethod.apply(_this3, args); | ||
var body = originalMethod.apply(_this4, args); | ||
if (isPromise(body)) { | ||
var promise = body; | ||
_this3._dispatchAsync(actionId, promise, args, methodName); | ||
_this4._dispatchAsync(actionId, promise, args, methodName); | ||
} else { | ||
_this3._dispatch(actionId, body, args, methodName); | ||
_this4._dispatch(actionId, body, args, methodName); | ||
} | ||
@@ -79,0 +88,0 @@ |
@@ -199,2 +199,62 @@ 'use strict'; | ||
it('passes injectActions prop to reactComponentMethod collectActions()', function () { | ||
var Flux = (function (_Flummox2) { | ||
function Flux() { | ||
_classCallCheck(this, Flux); | ||
_Flummox2.call(this); | ||
this.createActions('A', { | ||
'do': function _do() { | ||
return 're'; | ||
}, | ||
re: function re() { | ||
return 'mi'; | ||
} | ||
}); | ||
this.createActions('B', { | ||
mi: function mi() { | ||
return 'fa'; | ||
}, | ||
fa: function fa() { | ||
return 'so'; | ||
} | ||
}); | ||
} | ||
_inherits(Flux, _Flummox2); | ||
return Flux; | ||
})(_Flummox$Store$Actions.Flummox); | ||
var flux = new Flux(); | ||
var component = TestUtils.renderIntoDocument(React.createElement(FluxComponent, { | ||
flux: flux, | ||
injectActions: { | ||
A: function A(actions) { | ||
return { | ||
'do': actions['do'] | ||
}; | ||
}, | ||
B: function B(actions) { | ||
return { | ||
fa: actions.fa | ||
}; | ||
} }, | ||
render: function (storeState, actions, flux) { | ||
return React.createElement('div', actions); | ||
} | ||
})); | ||
var div = TestUtils.findRenderedDOMComponentWithTag(component, 'div'); | ||
expect(div.props['do']()).to.equal('re'); | ||
expect(div.props.fa()).to.equal('so'); | ||
}); | ||
it('injects children with flux prop', function () { | ||
@@ -239,11 +299,12 @@ var flux = new Flux(); | ||
// are injected. | ||
var tree = TestUtils.renderIntoDocument(React.createElement(FluxComponent, { | ||
flux: flux, | ||
connectToStores: 'test', | ||
stateGetter: stateGetter, | ||
extraProp: 'hello', | ||
render: function (props) { | ||
return React.createElement('div', props); | ||
} | ||
})); | ||
var tree = TestUtils.renderIntoDocument(React.createElement( | ||
FluxComponent, | ||
{ | ||
flux: flux, | ||
connectToStores: 'test', | ||
stateGetter: stateGetter, | ||
extraProp: 'hello' | ||
}, | ||
React.createElement('div', null) | ||
)); | ||
@@ -343,3 +404,3 @@ var div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); | ||
Owner.prototype.render = function render() { | ||
var _this = this; | ||
var _this5 = this; | ||
@@ -351,3 +412,3 @@ return React.createElement(FluxComponent, { | ||
return { | ||
yay: _this.state.foo | ||
yay: _this5.state.foo | ||
}; | ||
@@ -354,0 +415,0 @@ } |
@@ -92,9 +92,10 @@ 'use strict'; | ||
var connectToStores = _props.connectToStores; | ||
var injectActions = _props.injectActions; | ||
var stateGetter = _props.stateGetter; | ||
var flux = _props.flux; | ||
var extraProps = _objectWithoutProperties(_props, ['children', 'render', 'connectToStores', 'stateGetter', 'flux']); | ||
var extraProps = _objectWithoutProperties(_props, ['children', 'render', 'connectToStores', 'injectActions', 'stateGetter', 'flux']); | ||
return assign({ flux: this.getFlux() }, // TODO: remove in next major version | ||
this.state, extraProps); | ||
this.collectActions(injectActions), this.state, extraProps); | ||
}; | ||
@@ -116,5 +117,6 @@ | ||
var render = _props2.render; | ||
var injectActions = _props2.injectActions; | ||
if (typeof render === 'function') { | ||
return render(this.getChildProps(), this.getFlux()); | ||
return render(this.state, this.collectActions(injectActions), this.getFlux()); | ||
} | ||
@@ -121,0 +123,0 @@ |
@@ -126,3 +126,3 @@ 'use strict'; | ||
var getStore = function getStore(key) { | ||
function getStore(key) { | ||
var store = flux.getStore(key); | ||
@@ -135,3 +135,3 @@ | ||
return store; | ||
}; | ||
} | ||
@@ -141,3 +141,3 @@ if (typeof stateGetterMap === 'string') { | ||
var store = getStore(key); | ||
var getter = stateGetter || defaultStateGetter; | ||
var getter = createGetter(stateGetter, defaultStateGetter); | ||
@@ -152,3 +152,3 @@ this._fluxStateGetters.push({ stores: store, getter: getter }); | ||
var stores = stateGetterMap.map(getStore); | ||
var getter = stateGetter || defaultReduceStateGetter; | ||
var getter = createGetter(stateGetter, defaultReduceStateGetter); | ||
@@ -167,3 +167,3 @@ _this._fluxStateGetters.push({ stores: stores, getter: getter }); | ||
var store = getStore(key); | ||
var getter = stateGetterMap[key] || defaultStateGetter; | ||
var getter = createGetter(stateGetterMap[key], defaultStateGetter); | ||
@@ -179,4 +179,48 @@ this._fluxStateGetters.push({ stores: store, getter: getter }); | ||
return this.getStoreState(); | ||
}, | ||
collectActions: function collectActions() { | ||
var actionMap = arguments[0] === undefined ? {} : arguments[0]; | ||
var actionGetter = arguments[1] === undefined ? null : arguments[1]; | ||
if (typeof actionMap === 'undefined') { | ||
return {}; | ||
} | ||
var flux = this.getFlux(); | ||
function getActions(key) { | ||
var actions = flux.getActions(key); | ||
if (typeof actions === 'undefined') { | ||
throw new Error('connectToStores(): Actions with key \'' + key + '\' does not exist.'); | ||
} | ||
return actions; | ||
} | ||
var collectedActions = {}; | ||
if (typeof actionMap === 'string') { | ||
var key = actionMap; | ||
var actions = getActions(key); | ||
var getter = createGetter(actionGetter, defaultActionGetter); | ||
assign(collectedActions, getter(actions)); | ||
} else if (Array.isArray(actionMap)) { | ||
var actions = actionMap.map(getActions); | ||
var getter = createGetter(actionGetter, defaultReduceActionGetter); | ||
assign(collectedActions, getter(actions)); | ||
} else { | ||
for (var key in actionMap) { | ||
var actions = getActions(key); | ||
var getter = createGetter(actionMap[key], defaultActionGetter); | ||
assign(collectedActions, getter(actions)); | ||
} | ||
} | ||
return collectedActions; | ||
} | ||
}; | ||
@@ -207,2 +251,10 @@ | ||
function createGetter(value, defaultGetter) { | ||
if (typeof value !== 'function') { | ||
return defaultGetter; | ||
} else { | ||
return value; | ||
} | ||
} | ||
function defaultStateGetter(store) { | ||
@@ -216,2 +268,12 @@ return store.getStateAsObject(); | ||
}, {}); | ||
} | ||
function defaultActionGetter(actions) { | ||
return actions.getActionsAsObject(); | ||
} | ||
function defaultReduceActionGetter(actions) { | ||
return actions.reduce(function (result, _actions) { | ||
return assign(result, _actions.getStateAsObject()); | ||
}, {}); | ||
} |
@@ -242,3 +242,3 @@ 'use strict'; | ||
if (matcher(payload) === true) { | ||
if (matcher(payload)) { | ||
customMatchedActionHandlers.push(handler); | ||
@@ -291,5 +291,7 @@ } | ||
} finally { | ||
var emit = false; | ||
if (this._emitChangeAfterHandlingDispatch) { | ||
emit = true; | ||
this.state = this._pendingState; | ||
this.emit('change'); | ||
} | ||
@@ -300,2 +302,4 @@ | ||
this._emitChangeAfterHandlingDispatch = false; | ||
if (emit) this.emit('change'); | ||
} | ||
@@ -302,0 +306,0 @@ }; |
{ | ||
"name": "flummox", | ||
"version": "4.0.0-alpha", | ||
"version": "4.0.0-alpha2", | ||
"description": "Idiomatic, modular, testable, isomorphic Flux. No singletons required.", | ||
@@ -5,0 +5,0 @@ "main": "lib/Flux.js", |
2214207
7532