import { VMProtocolSettingsIn , VMProtocolSettingsReturn } from '@neo-one/node-core' ; import * as nodePath from 'path' ; import { ApplicationEngine , CreateOptions } from './ApplicationEngine' ; import { BaseMethods , EngineMethods , SnapshotMethods , TestMethods } from './Methods' ; import { SnapshotHandler } from './SnapshotHandler' ; import { DispatcherFunc } from './types' ; import { constants , createCSharpDispatchInvoke , validateProtocolSettings } from './utils' ; export interface DispatcherMethods extends BaseMethods , SnapshotMethods , EngineMethods , TestMethods { } const engineAssemblyOptions = { assemblyFile : nodePath . join ( constants . CSHARP_APP_ROOT , 'Dispatcher.dll' ) , methodName : 'Invoke' , typeName : 'NEOONE.Dispatcher' } ; export const createDispatcher = ( ) => createCSharpDispatchInvoke < DispatcherMethods > ( engineAssemblyOptions ) ; export interface DispatcherOptions { readonly levelDBPath ? : string ; readonly protocolSettings ? : VMProtocolSettingsIn ; } export class Dispatcher { public readonly init : boolean ; public readonly dispatch : DispatcherFunc < DispatcherMethods > ; public readonly options : DispatcherOptions ; public constructor ( options = { } ) { this . options = options ; this . dispatch = createDispatcher ( ) ; this . init = this . initialize ( this . options . levelDBPath , this . options . protocolSettings ) ; } public withSnapshots < T = void > ( func ) { const main = new SnapshotHandler ( this , 'main' ) ; const clone = new SnapshotHandler ( this , 'clone' ) ; return func ( { main , clone } ) ; } public withApplicationEngine < T = void > ( options , func ) { const engine = new ApplicationEngine ( this ) ; engine . create ( options ) ; let result ; try { result = func ( engine ) ; } catch ( error ) { throw error ; } finally { this . disposeEngine ( ) ; } return result ; } public disposeEngine ( ) { this . dispatch ( { method : 'dispose_engine' } ) ; } public updateSnapshots ( ) { this . dispatch ( { method : 'snapshot_reset' } ) ; } public dispose ( ) { this . dispatch ( { method : 'dispose' } ) ; } public reset ( ) { this . dispose ( ) ; this . initialize ( this . options . levelDBPath ) ; } public getConfig ( ) { return this . dispatch ( { method : 'get_config' } ) ; } public updateSnapshot ( key , id , value ) { return this . dispatch ( { method : 'test_snapshot_add' , args : { key , id , value } } ) ; } public readSnapshot ( key , id ) { return this . dispatch ( { method : 'test_snapshot_get' , args : { key , id } } ) ; } public updateStore ( storage ) { this . dispatch ( { method : 'test_update_store' , args : { changes : storage } } ) ; } public readStore ( key ) { return this . dispatch ( { method : 'test_read_store' , args : { key } } ) ; } public test ( ) { return this . dispatch ( { method : 'test' } ) ; } private initialize ( path ? , settings ? ) { return this . dispatch ( { method : 'init' , args : { path , settings : settings ? validateProtocolSettings ( settings ) : undefined } } ) ; } }