aboutsummaryrefslogtreecommitdiff
path: root/src/cdp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cdp')
-rw-r--r--src/cdp/evaluate.ts30
-rw-r--r--src/cdp/event-queue.ts38
-rw-r--r--src/cdp/pending-requests.ts47
-rw-r--r--src/cdp/session.ts33
-rw-r--r--src/cdp/transport.ts18
-rw-r--r--src/cdp/types.ts17
6 files changed, 47 insertions, 136 deletions
diff --git a/src/cdp/evaluate.ts b/src/cdp/evaluate.ts
deleted file mode 100644
index 733a11b..0000000
--- a/src/cdp/evaluate.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { type Result, err, ok } from "../util/result";
-import { type CdpError, cdpError } from "./errors";
-import type { CdpSession } from "./session";
-
-export const evaluateJson = async <T>(
- session: CdpSession,
- expression: string,
- check: (v: unknown) => v is T,
- opts?: { sessionId?: string | undefined; timeoutMs?: number | undefined },
-): Promise<Result<T, CdpError>> => {
- const params = {
- expression,
- returnByValue: true,
- awaitPromise: true,
- };
- const callOpts = opts?.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {};
- const r = opts?.sessionId !== undefined
- ? await session.callOnTarget("Runtime.evaluate", params, opts.sessionId, callOpts)
- : await session.call("Runtime.evaluate", params, callOpts);
- if (!r.success) return r;
- const { result, exceptionDetails } = r.data;
- if (exceptionDetails !== undefined) {
- return err(cdpError("remote_error", exceptionDetails.text, "Runtime.evaluate"));
- }
- const value = result.value;
- if (!check(value)) {
- return err(cdpError("invalid_response", `unexpected evaluate shape (type: ${result.type}) for: ${expression.slice(0, 60)}`, "Runtime.evaluate"));
- }
- return ok(value);
-};
diff --git a/src/cdp/event-queue.ts b/src/cdp/event-queue.ts
deleted file mode 100644
index 08024b0..0000000
--- a/src/cdp/event-queue.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { CdpEvent } from "./types";
-
-export type EventQueue = {
- readonly push: (e: CdpEvent) => void;
- readonly end: () => void;
- readonly iter: AsyncIterable<CdpEvent>;
-};
-
-export const makeEventQueue = (): EventQueue => {
- const buf: CdpEvent[] = [];
- const waiters: Array<(v: IteratorResult<CdpEvent, undefined>) => void> = [];
- let ended = false;
- return {
- push(e) {
- if (ended) return;
- const w = waiters.shift();
- if (w) w({ value: e, done: false });
- else buf.push(e);
- },
- end() {
- ended = true;
- for (const w of waiters.splice(0)) w({ value: undefined, done: true });
- },
- iter: {
- [Symbol.asyncIterator](): AsyncIterator<CdpEvent, undefined, undefined> {
- return {
- next: (): Promise<IteratorResult<CdpEvent, undefined>> =>
- new Promise((resolve) => {
- const next = buf.shift();
- if (next) resolve({ value: next, done: false });
- else if (ended) resolve({ value: undefined, done: true });
- else waiters.push(resolve);
- }),
- };
- },
- },
- };
-};
diff --git a/src/cdp/pending-requests.ts b/src/cdp/pending-requests.ts
deleted file mode 100644
index 03b19cd..0000000
--- a/src/cdp/pending-requests.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { type Result, err } from "../util/result";
-import { type CdpError, cdpError } from "./errors";
-
-export type CdpResult = Result<unknown, CdpError>;
-
-export type Pending = {
- readonly resolve: (v: Result<unknown, CdpError>) => void;
- readonly timer: ReturnType<typeof setTimeout>;
- readonly method: string;
-};
-
-export const rejectAllPending = (pending: Map<number, Pending>, reason: string): void => {
- for (const [, p] of pending) {
- clearTimeout(p.timer);
- p.resolve(err(cdpError("transport_closed", reason, p.method)));
- }
- pending.clear();
-};
-
-export const sendWithTimeout = (
- pending: Map<number, Pending>,
- id: number,
- method: string,
- timeoutMs: number,
- timeoutLabel: string,
- send: () => void,
-): Promise<CdpResult> =>
- new Promise((resolve) => {
- const timer = setTimeout(() => {
- pending.delete(id);
- resolve(err(cdpError("timeout", `${timeoutLabel} timeout after ${timeoutMs}ms: ${method}`, method)));
- }, timeoutMs);
- pending.set(id, { resolve, timer, method });
- try {
- send();
- } catch (e) {
- clearTimeout(timer);
- pending.delete(id);
- resolve(err(cdpError("transport_closed", e instanceof Error ? e.message : String(e), method)));
- }
- });
-
-export const makeOnClose = (closeListeners: Set<() => void>) =>
- (cb: () => void): (() => void) => {
- closeListeners.add(cb);
- return () => closeListeners.delete(cb);
- };
diff --git a/src/cdp/session.ts b/src/cdp/session.ts
index 0eb83fa..5adf7e0 100644
--- a/src/cdp/session.ts
+++ b/src/cdp/session.ts
@@ -1,8 +1,8 @@
-import { map, type Result, ok } from "../util/result";
-import type { CdpError } from "./errors";
+import { map, type Result, err, ok } from "../util/result";
+import { type CdpError, cdpError } from "./errors";
import type { DialogInfo } from "./types";
import type { OwnershipRegistry } from "./ownership";
-import type { CdpTransport } from "./transport";
+import type { CdpTransport } from "./types";
import { type CdpMethod, type ParamsOf, type ResultOf, decodeResult } from "./commands";
import { decodeEvent } from "./events";
import { createNetworkBuffer, type DrainResult, type NetworkFilter } from "./network-buffer";
@@ -374,3 +374,30 @@ export const createCdpSession = (
};
return session;
};
+
+export const evaluateJson = async <T>(
+ session: CdpSession,
+ expression: string,
+ check: (v: unknown) => v is T,
+ opts?: { sessionId?: string | undefined; timeoutMs?: number | undefined },
+): Promise<Result<T, CdpError>> => {
+ const params = {
+ expression,
+ returnByValue: true,
+ awaitPromise: true,
+ };
+ const callOpts = opts?.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {};
+ const r = opts?.sessionId !== undefined
+ ? await session.callOnTarget("Runtime.evaluate", params, opts.sessionId, callOpts)
+ : await session.call("Runtime.evaluate", params, callOpts);
+ if (!r.success) return r;
+ const { result, exceptionDetails } = r.data;
+ if (exceptionDetails !== undefined) {
+ return err(cdpError("remote_error", exceptionDetails.text, "Runtime.evaluate"));
+ }
+ const value = result.value;
+ if (!check(value)) {
+ return err(cdpError("invalid_response", `unexpected evaluate shape (type: ${result.type}) for: ${expression.slice(0, 60)}`, "Runtime.evaluate"));
+ }
+ return ok(value);
+};
diff --git a/src/cdp/transport.ts b/src/cdp/transport.ts
deleted file mode 100644
index 4036ff7..0000000
--- a/src/cdp/transport.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { Result } from "../util/result";
-import type { CdpError } from "./errors";
-import type { CdpEvent } from "./types";
-
-export const DEFAULT_TIMEOUT_MS = 15_000;
-
-export type CdpTransport = {
- connect(url: string, opts?: { timeoutMs?: number }): Promise<Result<void, CdpError>>;
- close(): Promise<void>;
- request(
- method: string,
- params: Record<string, unknown>,
- opts?: { sessionId?: string | null; timeoutMs?: number },
- ): Promise<Result<unknown, CdpError>>;
- events(): AsyncIterable<CdpEvent>;
- state(): "open" | "closed" | "connecting";
- onClose(cb: () => void): () => void;
-};
diff --git a/src/cdp/types.ts b/src/cdp/types.ts
index 984b930..6119b69 100644
--- a/src/cdp/types.ts
+++ b/src/cdp/types.ts
@@ -1,4 +1,6 @@
+import type { Result } from "../util/result";
import { isRecord } from "../util/guards";
+import type { CdpError } from "./errors";
export type CdpEvent = {
readonly method: string;
@@ -63,3 +65,18 @@ export const isCdpRawMessage = (v: unknown): v is CdpRawMessage => {
}
return true;
};
+
+export const DEFAULT_TIMEOUT_MS = 15_000;
+
+export type CdpTransport = {
+ connect(url: string, opts?: { timeoutMs?: number }): Promise<Result<void, CdpError>>;
+ close(): Promise<void>;
+ request(
+ method: string,
+ params: Record<string, unknown>,
+ opts?: { sessionId?: string | null; timeoutMs?: number },
+ ): Promise<Result<unknown, CdpError>>;
+ events(): AsyncIterable<CdpEvent>;
+ state(): "open" | "closed" | "connecting";
+ onClose(cb: () => void): () => void;
+};