aboutsummaryrefslogtreecommitdiff
path: root/src/cdp/pending-requests.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/cdp/pending-requests.ts')
-rw-r--r--src/cdp/pending-requests.ts47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/cdp/pending-requests.ts b/src/cdp/pending-requests.ts
new file mode 100644
index 0000000..03b19cd
--- /dev/null
+++ b/src/cdp/pending-requests.ts
@@ -0,0 +1,47 @@
+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);
+ };