Skip to content

Instantly share code, notes, and snippets.

@stecb
Last active November 29, 2015 00:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stecb/f93abaa741c0512228b7 to your computer and use it in GitHub Desktop.
Save stecb/f93abaa741c0512228b7 to your computer and use it in GitHub Desktop.
import { DEFAULT_ADAPTER } from './constants';
/*
Creates the subscription object
@param component function the React component
@param autoUnmount boolean defaults to true, if it has to remove all subscriptions on cwunmount
@param adapter object the pubsub adapter
@return the subscription object
*/
const createSubscription = function(component, autoUnmount = true, adapter) {
let sub = {
componentWillUnmount: component.componentWillUnmount,
subscriptions: [],
add(action, cb) {
const token = adapter.subscribe(action, cb);
sub.subscriptions.push(token);
return () => {
sub.subscriptions.splice(sub.subscriptions.indexOf(token), 1);
adapter.unsubscribe(token);
}
},
removeAll() {
sub.subscriptions.forEach( token => adapter.unsubscribe(token) );
sub.subscriptions = [];
},
publish(action, params) {
adapter.publish(action, params);
}
};
if (autoUnmount) {
component.componentWillUnmount = () => {
const { componentWillUnmount, removeAll } = sub;
componentWillUnmount && componentWillUnmount.apply(component, arguments);
removeAll();
sub = void 0;
};
}
return sub;
};
/*
PubSubAdapter function
@param Object adapter being used
@returns an object wrapping publish/subscribe/unsubscribe from given adapter
*/
const PubSubAdapter = (adapter) => {
const { publish, subscribe, unsubscribe } = adapter;
return {
publish,
subsribe,
unsubscribe
}
};
/*
createPubSub function
@param subscribersMap Object, default to empty object, subscribers that will be populated
like so:
subscribersMap[MyReactComponent] = {...}
@param adapter Object, default to default adapter specified
@returns an object wrapping register/unregister for a particular component
*/
const createPubSub = (subscribersMap = {}, adapter = DEFAULT_ADAPTER) => {
return {
register(component, autoUnmount = true) {
let registeredComponent = subscribersMap[component];
registeredComponent = registeredComponent || createSubscription(component, autoUnmount, PubSubAdapter(adapter));
return registeredComponent;
},
unregister(component) {
if (subscribersMap[component]) {
subscribersMap[component].removeAll() && delete subscribersMap[component];
} else {
console.log(`${component.displayName} is NOT registerd to PubSub`);
}
},
};
};
export default createPubSub;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment