59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
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 可能失败,忽略
|
||
}
|
||
}
|
||
}
|
||
}
|