11import Firebase from 'firebase'
22import { EventEmitter } from 'events'
3+ import { Promise } from 'es6-promise'
34
45const api = new Firebase ( 'https://hacker-news.firebaseio.com/v0' )
5- let cachedStoryIds = [ ]
6- const cachedStories = { }
6+ const itemsCache = Object . create ( null )
77const store = new EventEmitter ( )
88const storiesPerPage = store . storiesPerPage = 30
99
10+ let topStoryIds = [ ]
11+
1012export default store
1113
1214/**
1315 * Subscribe to real time updates of the top 100 stories,
1416 * and cache the IDs locally.
1517 */
1618
17- api . child ( 'topstories' ) . on ( 'value' , ( snapshot ) => {
18- cachedStoryIds = snapshot . val ( )
19- store . emit ( 'update ' )
19+ api . child ( 'topstories' ) . on ( 'value' , snapshot => {
20+ topStoryIds = snapshot . val ( )
21+ store . emit ( 'topstories-updated ' )
2022} )
2123
2224/**
@@ -26,15 +28,17 @@ api.child('topstories').on('value', (snapshot) => {
2628 * @param {Function } cb(item)
2729 */
2830
29- store . fetchItem = ( id , cb ) => {
30- if ( cachedStories [ id ] ) {
31- cb ( cachedStories [ id ] )
32- } else {
33- api . child ( 'item/' + id ) . once ( 'value' , function ( snapshot ) {
34- const story = cachedStories [ id ] = snapshot . val ( )
35- cb ( story )
36- } )
37- }
31+ store . fetchItem = id => {
32+ return new Promise ( ( resolve , reject ) => {
33+ if ( itemsCache [ id ] ) {
34+ resolve ( itemsCache [ id ] )
35+ } else {
36+ api . child ( 'item/' + id ) . once ( 'value' , snapshot => {
37+ const story = itemsCache [ id ] = snapshot . val ( )
38+ resolve ( story )
39+ } , reject )
40+ }
41+ } )
3842}
3943
4044/**
@@ -44,19 +48,12 @@ store.fetchItem = (id, cb) => {
4448 * @param {Function } cb(items)
4549 */
4650
47- store . fetchItems = ( ids , cb ) => {
51+ store . fetchItems = ids => {
4852 if ( ! ids || ! ids . length ) {
49- return cb ( [ ] )
53+ return Promise . resolve ( [ ] )
54+ } else {
55+ return Promise . all ( ids . map ( id => store . fetchItem ( id ) ) )
5056 }
51- const items = [ ]
52- ids . forEach ( ( id ) => {
53- store . fetchItem ( id , ( item ) => {
54- items . push ( item )
55- if ( items . length >= ids . length ) {
56- cb ( items )
57- }
58- } )
59- } )
6057}
6158
6259/**
@@ -66,11 +63,11 @@ store.fetchItems = (ids, cb) => {
6663 * @param {Function } cb(stories)
6764 */
6865
69- store . fetchItemsByPage = ( page , cb ) => {
66+ store . fetchItemsByPage = page => {
7067 const start = ( page - 1 ) * storiesPerPage
7168 const end = page * storiesPerPage
72- const ids = cachedStoryIds . slice ( start , end )
73- store . fetchItems ( ids , cb )
69+ const ids = topStoryIds . slice ( start , end )
70+ return store . fetchItems ( ids )
7471}
7572
7673/**
@@ -80,8 +77,10 @@ store.fetchItemsByPage = (page, cb) => {
8077 * @param {Function } cb(user)
8178 */
8279
83- store . fetchUser = ( id , cb ) => {
84- api . child ( 'user/' + id ) . once ( 'value' , ( snapshot ) => {
85- cb ( snapshot . val ( ) )
80+ store . fetchUser = id => {
81+ return new Promise ( ( resolve , reject ) => {
82+ api . child ( 'user/' + id ) . once ( 'value' , snapshot => {
83+ resolve ( snapshot . val ( ) )
84+ } , reject )
8685 } )
8786}
0 commit comments