@@ -27,11 +27,23 @@ function cleanEmptyKeys(obj = {}) {
2727}
2828
2929export default function createPubSubConnector ( mapSubscriptionsToProps , mapPublishToProps , options = { } ) {
30+ if (
31+ mapSubscriptionsToProps &&
32+ ( typeof mapSubscriptionsToProps !== 'function' && ! isPlainObject ( mapSubscriptionsToProps ) )
33+ ) {
34+ throw new Error (
35+ `"createPubSubConnector" expected "mapSubscriptionsToProps" to be a function`
36+ + ` or a plain object, instead received: ${ mapSubscriptionsToProps } .`
37+ ) ;
38+ }
3039 const shouldMapSubscriptions = Boolean ( mapSubscriptionsToProps ) ;
40+ const mapSubscriptionIsFunction = typeof mapSubscriptionsToProps === 'function' ;
41+
3142 const finalMapPublishToProps = isPlainObject ( mapPublishToProps ) ?
3243 wrapPublishMethods ( mapPublishToProps ) :
3344 mapPublishToProps || defaultMapPublishToProps ;
3445 const shouldUpdatePublishProps = finalMapPublishToProps . length > 1 ;
46+
3547 const { withRef = false , ownProps = true } = options || { } ;
3648
3749 let mappedSubscriptions = { } ;
@@ -98,6 +110,20 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
98110 } , { } ) ;
99111 }
100112
113+ function initSubscriptionFunction ( pubSub , subscriptionsFunction , updateSubscriptionProps , getProps ) {
114+ // init given function, this invocation will subscribe required actions to
115+ // passed pubSub instance
116+ const applySubscription = subscriptionsFunction ( pubSub , updateSubscriptionProps , getProps ) ;
117+
118+ if ( typeof applySubscription !== 'function' ) {
119+ throw new Error (
120+ `'initSubscriptionFunction' expected 'subscriptionsFunction' to return`
121+ + ` a function. Instead received: ${ applySubscription } `
122+ ) ;
123+ }
124+ return applySubscription ;
125+ }
126+
101127 function computePublishProps ( pubSub , props ) {
102128 const { publish } = pubSub ;
103129 const publishProps = shouldUpdatePublishProps ?
@@ -130,32 +156,53 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
130156 }
131157
132158 this . pubSub = this . pubSubCore . register ( this ) ;
159+ this . mappedSubscriptionProps = { } ;
133160
134161 if ( shouldMapSubscriptions ) {
135- registerMappedSubscriptions (
136- this . pubSub ,
137- mapSubscriptionsToProps ,
138- ( ...args ) => this . updateSingleMappedSubscription ( ...args ) ,
139- ( ) => this . props
140- ) ;
162+ if ( mapSubscriptionIsFunction ) {
163+ this . applySubscription = initSubscriptionFunction (
164+ this . pubSub ,
165+ mapSubscriptionsToProps ,
166+ ( ...args ) => this . updateSingleMappedSubscription ( ...args ) ,
167+ ( ) => this . props
168+ ) ;
169+ this . mappedSubscriptionProps = this . applySubscription ( props ) ;
170+
171+ if ( ! isPlainObject ( this . mappedSubscriptionProps ) ) {
172+ throw new Error (
173+ `'pubSubConnector' expected an object returned from`
174+ + ` given .applySubscription() method. Instead received:`
175+ + ` ${ this . mappedSubscriptionProps } `
176+ ) ;
177+ }
178+ } else {
179+ registerMappedSubscriptions (
180+ this . pubSub ,
181+ mapSubscriptionsToProps ,
182+ ( ...args ) => this . updateSingleMappedSubscription ( ...args ) ,
183+ ( ) => this . props
184+ ) ;
185+ }
141186 }
142187
143188 this . publishProps = computePublishProps ( this . pubSub , props ) ;
144- this . mappedSubscriptionProps = { } ;
145189
146190 this . state = { } ;
147191 }
148192
149193 shouldComponentUpdate ( nextProps , nextState ) {
150194 const stateChanged = ! shallowEqual ( nextState , this . state ) ;
151195 const propsChanged = ! shallowEqual ( nextProps , this . props ) ;
152- let publishPropsChanged = false ;
153196
154197 if ( propsChanged && shouldUpdatePublishProps ) {
155- publishPropsChanged = this . updatePublishProps ( nextProps ) ;
198+ this . updatePublishProps ( nextProps ) ;
156199 }
157200
158- return propsChanged || stateChanged || publishPropsChanged ;
201+ if ( propsChanged && shouldMapSubscriptions && mapSubscriptionIsFunction ) {
202+ this . updateMappedSubscriptionsProps ( nextProps ) ;
203+ }
204+
205+ return propsChanged || stateChanged ;
159206 }
160207
161208 componentWillUnmount ( ) {
@@ -182,14 +229,20 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
182229 }
183230 }
184231
232+ updateMappedSubscriptionsProps ( props = this . props ) {
233+ const newValues = this . applySubscription ( props ) ;
234+ Object . assign ( this . mappedSubscriptionProps , newValues ) ;
235+ cleanEmptyKeys ( this . mappedSubscriptionProps ) ;
236+ }
237+
185238 updatePublishProps ( props = this . props ) {
186239 const nextPublishProps = computePublishProps ( this . pubSub , props ) ;
240+
187241 if ( shallowEqual ( nextPublishProps , this . publishProps ) ) {
188242 return false ;
189243 }
190244
191245 this . publishProps = nextPublishProps ;
192- return true ;
193246 }
194247
195248 hasSubscriptions ( ) {
0 commit comments