@@ -320,13 +320,16 @@ module.exports = Kuzzle = function (url, options, cb) {
320320 } ,
321321 eventListeners : {
322322 value : {
323- connected : [ ] ,
324- error : [ ] ,
325- disconnected : [ ] ,
326- reconnected : [ ] ,
327- jwtTokenExpired : [ ]
323+ connected : { lastEmitted : null , listeners : [ ] } ,
324+ error : { lastEmitted : null , listeners : [ ] } ,
325+ disconnected : { lastEmitted : null , listeners : [ ] } ,
326+ reconnected : { lastEmitted : null , listeners : [ ] } ,
327+ jwtTokenExpired : { lastEmitted : null , listeners : [ ] }
328328 }
329329 } ,
330+ eventTimeout : {
331+ value : 200
332+ } ,
330333 io : {
331334 value : null ,
332335 writable : true
@@ -503,6 +506,28 @@ module.exports = Kuzzle = function (url, options, cb) {
503506 }
504507 } ) ;
505508
509+ /*
510+ * Emit an event to all registered listeners
511+ * An event cannot be emitted multiple times before a timeout has been reached.
512+ */
513+ Object . defineProperty ( this , 'emitEvent' , {
514+ value : function emitEvent ( event ) {
515+ var
516+ now = Date . now ( ) ,
517+ args = Array . prototype . slice . call ( arguments , 1 ) ;
518+
519+ if ( this . eventListeners [ event ] . lastEmitted && this . eventListeners [ event ] . lastEmitted >= now - this . eventTimeout ) {
520+ return false ;
521+ }
522+
523+ this . eventListeners [ event ] . listeners . forEach ( function ( listener ) {
524+ listener . fn . apply ( this , args ) ;
525+ } ) ;
526+
527+ this . eventListeners [ event ] . lastEmitted = now ;
528+ }
529+ } ) ;
530+
506531
507532 if ( ! options || ! options . connect || options . connect === 'auto' ) {
508533 this . connect ( ) ;
@@ -514,7 +539,9 @@ module.exports = Kuzzle = function (url, options, cb) {
514539 return this . bluebird . promisifyAll ( this , {
515540 suffix : 'Promise' ,
516541 filter : function ( name , func , target , passes ) {
517- var whitelist = [ 'getAllStatistics' , 'getServerInfo' , 'getStatistics' , 'listCollections' , 'listIndexes' , 'login' , 'logout' , 'now' , 'query' ] ;
542+ var whitelist = [ 'getAllStatistics' , 'getServerInfo' , 'getStatistics' ,
543+ 'listCollections' , 'listIndexes' , 'login' , 'logout' , 'now' , 'query' ,
544+ 'checkToken' ] ;
518545
519546 return passes && whitelist . indexOf ( name ) !== - 1 ;
520547 }
@@ -551,7 +578,7 @@ Kuzzle.prototype.connect = function () {
551578 self . state = 'connected' ;
552579 renewAllSubscriptions . call ( self ) ;
553580 dequeue . call ( self ) ;
554- emitEvent . call ( self , 'connected' ) ;
581+ self . emitEvent ( 'connected' ) ;
555582
556583 if ( self . connectCB ) {
557584 self . connectCB ( null , self ) ;
@@ -560,7 +587,7 @@ Kuzzle.prototype.connect = function () {
560587
561588 self . socket . on ( 'connect_error' , function ( error ) {
562589 self . state = 'error' ;
563- emitEvent . call ( self , 'error' ) ;
590+ self . emitEvent ( 'error' ) ;
564591
565592 if ( self . connectCB ) {
566593 self . connectCB ( error ) ;
@@ -578,7 +605,7 @@ Kuzzle.prototype.connect = function () {
578605 self . queuing = true ;
579606 }
580607
581- emitEvent . call ( self , 'disconnected' ) ;
608+ self . emitEvent ( 'disconnected' ) ;
582609 } ) ;
583610
584611 self . socket . on ( 'reconnect' , function ( ) {
@@ -596,7 +623,7 @@ Kuzzle.prototype.connect = function () {
596623 }
597624
598625 // alert listeners
599- emitEvent . call ( self , 'reconnected' ) ;
626+ self . emitEvent ( 'reconnected' ) ;
600627 } ) ;
601628
602629 return this ;
@@ -719,9 +746,7 @@ Kuzzle.prototype.checkToken = function (token, callback) {
719746 }
720747 } ;
721748
722- if ( typeof callback !== 'function' ) {
723- throw new Error ( 'The provided callback is not a function' ) ;
724- }
749+ this . callbackRequired ( 'Kuzzle.checkToken' , callback ) ;
725750
726751 this . query ( { controller : 'auth' , action : 'checkToken' } , request , { } , callback ) ;
727752
@@ -768,7 +793,8 @@ function emitRequest (request, cb) {
768793 if ( self . jwtToken !== undefined || cb ) {
769794 self . socket . once ( request . requestId , function ( response ) {
770795 if ( response . error && response . error . message === 'Token expired' ) {
771- emitEvent . call ( self , 'jwtTokenExpired' , request , cb ) ;
796+ self . jwtToken = undefined ;
797+ self . emitEvent ( 'jwtTokenExpired' , request , cb ) ;
772798 }
773799
774800 if ( cb ) {
@@ -823,21 +849,6 @@ function renewAllSubscriptions() {
823849 } ) ;
824850}
825851
826- /**
827- * Emits an event to all registered listeners
828- *
829- * @param {string } event - name of the target global event
830- */
831- function emitEvent ( event ) {
832- var
833- self = this ,
834- args = Array . prototype . slice . call ( arguments , 1 ) ;
835-
836- self . eventListeners [ event ] . forEach ( function ( listener ) {
837- listener . fn . apply ( self , args ) ;
838- } ) ;
839- }
840-
841852/**
842853 * Adds a listener to a Kuzzle global event. When an event is fired, listeners are called in the order of their
843854 * insertion.
@@ -865,7 +876,7 @@ Kuzzle.prototype.addListener = function(event, listener) {
865876 }
866877
867878 listenerId = uuid . v1 ( ) ;
868- this . eventListeners [ event ] . push ( { id : listenerId , fn : listener } ) ;
879+ this . eventListeners [ event ] . listeners . push ( { id : listenerId , fn : listener } ) ;
869880 return listenerId ;
870881} ;
871882
@@ -1252,10 +1263,10 @@ Kuzzle.prototype.removeAllListeners = function (event) {
12521263 throw new Error ( '[' + event + '] is not a known event. Known events: ' + knownEvents . toString ( ) ) ;
12531264 }
12541265
1255- this . eventListeners [ event ] = [ ] ;
1266+ this . eventListeners [ event ] . listeners = [ ] ;
12561267 } else {
12571268 knownEvents . forEach ( function ( eventName ) {
1258- self . eventListeners [ eventName ] = [ ] ;
1269+ self . eventListeners [ eventName ] . listeners = [ ] ;
12591270 } ) ;
12601271 }
12611272} ;
@@ -1275,9 +1286,9 @@ Kuzzle.prototype.removeListener = function (event, listenerId) {
12751286 throw new Error ( '[' + event + '] is not a known event. Known events: ' + knownEvents . toString ( ) ) ;
12761287 }
12771288
1278- this . eventListeners [ event ] . forEach ( function ( listener , index ) {
1289+ this . eventListeners [ event ] . listeners . forEach ( function ( listener , index ) {
12791290 if ( listener . id === listenerId ) {
1280- self . eventListeners [ event ] . splice ( index , 1 ) ;
1291+ self . eventListeners [ event ] . listeners . splice ( index , 1 ) ;
12811292 }
12821293 } ) ;
12831294} ;
@@ -2528,7 +2539,8 @@ function dequeue () {
25282539module . exports = KuzzleDocument ;
25292540
25302541} , { } ] , 6 :[ function ( require , module , exports ) {
2531- var uuid = require ( 'node-uuid' ) ;
2542+ var
2543+ uuid = require ( 'node-uuid' ) ;
25322544
25332545/**
25342546 * This is a global callback pattern, called by all asynchronous functions of the Kuzzle object.
@@ -2834,6 +2846,11 @@ function notificationCallback (data) {
28342846 return this . callback ( data . error ) ;
28352847 }
28362848
2849+ if ( data . action === 'jwtTokenExpired' ) {
2850+ this . kuzzle . jwtToken = undefined ;
2851+ return this . kuzzle . emitEvent ( 'jwtTokenExpired' ) ;
2852+ }
2853+
28372854 if ( this . kuzzle . requestHistory [ data . requestId ] ) {
28382855 if ( this . subscribeToSelf ) {
28392856 this . callback ( null , data ) ;
0 commit comments