export * from './generate' ; export * from './middleware' ; export * from './plugin' ; interface IHasName { name : string ; [ s ] : any ; } export interface IObject < T > { [ s ] : T ; } export function objectify < T , T2 = T > ( array , map ) { return array . reduce ( ( store , x ) => { store [ x . name ] = map ? map ( x ) : x ; return store ; } , { } ) ; } const isNullOrUndefined = ( x ) => x === null || x === undefined ; export function isEqual ( rowsA , rowsB , revisionField = 'rev' ) { if ( Array . isArray ( rowsA ) && rowsA . length === 0 ) { rowsA = null ; } if ( Array . isArray ( rowsB ) && rowsB . length === 0 ) { rowsB = null ; } if ( rowsA === rowsB ) { return true ; } if ( isNullOrUndefined ( rowsA ) && isNullOrUndefined ( rowsB ) ) { return true ; } if ( ( ! rowsA && rowsB ) || ( rowsA && ! rowsB ) ) { return false ; } if ( typeof rowsA === 'bigint' || typeof rowsA === 'boolean' || typeof rowsA === 'number' || typeof rowsA === 'string' ) { return rowsA === rowsB ; } if ( rowsA instanceof Date ) { if ( ! ( rowsB instanceof Date ) ) { return false ; } return + rowsA === + rowsB ; } function extrapolate ( item ) { return `${ item . id }|${ item [ revisionField ] }` ; } function isEqualSingle ( itemA , itemB ) { if ( itemA === itemB ) { return true ; } if ( ! itemA && ! itemB ) { return true ; } if ( ( ! itemA && itemB ) || ( itemA && ! itemB ) ) { return false ; } return extrapolate ( itemA as any ) === extrapolate ( itemB as any ) ; } if ( ! Array . isArray ( rowsA ) && ! Array . isArray ( rowsB ) ) { return isEqualSingle ( rowsA , rowsB ) ; } if ( ( rowsA as any [ ] ) . length !== ( rowsB as any [ ] ) . length ) { return false ; } if ( ( rowsA as any [ ] ) . map ( extrapolate ) . join ( '|' ) !== ( rowsB as any [ ] ) . map ( extrapolate ) . join ( '|' ) ) { return false ; } return true ; } interface IListeners { [ s ] : Function [ ] ; } export class Emitter { listeners : IListeners = { } ; get numberOfListeners ( ) { return Object . keys ( this . listeners ) . reduce ( ( state , key ) => state + this . listeners [ key ] . length , 0 ) ; } proxyTo ( obj ) { obj . once = this . once ; obj . on = this . on ; obj . emit = this . emit ; obj . listeners = this . listeners ; obj . $args = this . $args ; obj . $o = this . $o ; } private $args ( nameOrListener , mayBeListener ? ) { if ( ! mayBeListener && typeof nameOrListener === 'function' ) { return [ '*' , nameOrListener ] ; } else if ( mayBeListener && typeof nameOrListener === 'string' ) { return [ nameOrListener , mayBeListener ] ; } else { throw new Error ( 'Please provide either name and listener or only listener to on function' ) ; } } private $o ( name , listener ) { this . listeners [ name ] = this . listeners [ name ] || [ ] ; this . listeners [ name ] . push ( listener ) ; return ( ) => { var index = this . listeners [ name ] . indexOf ( listener ) ; if ( index !== - 1 ) { this . listeners [ name ] . splice ( index , 1 ) ; } } ; } on ( listener ) ; on ( name , listener ) ; on ( nameOrListener , mayBeListener ? ) { const [ name , listener ] = this . $args ( nameOrListener , mayBeListener ) ; return this . $o ( name , listener ) ; } once ( listener ) ; once ( name , listener ) ; once ( nameOrListener , mayBeListener ? ) { const [ name , listener ] = this . $args ( nameOrListener , mayBeListener ) ; const unlisten = this . $o ( name , ( ... args ) => { unlisten ( ) ; listener ( ... args ) ; } ) ; return unlisten ; } close ( ) { this . listeners = { } ; } emit ( name , ... args ) { const listeners = [ ... ( this . listeners [ name ] || [ ] ) , ... ( this . listeners [ '*' ] || [ ] ) ] ; let i = listeners . length ; const promises = [ ] ; if ( listeners . length ) { while ( i -- ) { let result = listeners [ i ] ( ... args ) ; if ( result && result . then ) { promises . push ( result ) ; } } } return Promise . all ( promises ) ; } }