Add wrapSelectors functionality

This commit is contained in:
Kyle Shockey
2017-05-17 18:40:58 -07:00
parent 3881a82fc7
commit 1f314ddca2
2 changed files with 147 additions and 1 deletions

View File

@@ -76,7 +76,7 @@ export default class Store {
this.boundSystem = Object.assign({}, this.boundSystem = Object.assign({},
this.getRootInjects(), this.getRootInjects(),
this.getWrappedAndBoundActions(dispatch), this.getWrappedAndBoundActions(dispatch),
this.getBoundSelectors(getState, this.getSystem), this.getWrappedAndBoundSelectors(getState, this.getSystem),
this.getStateThunks(getState), this.getStateThunks(getState),
this.getFn(), this.getFn(),
this.getConfigs() this.getConfigs()
@@ -176,6 +176,36 @@ export default class Store {
}) })
} }
getWrappedAndBoundSelectors(getState, getSystem) {
let selectorGroups = this.getBoundSelectors(getState, getSystem)
return objMap(selectorGroups, (selectors, selectorGroupName) => {
let stateName = [selectorGroupName.slice(0, -9)] // selectors = 9 chars
let wrappers = this.system.statePlugins[stateName].wrapSelectors
if(wrappers) {
return objMap(selectors, (selector, selectorName) => {
let wrap = wrappers[selectorName]
if(!wrap) {
return selector
}
if(!Array.isArray(wrap)) {
wrap = [wrap]
}
return wrap.reduce((acc, fn) => {
let wrappedSelector = (...args) => {
return fn(acc, this.getSystem())(getState().getIn(stateName), ...args)
}
if(!isFn(wrappedSelector)) {
throw new TypeError("wrapSelector needs to return a function that returns a new function (ie the wrapped action)")
}
return wrappedSelector
}, selector || Function.prototype)
})
}
return selectors
})
}
getStates(state) { getStates(state) {
return Object.keys(this.system.statePlugins).reduce((obj, key) => { return Object.keys(this.system.statePlugins).reduce((obj, key) => {
obj[key] = state.get(key) obj[key] = state.get(key)

View File

@@ -326,6 +326,122 @@ describe("bound system", function(){
}) })
describe('wrapSelectors', () => {
it("should wrap a selector and provide a reference to the original", function(){
// Given
const system = new System({
plugins: [
{
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "original"
}
}
}
}
},
{
statePlugins: {
doge: {
wrapSelectors: {
wow: (ori) => (system) => {
// Then
return ori() + " wrapper"
}
}
}
}
}
]
})
// When
var res = system.getSystem().dogeSelectors.wow(1)
expect(res).toEqual("original wrapper")
})
it("should provide a live reference to the system to a wrapper", function(done){
// Given
const mySystem = new System({
plugins: [
{
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "original"
}
}
}
}
},
{
statePlugins: {
doge: {
wrapSelectors: {
wow: (ori, system) => () => {
// Then
expect(mySystem.getSystem()).toEqual(system.getSystem())
done()
return ori() + " wrapper"
}
}
}
}
}
]
})
mySystem.getSystem().dogeSelectors.wow(1)
})
it("should provide the state as the first argument to the inner function", function(done){
// Given
const mySystem = new System({
state: {
doge: {
abc: "123"
}
},
plugins: [
{
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "original"
}
}
}
}
},
{
statePlugins: {
doge: {
wrapSelectors: {
wow: (ori, system) => (dogeState) => {
// Then
expect(dogeState.toJS().abc).toEqual('123')
done()
return ori() + " wrapper"
}
}
}
}
}
]
})
mySystem.getSystem().dogeSelectors.wow(1)
})
})
}) })
}) })