import { EventEmitter } from "events" ; const sync_tables = { } ; function get_name ( name ) { return `symmetric_channel:${ name }` ; } export async function browser_symmetric_channel ( _ , primus , logger , name ) { name = get_name ( name ) ; if ( sync_tables [ name ] !== undefined && sync_tables [ name ] . channel !== undefined ) { return name ; } const channel = primus . channel ( name ) ; let local ; if ( sync_tables [ name ] !== undefined ) { local = sync_tables [ name ] . local ; local . channel = channel ; sync_tables [ name ] . channel = channel ; } else { local = new SymmetricChannel ( channel ) ; sync_tables [ name ] = { local , channel , } ; } channel . on ( "connection" , function ( spark ) : void { logger . debug ( "sync" , name , `conn from ${ spark . address . ip } -- ${ spark . id }` ) ; spark . on ( "end" , function ( ) { logger . debug ( "sync" , name , `closed ${ spark . address . ip } -- ${ spark . id }` ) ; } ) ; spark . on ( "data" , function ( data ) { local . _data_from_spark ( data ) ; channel . forEach ( function ( spark0 , id ) { if ( id !== spark . id ) { spark0 . write ( data ) ; } } ) ; } ) ; } ) ; return name ; } class SymmetricChannel extends EventEmitter { channel : any ; constructor ( channel ? ) { super ( ) ; this . channel = channel ; } write ( data ) { if ( this . channel !== undefined ) { return this . channel . write ( data ) ; } return false ; } _data_from_spark ( data ) { this . emit ( "data" , data ) ; } } export function symmetric_channel ( name ) { name = get_name ( name ) ; if ( sync_tables [ name ] !== undefined ) { return sync_tables [ name ] . local ; } const local = new SymmetricChannel ( undefined ) ; sync_tables [ name ] = { local } ; return local ; }