import { combineRaceCancellation , disposablePromise , throwIfCancelled , } from "race-cancellation" ; import type { AttachProtocolTransport , AttachSession , NewEventEmitter , Protocol , ProtocolConnection , RaceCancellation , RootConnection , SessionConnection , SessionID , TargetID , } from "../types" ; import type { Session } from "./newEventHook" ; import newEventHook from "./newEventHook" ; param connect param newEventEmitter export default function newRootConnection ( attach , newEventEmitter ) { return newProtocolConnection ( attach , newEventEmitter ) ; } function newSessionConnection ( attachSession , newEventEmitter , session ) { return newProtocolConnection ( attachSession ( session . sessionId ) , newEventEmitter , session ) ; } function newProtocolConnection ( attachTransport , newEventEmitter , session ) ; function newProtocolConnection ( attachTransport , newEventEmitter ) ; function newProtocolConnection ( attachTransport , newEventEmitter , session ? ) { const emitter = newEventEmitter ( ) ; let isDetached = false ; const [ onTargetAttached , onTargetDetached , send , raceDetached , ] = attachTransport ( onEvent , onError , onDetached ) ; const [ eventHook , connection , clearSessions ] = newEventHook ( newSessionConnection . bind ( null , onTargetAttached , newEventEmitter ) , onTargetDetached ) ; const base = { attachToTarget , connection , off : emitter . removeListener . bind ( emitter ) , on : emitter . on . bind ( emitter ) , once : emitter . once . bind ( emitter ) , raceDetached , removeAllListeners : emitter . removeAllListeners . bind ( emitter ) , removeListener : emitter . removeListener . bind ( emitter ) , send , setAutoAttach , until , get isDetached ( ) { return isDetached ; } , } ; if ( session !== undefined ) { return Object . create ( base , { sessionId : { get : ( ) => session . sessionId , } , targetId : { get : ( ) => session . targetId , } , targetInfo : { get : ( ) => session . targetInfo , } , } ) as SessionConnection ; } return base ; async function attachToTarget ( targetId , raceCancellation ? ) { if ( typeof targetId === "object" && targetId !== null ) { targetId = targetId . targetId ; } const request = { flatten : true , targetId } ; const conn = connection ( request , false ) ; if ( conn !== undefined ) { return conn ; } const resp = await send ( "Target.attachToTarget" , request , raceCancellation ) ; return connection ( resp ) ; } async function setAutoAttach ( autoAttach , waitForDebuggerOnStart = false , raceCancellation ? ) { const request = { autoAttach , flatten : true , waitForDebuggerOnStart , } ; await send ( "Target.setAutoAttach" , request , raceCancellation ) ; } function onEvent ( event , params ? ) { eventHook ( event , params ) ; emitter . emit ( event , params ) ; } function onError ( error ) { emitter . emit ( "error" , error ) ; } function onDetached ( ) { if ( isDetached ) { return ; } isDetached = true ; clearSessions ( ) ; emitter . emit ( "detached" ) ; } async function until < Event > ( eventName , predicate ? , raceCancellation ? ) { return throwIfCancelled ( await disposablePromise < Event > ( ( resolve , reject ) => { const listener = predicate === undefined ? resolve : ( event ) => { try { if ( predicate ( event ) ) { resolve ( event ) ; } } catch ( e ) { reject ( e ) ; } } ; emitter . on ( eventName , listener ) ; return ( ) => { emitter . removeListener ( eventName , listener ) ; } ; } , combineRaceCancellation ( raceDetached , raceCancellation ) ) ) ; } }