import { CLIENT_MASTER , Signal , WebSocketTransport , Transport , } from "@web-udp/protocol" ; import { Connection , ConnectionProvider , ConnectionOptions } from "./provider" ; import { RTCConnectionProvider } from "./provider/web-rtc" ; interface ClientOptions { provider ? : ConnectionProvider ; transport ? : Transport ; url ? : string ; } export class Client { private provider : ConnectionProvider ; private _route : Promise < string > ; connections : Signal < Connection > = new Signal ( ) ; constructor ( options ) { let provider ; let transport ; if ( options . provider ) { provider = options . provider ; transport = options . transport ; } else { let { url = `ws://${ location . hostname }:${ location . port }` } = options ; url = url . replace ( /^http/ , "ws" ) ; if ( url . indexOf ( "ws" ) < 0 ) { url = `ws://${ url }` ; } transport = new WebSocketTransport ( new WebSocket ( url ) ) ; provider = new RTCConnectionProvider ( { transport , onConnection : connection => this . connections . dispatch ( connection ) , } ) ; } this . provider = provider ; this . _route = new Promise ( resolve => { const handle = message => { if ( message . type === "ROUTE" ) { resolve ( message . route ) ; transport . unsubscribe ( handle ) ; } } ; transport . subscribe ( handle ) ; } ) ; if ( typeof window !== "undefined" ) { window . addEventListener ( "beforeunload" , ( ) => { transport . close ( ) ; } ) ; } } async connect ( to = CLIENT_MASTER , options ? ) { if ( typeof to === "object" && to !== null ) { return this . provider . create ( CLIENT_MASTER , to ) ; } if ( typeof to === "string" ) { return this . provider . create ( to , options ) ; } throw new Error ( `Invalid options provided to Client.connect()` ) ; } route ( ) { return this . _route ; } close ( id ) { this . provider . close ( id ) ; } } export { RTCConnectionProvider } ;