use observer.js for pub/sub