@@ -34,6 +34,7 @@ module.exports = class FeedReader extends EventEmitter {
3434 // Create news emitter.
3535 this . news = new NewsEmitter ( {
3636 maxHistory : this . options . maxHistory ,
37+ manageHistory : true ,
3738 identifier : ( item ) => {
3839 item = item [ 0 ] ;
3940 return [
@@ -47,17 +48,7 @@ module.exports = class FeedReader extends EventEmitter {
4748 } ) ;
4849
4950 this . news . addHistory ( 'item' , this . options . history ) ;
50-
51- this . newitems = [ ] ;
5251 this . first = this . news . history . get ( 'item' ) . size === 0 ;
53-
54- // Keep track of and emit new items.
55- this . news . on ( 'item' , ( item ) => {
56- if ( ! this . first || this . options . emitOnStart ) {
57- this . newitems . unshift ( item ) ;
58- }
59- } ) ;
60-
6152 this . getOpts = Object . assign ( {
6253 headers : { } ,
6354 acceptEncoding : {
@@ -108,10 +99,12 @@ module.exports = class FeedReader extends EventEmitter {
10899 let ended = false ;
109100 let aborted = false ;
110101 let req ;
102+ let items = [ ] ;
103+ let newItems = [ ] ;
104+ let sortOrder = 0 ;
111105
112106 const error = ( abort , err ) => {
113107 ended = true ;
114- this . newitems = [ ] ;
115108 this . first = false ;
116109 if ( ! aborted ) {
117110 if ( typeof callback === 'function' ) {
@@ -126,22 +119,21 @@ module.exports = class FeedReader extends EventEmitter {
126119 }
127120 } ;
128121
129- const success = ( results , abort ) => {
122+ const success = ( abort ) => {
123+ if ( ended ) { return ; }
130124 ended = true ;
131- this . newitems = [ ] ;
125+ this . news . addHistory ( 'item' , newItems . map ( ( item ) => [ item ] ) ) ;
126+ if ( this . first && ! this . options . emitOnStart ) {
127+ newItems = [ ] ;
128+ }
129+ newItems . forEach ( this . emit . bind ( this , 'item' ) ) ;
130+ this . emit ( 'items' , newItems ) ;
132131 if ( abort && ! aborted ) {
133132 aborted = true ;
134- if ( req ) {
135- req . abort ( ) ;
136- }
133+ req . abort ( ) ;
137134 }
138-
139- results . forEach ( ( item ) => {
140- this . emit ( 'item' , item ) ;
141- } ) ;
142- this . emit ( 'items' , results ) ;
143135 if ( typeof callback === 'function' ) {
144- callback ( null , results ) ;
136+ callback ( null , newItems ) ;
145137 }
146138 } ;
147139
@@ -164,15 +156,15 @@ module.exports = class FeedReader extends EventEmitter {
164156 } ;
165157
166158 if ( shouldSkip ( ) ) {
167- return success ( [ ] , true ) ;
159+ return success ( ) ;
168160 }
169161
170162 req = miniget ( this . feed , this . getOpts ) ;
171163 req . on ( 'response' , ( res ) => {
172164 // Check if not modified code is sent back
173165 // in this case, the body will be empty.
174166 if ( res . statusCode === 304 ) {
175- return success ( [ ] ) ;
167+ return success ( ) ;
176168 }
177169
178170 // Check headers for conditional get.
@@ -231,47 +223,78 @@ module.exports = class FeedReader extends EventEmitter {
231223 const firstitem = ( item ) => {
232224 // If date is the same as last, abort.
233225 if ( date && this . options . lastDate === date ) {
234- return success ( [ ] , true ) ;
226+ return success ( ) ;
235227 }
236228
237229 if ( shouldSkip ( ) ) {
238- return success ( [ ] , true ) ;
230+ return success ( ) ;
239231 }
240232
241233 // Continue if dates differ.
242234 if ( date ) {
243235 this . options . lastDate = date ;
244236 }
245- parser . on ( 'item' , getitems ) ;
246- getitems ( item ) ;
237+ parser . on ( 'item' , getItem ) ;
238+ getItem ( item ) ;
247239 } ;
248240
249241 parser . once ( 'item' , firstitem ) ;
250242
251- const getitems = ( item ) => {
252- if ( this . first && this . options . emitOnStart ) {
253- this . newitems . unshift ( item ) ;
243+ const getItemDate = ( item ) => new Date ( item . pubdate || item . published || 0 ) ;
244+ const getItem = ( item ) => {
245+ if ( sortOrder === 0 ) {
246+ items . push ( item ) ;
247+ sortOrder = getItemDate ( item ) - getItemDate ( items [ 0 ] ) ;
248+ if ( sortOrder < 0 ) {
249+ items . forEach ( getOlderItem ) ;
250+ } else if ( sortOrder > 0 ) {
251+ items . forEach ( getNewerItem ) ;
252+ }
253+ } else if ( sortOrder < 0 ) {
254+ getOlderItem ( item ) ;
255+
256+ } else {
257+ getNewerItem ( item ) ;
258+ }
259+ } ;
254260
255- } else if ( ! this . news . emit ( 'item' , item ) ) {
256- // Check if this item has already been read in previous requests
257- // if it has, then stop parsing the rest of the document.
258- parser . removeListener ( 'item' , getitems ) ;
259- success ( this . newitems ) ;
261+ const getOlderItem = ( item ) => {
262+ if ( this . first ) {
263+ newItems . unshift ( item ) ;
264+ } else if ( ! ended ) {
265+ let emitted = this . news . emit ( 'item' , item ) ;
266+ if ( emitted ) {
267+ newItems . unshift ( item ) ;
268+ } else {
269+ // Check if this item has already been read in previous requests
270+ // if it has, then stop parsing the rest of the document.
271+ parser . removeListener ( 'item' , getItem ) ;
272+ success ( true ) ;
273+ }
274+ }
275+ } ;
276+
277+ let foundPrevItem = false ;
278+ const getNewerItem = ( item ) => {
279+ if ( this . first ) {
280+ newItems . push ( item ) ;
281+ } else if ( ! foundPrevItem && ! this . news . emit ( 'item' , item ) ) {
282+ foundPrevItem = true ;
283+ } else if ( foundPrevItem && this . news . emit ( 'item' , item ) ) {
284+ newItems . push ( item ) ;
260285 }
261286 } ;
262287
263288 req . pipe ( parser ) ;
264289
265290 req . on ( 'end' , ( ) => {
266- if ( ! ended ) {
267- if ( this . first && this . options . emitOnStart ) {
268- this . news . addHistory ( 'item' , this . newitems . map ( ( item ) => {
269- return [ item ] ;
270- } ) ) ;
271- }
272- success ( this . newitems ) ;
273- this . first = false ;
291+ if ( ended ) { return ; }
292+ // Process items in descending order if no order found at end.
293+ if ( sortOrder === 0 && newItems . length === 0 ) {
294+ items . forEach ( getOlderItem ) ;
274295 }
296+ success ( ) ;
297+ this . first = false ;
275298 } ) ;
276299 } ) ;
277300
0 commit comments