123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.MapperCdpConnection = void 0;
- const log_js_1 = require("../utils/log.js");
- const CdpClient_js_1 = require("./CdpClient.js");
- /**
- * Represents a high-level CDP connection to the browser backend.
- *
- * Manages all CdpClients (each backed by a Session ID) instance for each active
- * CDP session.
- */
- class MapperCdpConnection {
- static LOGGER_PREFIX_RECV = `${log_js_1.LogType.cdp}:RECV ◂`;
- static LOGGER_PREFIX_SEND = `${log_js_1.LogType.cdp}:SEND ▸`;
- #mainBrowserCdpClient;
- #transport;
- /** Map from session ID to CdpClient.
- * `undefined` points to the main browser session. */
- #sessionCdpClients = new Map();
- #commandCallbacks = new Map();
- #logger;
- #nextId = 0;
- constructor(transport, logger) {
- this.#transport = transport;
- this.#logger = logger;
- this.#transport.setOnMessage(this.#onMessage);
- // Create default Browser CDP Session.
- this.#mainBrowserCdpClient = this.#createCdpClient(undefined);
- }
- /** Closes the connection to the browser. */
- close() {
- this.#transport.close();
- for (const [, { reject, error }] of this.#commandCallbacks) {
- reject(error);
- }
- this.#commandCallbacks.clear();
- this.#sessionCdpClients.clear();
- }
- async createBrowserSession() {
- const { sessionId } = await this.#mainBrowserCdpClient.sendCommand('Target.attachToBrowserTarget');
- return this.#createCdpClient(sessionId);
- }
- /**
- * Gets a CdpClient instance attached to the given session ID,
- * or null if the session is not attached.
- */
- getCdpClient(sessionId) {
- const cdpClient = this.#sessionCdpClients.get(sessionId);
- if (!cdpClient) {
- throw new Error(`Unknown CDP session ID: ${sessionId}`);
- }
- return cdpClient;
- }
- sendCommand(method, params, sessionId) {
- return new Promise((resolve, reject) => {
- const id = this.#nextId++;
- this.#commandCallbacks.set(id, {
- resolve,
- reject,
- error: new CdpClient_js_1.CloseError(`${method} ${JSON.stringify(params)} ${sessionId ?? ''} call rejected because the connection has been closed.`),
- });
- const cdpMessage = { id, method, params };
- if (sessionId) {
- cdpMessage.sessionId = sessionId;
- }
- void this.#transport
- .sendMessage(JSON.stringify(cdpMessage))
- ?.catch((error) => {
- this.#logger?.(log_js_1.LogType.debugError, error);
- this.#transport.close();
- });
- this.#logger?.(MapperCdpConnection.LOGGER_PREFIX_SEND, cdpMessage);
- });
- }
- #onMessage = (json) => {
- const message = JSON.parse(json);
- this.#logger?.(MapperCdpConnection.LOGGER_PREFIX_RECV, message);
- // Update client map if a session is attached
- // Listen for these events on every session.
- if (message.method === 'Target.attachedToTarget') {
- const { sessionId } = message.params;
- this.#createCdpClient(sessionId);
- }
- if (message.id !== undefined) {
- // Handle command response.
- const callbacks = this.#commandCallbacks.get(message.id);
- this.#commandCallbacks.delete(message.id);
- if (callbacks) {
- if (message.result) {
- callbacks.resolve(message.result);
- }
- else if (message.error) {
- callbacks.reject(message.error);
- }
- }
- }
- else if (message.method) {
- const client = this.#sessionCdpClients.get(message.sessionId ?? undefined);
- client?.emit(message.method, message.params || {});
- // Update client map if a session is detached
- // But emit on that session
- if (message.method === 'Target.detachedFromTarget') {
- const { sessionId } = message.params;
- const client = this.#sessionCdpClients.get(sessionId);
- if (client) {
- this.#sessionCdpClients.delete(sessionId);
- client.removeAllListeners();
- }
- }
- }
- };
- /**
- * Creates a new CdpClient instance for the given session ID.
- * @param sessionId either a string, or undefined for the main browser session.
- * The main browser session is used only to create new browser sessions.
- * @private
- */
- #createCdpClient(sessionId) {
- const cdpClient = new CdpClient_js_1.MapperCdpClient(this, sessionId);
- this.#sessionCdpClients.set(sessionId, cdpClient);
- return cdpClient;
- }
- }
- exports.MapperCdpConnection = MapperCdpConnection;
- //# sourceMappingURL=CdpConnection.js.map
|