import { assertExists } from '@ulangi/assert' ; import { SyncTask } from '@ulangi/ulangi-common/enums' ; import * as EventEmitter from 'eventemitter3' ; import * as _ from 'lodash' ; import { EventChannel , eventChannel } from 'redux-saga' ; export class SyncQueue { private queue : SyncTask [ ] = [ ] ; private priorityMap : Map < SyncTask , number > ; private eventEmitter = new EventEmitter ( ) ; public constructor ( priority ) { this . priorityMap = new Map ( priority ) ; } public shift ( ) { return this . queue . shift ( ) ; } public add ( syncTask ) { this . queue . push ( syncTask ) ; this . queue = _ . uniq ( this . queue ) ; this . sortQueueByPriority ( ) ; this . eventEmitter . emit ( 'SYNC_TASK_ADDED' , syncTask ) ; } public isEmpty ( ) { return this . queue . length === 0 ; } public createChannel ( eventName ) { return eventChannel ( ( emitter ) : ( ( ) => EventEmitter ) => { const listener = ( syncTask ) : void => { emitter ( syncTask ) ; } ; this . eventEmitter . addListener ( eventName , listener ) ; return ( ) : EventEmitter => this . eventEmitter . removeListener ( eventName , listener ) ; } ) ; } private sortQueueByPriority ( ) { this . queue . sort ( ( a , b ) : number => { const priorityOfA = assertExists ( this . priorityMap . get ( a ) ) ; const priorityOfB = assertExists ( this . priorityMap . get ( b ) ) ; return priorityOfA - priorityOfB ; } ) ; } }