Add wrapSelectors functionality
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user