import { AdbBackend , BufferedStream , Stream } from '@yume-chan/adb' ; import { EventEmitter } from '@yume-chan/event' ; declare global { interface TCPSocket { close ( ) : Promise < void > ; readonly remoteAddress : string ; readonly remotePort : number ; readonly readable : ReadableStream ; readonly writable : WritableStream ; } interface SocketOptions { localAddress ? : string | undefined ; localPort ? : number | undefined ; remoteAddress : string ; remotePort : number ; sendBufferSize ? : number ; receiveBufferSize ? : number ; keepAlive ? : number ; noDelay ? : boolean ; } interface Navigator { openTCPSocket ( options ? ) : Promise < TCPSocket > ; } } export default class AdbDirectSocketsBackend implements AdbBackend { public static isSupported ( ) { return typeof window !== 'undefined' && ! ! window . navigator ?. openTCPSocket ; } public readonly serial : string ; public readonly address : string ; public readonly port : number ; public name : string | undefined ; private socket : TCPSocket | undefined ; private reader : ReadableStreamDefaultReader < Uint8Array > | undefined ; private bufferedStream : BufferedStream < Stream > | undefined ; private writer : WritableStreamDefaultWriter < Uint8Array > | undefined ; private _connected = false ; public get connected ( ) { return this . _connected ; } private readonly disconnectEvent = new EventEmitter < void > ( ) ; public readonly onDisconnected = this . disconnectEvent . event ; public constructor ( address , port = 5555 , name ? ) { this . address = address ; this . port = port ; this . serial = `${ address }:${ port }` ; this . name = name ; } public async connect ( ) { const socket = await navigator . openTCPSocket ( { remoteAddress : this . address , remotePort : this . port , noDelay : true , } ) ; this . socket = socket ; this . reader = this . socket . readable . getReader ( ) ; this . bufferedStream = new BufferedStream ( { read : async ( ) => { const result = await this . reader ! . read ( ) ; if ( result . value ) { return result . value . buffer ; } throw new Error ( 'Stream ended' ) ; } } ) ; this . writer = this . socket . writable . getWriter ( ) ; this . _connected = true ; } public write ( buffer ) { return this . writer ! . write ( new Uint8Array ( buffer ) ) ; } public async read ( length ) { return this . bufferedStream ! . read ( length ) ; } public dispose ( ) { this . socket ?. close ( ) ; this . _connected = false ; } }