diff options
Diffstat (limited to 'src/cdp')
| -rw-r--r-- | src/cdp/evaluate.ts | 30 | ||||
| -rw-r--r-- | src/cdp/event-queue.ts | 38 | ||||
| -rw-r--r-- | src/cdp/pending-requests.ts | 47 | ||||
| -rw-r--r-- | src/cdp/session.ts | 33 | ||||
| -rw-r--r-- | src/cdp/transport.ts | 18 | ||||
| -rw-r--r-- | src/cdp/types.ts | 17 |
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; +}; |
