const e=!("undefined"==typeof process||!process.versions||!process.versions.node),s=s=>e?require("debug")(s):(...e)=>{const t=globalThis.__PUPPETEER_DEBUG;if(!t)return;("*"===t||(t.endsWith("*")?s.startsWith(t):s===t))&&console.log(s+":",...e)};class t{constructor(){var e;this.eventsMap=new Map,this.emitter=(e=(e=this.eventsMap)||new Map,{on(s,t){const o=e.get(s);o&&o.push(t)||e.set(s,[t])},off(s,t){const o=e.get(s);o&&o.splice(o.indexOf(t)>>>0,1)},emit(s,t){(e.get(s)||[]).slice().map(e=>{e(t)}),(e.get("*")||[]).slice().map(e=>{e(s,t)})}})}on(e,s){return this.emitter.on(e,s),this}off(e,s){return this.emitter.off(e,s),this}removeListener(e,s){return this.off(e,s),this}addListener(e,s){return this.on(e,s),this}emit(e,s){return this.emitter.emit(e,s),this.eventListenersCount(e)>0}once(e,s){const t=o=>{s(o),this.off(e,t)};return this.on(e,t)}listenerCount(e){return this.eventListenersCount(e)}removeAllListeners(e){return e?this.eventsMap.delete(e):this.eventsMap.clear(),this}eventListenersCount(e){return this.eventsMap.has(e)?this.eventsMap.get(e).length:0}}const o=s("puppeteer:protocol:SEND ►"),r=s("puppeteer:protocol:RECV ◀"),n={Disconnected:Symbol("Connection.Disconnected")};class i extends t{constructor(e,s,t=0){super(),this._lastId=0,this._sessions=new Map,this._closed=!1,this._callbacks=new Map,this._url=e,this._delay=t,this._transport=s,this._transport.onmessage=this._onMessage.bind(this),this._transport.onclose=this._onClose.bind(this)}static fromSession(e){return e._connection}session(e){return this._sessions.get(e)||null}url(){return this._url}send(e,...s){const t=s.length?s[0]:void 0,o=this._rawSend({method:e,params:t});return new Promise((s,t)=>{this._callbacks.set(o,{resolve:s,reject:t,error:new Error,method:e})})}_rawSend(e){const s=++this._lastId;return e=JSON.stringify(Object.assign({},e,{id:s})),o(e),this._transport.send(e),s}async _onMessage(e){this._delay&&await new Promise(e=>setTimeout(e,this._delay)),r(e);const s=JSON.parse(e);if("Target.attachedToTarget"===s.method){const e=s.params.sessionId,t=new c(this,s.params.targetInfo.type,e);this._sessions.set(e,t)}else if("Target.detachedFromTarget"===s.method){const e=this._sessions.get(s.params.sessionId);e&&(e._onClosed(),this._sessions.delete(s.params.sessionId))}if(s.sessionId){const e=this._sessions.get(s.sessionId);e&&e._onMessage(s)}else if(s.id){const e=this._callbacks.get(s.id);e&&(this._callbacks.delete(s.id),s.error?e.reject(h(e.error,e.method,s)):e.resolve(s.result))}else this.emit(s.method,s.params)}_onClose(){if(!this._closed){this._closed=!0,this._transport.onmessage=null,this._transport.onclose=null;for(const e of this._callbacks.values())e.reject(l(e.error,`Protocol error (${e.method}): Target closed.`));this._callbacks.clear();for(const e of this._sessions.values())e._onClosed();this._sessions.clear(),this.emit(n.Disconnected)}}dispose(){this._onClose(),this._transport.close()}async createSession(e){const{sessionId:s}=await this.send("Target.attachToTarget",{targetId:e.targetId,flatten:!0});return this._sessions.get(s)}}const a={Disconnected:Symbol("CDPSession.Disconnected")};class c extends t{constructor(e,s,t){super(),this._callbacks=new Map,this._connection=e,this._targetType=s,this._sessionId=t}send(e,...s){if(!this._connection)return Promise.reject(new Error(`Protocol error (${e}): Session closed. Most likely the ${this._targetType} has been closed.`));const t=s.length?s[0]:void 0,o=this._connection._rawSend({sessionId:this._sessionId,method:e,params:t||{}});return new Promise((s,t)=>{this._callbacks.set(o,{resolve:s,reject:t,error:new Error,method:e})})}_onMessage(e){if(e.id&&this._callbacks.has(e.id)){const s=this._callbacks.get(e.id);this._callbacks.delete(e.id),e.error?s.reject(h(s.error,s.method,e)):s.resolve(e.result)}else((e,s)=>{if(!e)throw new Error(s)})(!e.id),this.emit(e.method,e.params)}async detach(){if(!this._connection)throw new Error(`Session already detached. Most likely the ${this._targetType} has been closed.`);await this._connection.send("Target.detachFromTarget",{sessionId:this._sessionId})}_onClosed(){for(const e of this._callbacks.values())e.reject(l(e.error,`Protocol error (${e.method}): Target closed.`));this._callbacks.clear(),this._connection=null,this.emit(a.Disconnected)}}function h(e,s,t){let o=`Protocol error (${s}): ${t.error.message}`;return"data"in t.error&&(o+=" "+t.error.data),l(e,o)}function l(e,s){return e.message=s,e}export{i as Connection};
