21 lines
1.5 KiB
JavaScript
21 lines
1.5 KiB
JavaScript
/** Bounded protocol calls for isolated browser fixtures, never product code. */
|
|
export function createCdpCalls(socket,{timeoutMs=30000,onEvent=()=>{},setTimer=setTimeout,clearTimer=clearTimeout}={}){
|
|
let serial=0,failure;const pending=new Map();
|
|
const fail=error=>{failure??=error;for(const row of pending.values()){clearTimer(row.timer);row.reject(failure);}pending.clear();};
|
|
socket.addEventListener('close',()=>fail(Error('CDP connection closed')));
|
|
socket.addEventListener('error',()=>fail(Error('CDP connection failed')));
|
|
socket.addEventListener('message',event=>{
|
|
try{
|
|
const message=JSON.parse(event.data);
|
|
if(!message.id){onEvent(message);if(['Inspector.targetCrashed','Inspector.detached','Target.targetCrashed','Page.javascriptDialogOpening'].includes(message.method))fail(Error('CDP target unavailable: '+message.method+' '+JSON.stringify(message.params??{})));return;}
|
|
const row=pending.get(message.id);if(!row)return;pending.delete(message.id);clearTimer(row.timer);message.error?row.reject(Error(JSON.stringify(message.error))):row.resolve(message.result);
|
|
}catch(error){fail(error);}
|
|
});
|
|
return(method,params={})=>new Promise((resolve,reject)=>{
|
|
if(failure){reject(failure);return;}
|
|
const id=++serial,row={resolve,reject,timer:undefined};pending.set(id,row);
|
|
row.timer=setTimer(()=>fail(Error(`CDP ${method} timed out after ${timeoutMs}ms`)),timeoutMs);
|
|
try{socket.send(JSON.stringify({id,method,params}));}catch(error){fail(error);}
|
|
});
|
|
}
|