import { rendererEvents } from '../../../events' ; import { v4 } from 'uuid' ; import { storageStoreEvent , makeStorageResponseEvent , storageLoadEvent , storageClearEvent , makeStorageAcknowledgementEvent , } from '../../../events/StorageEvents' ; export interface StorageIdentifier < Model > { id : string ; } export interface PersistentStorage { store < Model > ( identifier , data ) : Promise < void > ; load < Model > ( identifier ) : Promise < Model | undefined > ; clear ( ) : Promise < void > ; } class RemoteStorage implements PersistentStorage { private timeoutCallback ( event , callback , reject ) { setTimeout ( ( ) => { reject ( 'remote storage timeout' ) ; rendererEvents . unsubscribe ( event , callback ) ; } , 10000 ) ; } private expectAck ( transactionId ) { const ack = makeStorageAcknowledgementEvent ( transactionId ) ; return new Promise < void > ( ( resolve , reject ) => { const callback = ( msg ) => { if ( msg && msg . error ) { reject ( msg . error ) ; } else { resolve ( ) ; } rendererEvents . unsubscribe ( ack , callback ) ; } ; rendererEvents . subscribe ( ack , callback ) ; this . timeoutCallback ( ack , callback , reject ) ; } ) ; } public store < Model > ( identifier , data ) { const transactionId = v4 ( ) ; const expectation = this . expectAck ( transactionId ) ; rendererEvents . emit ( storageStoreEvent , { data , transactionId , store : identifier . id , } ) ; return expectation ; } public load < Model > ( identifier ) { const transactionId = v4 ( ) ; const responseEvent = makeStorageResponseEvent ( transactionId ) ; const promise = new Promise < Model > ( ( resolve , reject ) => { const callback = ( msg ) => { if ( msg . error ) { reject ( msg . error ) ; } else { resolve ( msg . data ) ; } rendererEvents . unsubscribe ( responseEvent , callback ) ; } ; rendererEvents . subscribe ( responseEvent , callback ) ; this . timeoutCallback ( responseEvent , callback , reject ) ; } ) ; rendererEvents . emit ( storageLoadEvent , { transactionId , store : identifier . id , } ) ; return promise ; } public clear ( ) { const transactionId = v4 ( ) ; const expectation = this . expectAck ( transactionId ) ; rendererEvents . emit ( storageClearEvent , { transactionId } ) ; return expectation ; } } export default new RemoteStorage ( ) ;