PRA-only-demo/src/main/browser/transport.ts

59 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { BrowserWindow } from "electron";
import { RuntimeError, mapCdpError, type CdpEventHandler, type CdpTransport } from "@rpa/core";
/**
* 内置运行浏览器传输层(宿主适配层,任务 2.3)。
*
* 包装 Electron BrowserWindow.webContents.debugger,实现包内的 CdpTransport 接口;
* CdpTransport / mapCdpError / ExternalTransport(外部浏览器)已迁入 @rpa/core。
*/
export class EmbeddedTransport implements CdpTransport {
readonly kind = "embedded" as const;
private wrappers = new Map<CdpEventHandler, (event: unknown, method: string, params?: Record<string, unknown>) => void>();
constructor(private win: BrowserWindow) {}
get closed(): boolean {
return this.win.isDestroyed();
}
async send<T = unknown>(method: string, params: Record<string, unknown> = {}): Promise<T> {
if (this.win.isDestroyed()) {
throw new RuntimeError("tab_unavailable", "运行浏览器已关闭", { recommendation: "重新运行流程" });
}
try {
if (!this.win.webContents.debugger.isAttached()) this.win.webContents.debugger.attach("1.3");
return (await this.win.webContents.debugger.sendCommand(method, params)) as T;
} catch (error) {
throw mapCdpError(error, "embedded");
}
}
on(method: string, handler: CdpEventHandler): void {
if (this.win.isDestroyed()) return;
const wrapper = (_event: unknown, evtMethod: string, evtParams?: Record<string, unknown>) => {
if (evtMethod === method) handler(evtParams ?? {});
};
this.wrappers.set(handler, wrapper);
this.win.webContents.debugger.on("message", wrapper as never);
}
off(method: string, handler: CdpEventHandler): void {
const wrapper = this.wrappers.get(handler);
if (wrapper) {
this.win.webContents.debugger.removeListener("message", wrapper as never);
this.wrappers.delete(handler);
}
}
async close(): Promise<void> {
if (!this.win.isDestroyed() && this.win.webContents.debugger.isAttached()) {
try {
this.win.webContents.debugger.detach();
} catch {
// 窗口关闭过程中 detach 可能失败,忽略
}
}
}
}