@orkestrel/browser 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/src/core/index.cjs +1209 -0
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +742 -0
- package/dist/src/core/index.d.ts +742 -0
- package/dist/src/core/index.js +1174 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/server/index.cjs +1172 -0
- package/dist/src/server/index.cjs.map +1 -0
- package/dist/src/server/index.d.cts +567 -0
- package/dist/src/server/index.d.ts +567 -0
- package/dist/src/server/index.js +1120 -0
- package/dist/src/server/index.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
import { EmitterHooks } from '@orkestrel/emitter';
|
|
2
|
+
import { EmitterInterface } from '@orkestrel/emitter';
|
|
3
|
+
|
|
4
|
+
/** Base64 alphabet, index-ordered, used to build {@link BASE64_LOOKUP}. */
|
|
5
|
+
export declare const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
6
|
+
|
|
7
|
+
/** Base64 character to 6-bit value lookup table, derived from {@link BASE64_CHARS}. */
|
|
8
|
+
export declare const BASE64_LOOKUP: Readonly<Record<string, number>>;
|
|
9
|
+
|
|
10
|
+
/** Name of the CDP runtime binding the codegen recorder script calls into. */
|
|
11
|
+
export declare const BROWSER_CODEGEN_BINDING_NAME = "__orkestrelBrowserCodegen";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* In-page recorder script injected via `Page.addScriptToEvaluateOnNewDocument`
|
|
15
|
+
* and `Runtime.evaluate`.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Attaches capturing-phase listeners for `click`, `input` (fill), and
|
|
19
|
+
* `change` (select) on `document`, builds a stable CSS selector for the
|
|
20
|
+
* target element, and forwards each action to the CDP binding
|
|
21
|
+
* ({@link BROWSER_CODEGEN_BINDING_NAME}) as a JSON string payload. Guarded to
|
|
22
|
+
* install exactly once per document (`window[name]` sentinel) so repeated
|
|
23
|
+
* injection on every new document is idempotent.
|
|
24
|
+
*/
|
|
25
|
+
export declare const BROWSER_CODEGEN_SOURCE: string;
|
|
26
|
+
|
|
27
|
+
/** Default timeout in milliseconds for browser connection, requests, and navigation. */
|
|
28
|
+
export declare const BROWSER_DEFAULT_TIMEOUT_MS = 30000;
|
|
29
|
+
|
|
30
|
+
/** Default viewport height in pixels. */
|
|
31
|
+
export declare const BROWSER_DEFAULT_VIEWPORT_HEIGHT = 720;
|
|
32
|
+
|
|
33
|
+
/** Default viewport width in pixels. */
|
|
34
|
+
export declare const BROWSER_DEFAULT_VIEWPORT_WIDTH = 1280;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Maximum serialized-character length for an `evaluate()`/`content()` result,
|
|
38
|
+
* enforced IN-PAGE before the result is returned to CDP.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* This counts UTF-16 STRING LENGTH (`String#length`), not transport BYTES —
|
|
42
|
+
* the actual CDP frame is UTF-8 encoded (up to 3 bytes/char for common
|
|
43
|
+
* multibyte content) and carries additional JSON/CDP framing overhead on top
|
|
44
|
+
* of the raw content. A `Runtime.evaluate` result above this size, once
|
|
45
|
+
* framed as a CDP JSON response, overflows the native WebSocket inbound frame
|
|
46
|
+
* limit and closes the whole CDP connection — a page-level failure with no
|
|
47
|
+
* clean error. The limit is set well under the observed ~3-4MB transport
|
|
48
|
+
* ceiling (rather than at it) to leave headroom for the length-vs-bytes gap
|
|
49
|
+
* and framing overhead. The cap is enforced by stringifying the candidate
|
|
50
|
+
* result in-page and throwing a recognizable sentinel error (see
|
|
51
|
+
* {@link BROWSER_RESULT_LIMIT_SENTINEL_PREFIX}) before the oversized frame is
|
|
52
|
+
* ever produced, so the caller gets a coded error instead of a dropped
|
|
53
|
+
* connection.
|
|
54
|
+
*/
|
|
55
|
+
export declare const BROWSER_RESULT_LIMIT = 2500000;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Matches the in-page result-limit sentinel error message, anchored
|
|
59
|
+
* immediately after the `Error: ` (optionally `Uncaught Error: `) prefix that
|
|
60
|
+
* Chromium prepends to a thrown error's description — so the guard's own
|
|
61
|
+
* throw is recognized only at the message START, not wherever the substring
|
|
62
|
+
* happens to occur.
|
|
63
|
+
*/
|
|
64
|
+
export declare const BROWSER_RESULT_LIMIT_PATTERN: RegExp;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Distinctive prefix for the in-page result-limit sentinel error, immediately
|
|
68
|
+
* followed by the serialized length.
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* Deliberately unlikely to appear in a page's own thrown error text (unlike
|
|
72
|
+
* a plain `BROWSER_RESULT_LIMIT: ` label), so {@link BROWSER_RESULT_LIMIT_PATTERN}
|
|
73
|
+
* can distinguish the guard's own throw from a page error that merely
|
|
74
|
+
* mentions similar text.
|
|
75
|
+
*/
|
|
76
|
+
export declare const BROWSER_RESULT_LIMIT_SENTINEL_PREFIX = "[[ORKESTREL_BROWSER_RESULT_LIMIT]]";
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Bound (in milliseconds) on the best-effort `Page.stopLoading` call issued
|
|
80
|
+
* after a failed `navigate()`.
|
|
81
|
+
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* A wedged renderer can make the underlying CDP call hang for the full
|
|
84
|
+
* per-call timeout; capping it to a small fixed bound keeps a navigate
|
|
85
|
+
* failure's total latency close to the original timeout instead of doubling
|
|
86
|
+
* it. Best-effort only — never masks the original navigate error.
|
|
87
|
+
*/
|
|
88
|
+
export declare const BROWSER_STOP_LOADING_TIMEOUT_MS = 1000;
|
|
89
|
+
|
|
90
|
+
/** Poll interval in milliseconds while waiting for a selector to appear. */
|
|
91
|
+
export declare const BROWSER_WAIT_POLL_INTERVAL_MS = 100;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Options for element interaction (click, fill, select, wait).
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* - `timeout` — maximum time to wait for the selector in milliseconds
|
|
98
|
+
*/
|
|
99
|
+
export declare interface BrowserActionOptions {
|
|
100
|
+
readonly timeout?: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export declare class BrowserCodegen implements BrowserCodegenInterface {
|
|
104
|
+
#private;
|
|
105
|
+
constructor(client: CDPClientInterface, sessionId: string, options?: BrowserCodegenOptions);
|
|
106
|
+
get emitter(): EmitterInterface<BrowserCodegenEventMap>;
|
|
107
|
+
get started(): boolean;
|
|
108
|
+
start(): Promise<void>;
|
|
109
|
+
stop(): Promise<readonly BrowserCodegenAction[]>;
|
|
110
|
+
actions(): readonly BrowserCodegenAction[];
|
|
111
|
+
script(options?: BrowserCodegenScriptOptions): string;
|
|
112
|
+
clear(): void;
|
|
113
|
+
destroy(): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** One recorded browser action captured during a codegen session. */
|
|
117
|
+
export declare type BrowserCodegenAction = {
|
|
118
|
+
readonly action: 'navigate';
|
|
119
|
+
readonly url: string;
|
|
120
|
+
} | {
|
|
121
|
+
readonly action: 'click';
|
|
122
|
+
readonly selector: string;
|
|
123
|
+
} | {
|
|
124
|
+
readonly action: 'fill';
|
|
125
|
+
readonly selector: string;
|
|
126
|
+
readonly value: string;
|
|
127
|
+
} | {
|
|
128
|
+
readonly action: 'select';
|
|
129
|
+
readonly selector: string;
|
|
130
|
+
readonly values: readonly string[];
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Event map for a {@link BrowserCodegenInterface}.
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* - `start` — recording started
|
|
138
|
+
* - `stop` — recording stopped, carrying the final action list
|
|
139
|
+
* - `action` — one new action was captured
|
|
140
|
+
* - `clear` — recorded actions were reset
|
|
141
|
+
*/
|
|
142
|
+
export declare type BrowserCodegenEventMap = {
|
|
143
|
+
readonly start: readonly [];
|
|
144
|
+
readonly stop: readonly [actions: readonly BrowserCodegenAction[]];
|
|
145
|
+
readonly action: readonly [action: BrowserCodegenAction];
|
|
146
|
+
readonly clear: readonly [];
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Records page interactions (navigation, click, fill, select) as a session
|
|
151
|
+
* runs, for later compilation into a replayable script.
|
|
152
|
+
*
|
|
153
|
+
* @remarks
|
|
154
|
+
* - `emitter` — subscribe to recording lifecycle and capture events
|
|
155
|
+
* - `started` — true while actively recording
|
|
156
|
+
* - `start` — begin recording on the page's session
|
|
157
|
+
* - `stop` — stop recording and return the captured actions
|
|
158
|
+
* - `actions` — current normalized action list
|
|
159
|
+
* - `script` — compile the captured actions into a script
|
|
160
|
+
* - `clear` — reset the captured action list
|
|
161
|
+
* - `destroy` — tear down the recorder and detach CDP listeners
|
|
162
|
+
*/
|
|
163
|
+
export declare interface BrowserCodegenInterface {
|
|
164
|
+
readonly emitter: EmitterInterface<BrowserCodegenEventMap>;
|
|
165
|
+
readonly started: boolean;
|
|
166
|
+
start(): Promise<void>;
|
|
167
|
+
stop(): Promise<readonly BrowserCodegenAction[]>;
|
|
168
|
+
actions(): readonly BrowserCodegenAction[];
|
|
169
|
+
script(options?: BrowserCodegenScriptOptions): string;
|
|
170
|
+
clear(): void;
|
|
171
|
+
destroy(): Promise<void>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Target language for a compiled codegen script. */
|
|
175
|
+
export declare type BrowserCodegenLanguage = 'javascript' | 'typescript';
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Options for creating a BrowserCodegen recorder.
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* - `on` — initial event listeners wired at construction
|
|
182
|
+
*/
|
|
183
|
+
export declare interface BrowserCodegenOptions {
|
|
184
|
+
readonly on?: EmitterHooks<BrowserCodegenEventMap>;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Options for compiling recorded actions into a script.
|
|
189
|
+
*
|
|
190
|
+
* @remarks
|
|
191
|
+
* - `language` — target output language (default `'javascript'`)
|
|
192
|
+
*/
|
|
193
|
+
export declare interface BrowserCodegenScriptOptions {
|
|
194
|
+
readonly language?: BrowserCodegenLanguage;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Result of page content extraction.
|
|
199
|
+
*
|
|
200
|
+
* @remarks
|
|
201
|
+
* - `url` — current page URL after navigation
|
|
202
|
+
* - `title` — document title
|
|
203
|
+
* - `html` — full HTML source
|
|
204
|
+
* - `text` — visible text content (no markup)
|
|
205
|
+
*/
|
|
206
|
+
export declare interface BrowserContentResult {
|
|
207
|
+
readonly url: string;
|
|
208
|
+
readonly title: string;
|
|
209
|
+
readonly html: string;
|
|
210
|
+
readonly text: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export declare class BrowserContext implements BrowserContextInterface {
|
|
214
|
+
#private;
|
|
215
|
+
constructor(client: CDPClientInterface, id?: string, viewport?: BrowserViewport, writer?: ScreenshotWriterInterface);
|
|
216
|
+
get id(): string | undefined;
|
|
217
|
+
page(index?: number): BrowserPageInterface | undefined;
|
|
218
|
+
pages(): readonly BrowserPageInterface[];
|
|
219
|
+
create(options?: BrowserPageOptions): Promise<BrowserPageInterface>;
|
|
220
|
+
sync(targets: readonly CDPTarget[]): Promise<void>;
|
|
221
|
+
close(): Promise<void>;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Isolated browser session over a CDP browser context.
|
|
226
|
+
*
|
|
227
|
+
* @remarks
|
|
228
|
+
* Follows the manager accessor pattern:
|
|
229
|
+
* - `page(index?)` → one page by index or the first page
|
|
230
|
+
* - `pages()` → all pages in creation order
|
|
231
|
+
*
|
|
232
|
+
* - `create` — open a new page in this context
|
|
233
|
+
* - `sync` — synchronize pages from the given CDP targets (server discovers
|
|
234
|
+
* the targets; core never fetches them itself)
|
|
235
|
+
* - `close` — close the context and all its pages
|
|
236
|
+
*/
|
|
237
|
+
export declare interface BrowserContextInterface {
|
|
238
|
+
readonly id: string | undefined;
|
|
239
|
+
page(index?: number): BrowserPageInterface | undefined;
|
|
240
|
+
pages(): readonly BrowserPageInterface[];
|
|
241
|
+
create(options?: BrowserPageOptions): Promise<BrowserPageInterface>;
|
|
242
|
+
sync(targets: readonly CDPTarget[]): Promise<void>;
|
|
243
|
+
close(): Promise<void>;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Base error for all browser automation operations.
|
|
248
|
+
*
|
|
249
|
+
* @remarks
|
|
250
|
+
* Carries a machine-readable `code` and optional `context` (AGENTS §12) so
|
|
251
|
+
* callers can branch in a `catch` without parsing message strings.
|
|
252
|
+
*/
|
|
253
|
+
export declare class BrowserError extends Error {
|
|
254
|
+
readonly code: string;
|
|
255
|
+
readonly context: Readonly<Record<string, unknown>> | undefined;
|
|
256
|
+
constructor(message: string, code?: string, context?: Readonly<Record<string, unknown>>);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* One frame in a page's frame tree, as reported by CDP `Page.getFrameTree`.
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* - `id` — the frame's CDP frame id
|
|
264
|
+
* - `parent` — the parent frame's id, undefined for the main frame
|
|
265
|
+
* - `name` — the frame's `name`/`id` HTML attribute, undefined when not set
|
|
266
|
+
* - `url` — the frame's current URL
|
|
267
|
+
*/
|
|
268
|
+
export declare type BrowserFrame = {
|
|
269
|
+
readonly id: string;
|
|
270
|
+
readonly parent?: string;
|
|
271
|
+
readonly name?: string;
|
|
272
|
+
readonly url: string;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Options for page navigation.
|
|
277
|
+
*
|
|
278
|
+
* @remarks
|
|
279
|
+
* - `condition` — page load condition to wait for (default `'load'`)
|
|
280
|
+
* - `timeout` — bounds the whole navigate call (the `Page.navigate` send
|
|
281
|
+
* itself plus the load-event wait), in milliseconds
|
|
282
|
+
*/
|
|
283
|
+
export declare interface BrowserNavigationOptions {
|
|
284
|
+
readonly condition?: BrowserWaitUntil;
|
|
285
|
+
readonly timeout?: number;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export declare class BrowserPage implements BrowserPageInterface {
|
|
289
|
+
#private;
|
|
290
|
+
constructor(client: CDPClientInterface, targetId: string, sessionId: string, writer?: ScreenshotWriterInterface, url?: string);
|
|
291
|
+
get url(): string;
|
|
292
|
+
get closed(): boolean;
|
|
293
|
+
title(): Promise<string>;
|
|
294
|
+
navigate(url: string, options?: BrowserNavigationOptions): Promise<void>;
|
|
295
|
+
content(): Promise<BrowserContentResult>;
|
|
296
|
+
screenshot(options?: BrowserScreenshotOptions): Promise<BrowserScreenshotResult>;
|
|
297
|
+
click(selector: string, options?: BrowserActionOptions): Promise<void>;
|
|
298
|
+
fill(selector: string, value: string, options?: BrowserActionOptions): Promise<void>;
|
|
299
|
+
select(selector: string, values: readonly string[], options?: BrowserActionOptions): Promise<void>;
|
|
300
|
+
evaluate(expression: string): Promise<unknown>;
|
|
301
|
+
wait(selector: string, options?: BrowserActionOptions): Promise<void>;
|
|
302
|
+
frame(name: string): Promise<BrowserFrame | undefined>;
|
|
303
|
+
frames(): Promise<readonly BrowserFrame[]>;
|
|
304
|
+
codegen(options?: BrowserCodegenOptions): Promise<BrowserCodegenInterface>;
|
|
305
|
+
close(): Promise<void>;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Abstraction over a single browser page or frame.
|
|
310
|
+
*
|
|
311
|
+
* @remarks
|
|
312
|
+
* - `url` — current URL; when the page was constructed with a seeded url
|
|
313
|
+
* (e.g. reattaching to an existing CDP target), reports that url
|
|
314
|
+
* immediately, before any `navigate()`/`content()` call refreshes it
|
|
315
|
+
* - `closed` — true after `close()` is called
|
|
316
|
+
* - `title` — resolve the document title
|
|
317
|
+
* - `navigate` — go to a URL and wait for the specified load condition
|
|
318
|
+
* - `content` — extract page URL, title, HTML, and visible text
|
|
319
|
+
* - `screenshot` — capture a PNG or JPEG image of the page
|
|
320
|
+
* - `click` — click an element matching the selector
|
|
321
|
+
* - `fill` — type text into an input element
|
|
322
|
+
* - `select` — choose option(s) in a `<select>` element
|
|
323
|
+
* - `evaluate` — execute a JavaScript expression in the page context
|
|
324
|
+
* - `wait` — wait for an element matching the selector to appear
|
|
325
|
+
* - `frame` — look up a frame by name or URL in the page's flattened frame tree
|
|
326
|
+
* - `frames` — list the page's flattened frame tree, main frame first
|
|
327
|
+
* - `codegen` — start (or return the existing) action recorder for this page
|
|
328
|
+
* - `close` — close the page
|
|
329
|
+
*/
|
|
330
|
+
export declare interface BrowserPageInterface {
|
|
331
|
+
readonly url: string;
|
|
332
|
+
readonly closed: boolean;
|
|
333
|
+
title(): Promise<string>;
|
|
334
|
+
navigate(url: string, options?: BrowserNavigationOptions): Promise<void>;
|
|
335
|
+
content(): Promise<BrowserContentResult>;
|
|
336
|
+
screenshot(options?: BrowserScreenshotOptions): Promise<BrowserScreenshotResult>;
|
|
337
|
+
click(selector: string, options?: BrowserActionOptions): Promise<void>;
|
|
338
|
+
fill(selector: string, value: string, options?: BrowserActionOptions): Promise<void>;
|
|
339
|
+
select(selector: string, values: readonly string[], options?: BrowserActionOptions): Promise<void>;
|
|
340
|
+
evaluate(expression: string): Promise<unknown>;
|
|
341
|
+
wait(selector: string, options?: BrowserActionOptions): Promise<void>;
|
|
342
|
+
frame(name: string): Promise<BrowserFrame | undefined>;
|
|
343
|
+
frames(): Promise<readonly BrowserFrame[]>;
|
|
344
|
+
codegen(options?: BrowserCodegenOptions): Promise<BrowserCodegenInterface>;
|
|
345
|
+
close(): Promise<void>;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Options for creating a browser page.
|
|
350
|
+
*
|
|
351
|
+
* @remarks
|
|
352
|
+
* - `url` — navigate to this URL immediately after creation
|
|
353
|
+
* - `viewport` — override the context-level default viewport
|
|
354
|
+
* - `timeout` — navigation timeout for the initial URL
|
|
355
|
+
*/
|
|
356
|
+
export declare interface BrowserPageOptions {
|
|
357
|
+
readonly url?: string;
|
|
358
|
+
readonly viewport?: BrowserViewport;
|
|
359
|
+
readonly timeout?: number;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* An `evaluate()`/`content()` result exceeded {@link BROWSER_RESULT_LIMIT}
|
|
364
|
+
* and was rejected in-page before it could overflow the CDP transport frame.
|
|
365
|
+
*/
|
|
366
|
+
export declare class BrowserResultLimitError extends BrowserError {
|
|
367
|
+
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Options for taking a page screenshot.
|
|
372
|
+
*
|
|
373
|
+
* @remarks
|
|
374
|
+
* - `path` — file path to persist the screenshot to, via the page's writer
|
|
375
|
+
* - `full` — capture the full scrollable page (default `false`)
|
|
376
|
+
* - `type` — image format (default `'png'`)
|
|
377
|
+
* - `quality` — JPEG quality 0–100 (ignored for PNG)
|
|
378
|
+
*/
|
|
379
|
+
export declare interface BrowserScreenshotOptions {
|
|
380
|
+
readonly path?: string;
|
|
381
|
+
readonly full?: boolean;
|
|
382
|
+
readonly type?: 'png' | 'jpeg';
|
|
383
|
+
readonly quality?: number;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Result of a page screenshot.
|
|
388
|
+
*
|
|
389
|
+
* @remarks
|
|
390
|
+
* - `bytes` — raw image bytes
|
|
391
|
+
* - `path` — file path if persisted via the page's writer, otherwise undefined
|
|
392
|
+
*/
|
|
393
|
+
export declare interface BrowserScreenshotResult {
|
|
394
|
+
readonly bytes: Uint8Array;
|
|
395
|
+
readonly path: string | undefined;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* A selector-based lookup or wait timed out without the element appearing.
|
|
400
|
+
*/
|
|
401
|
+
export declare class BrowserSelectorError extends BrowserError {
|
|
402
|
+
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** Viewport dimensions for a browser page. */
|
|
406
|
+
export declare interface BrowserViewport {
|
|
407
|
+
readonly width: number;
|
|
408
|
+
readonly height: number;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/** Page load condition for navigation — the CDP load event awaited by `navigate()`. */
|
|
412
|
+
export declare type BrowserWaitUntil = 'load' | 'domcontentloaded';
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Lightweight Chrome DevTools Protocol client over a {@link CDPTransportInterface}.
|
|
416
|
+
*
|
|
417
|
+
* @remarks
|
|
418
|
+
* Sends JSON-RPC messages over the injected transport and dispatches
|
|
419
|
+
* responses and events. The transport owns the connection itself
|
|
420
|
+
* (WebSocket, pipe, or any other duplex channel); this class owns only
|
|
421
|
+
* the JSON-RPC framing and id/session correlation.
|
|
422
|
+
*
|
|
423
|
+
* Supports session-scoped event subscriptions: when a sessionId is
|
|
424
|
+
* provided to subscribe/unsubscribe, the handler only fires for CDP
|
|
425
|
+
* events carrying that sessionId. Global subscriptions (no sessionId)
|
|
426
|
+
* continue to see ALL events for backwards compatibility.
|
|
427
|
+
*/
|
|
428
|
+
export declare class CDPClient implements CDPClientInterface {
|
|
429
|
+
#private;
|
|
430
|
+
constructor(options: CDPClientOptions);
|
|
431
|
+
get connected(): boolean;
|
|
432
|
+
connect(): Promise<void>;
|
|
433
|
+
/**
|
|
434
|
+
* Close the transport and re-establish a fresh connection.
|
|
435
|
+
*
|
|
436
|
+
* @remarks
|
|
437
|
+
* Client-level subscriptions (`subscribe`/`unsubscribe` registrations)
|
|
438
|
+
* survive `close()` and remain active after the reconnect — only pending
|
|
439
|
+
* in-flight requests are rejected. This lets a caller reconnect a dropped
|
|
440
|
+
* transport without re-registering every handler.
|
|
441
|
+
*/
|
|
442
|
+
reconnect(): Promise<void>;
|
|
443
|
+
send(method: string, params?: Readonly<Record<string, unknown>>, sessionId?: string, timeout?: number): Promise<unknown>;
|
|
444
|
+
subscribe(method: string, handler: CDPHandler, sessionId?: string): void;
|
|
445
|
+
unsubscribe(method: string, handler: CDPHandler, sessionId?: string): void;
|
|
446
|
+
/**
|
|
447
|
+
* Close the transport and reject all pending requests.
|
|
448
|
+
*
|
|
449
|
+
* @remarks
|
|
450
|
+
* Subscriptions registered via `subscribe()` are client-level
|
|
451
|
+
* registrations, not connection-level state — they survive `close()`
|
|
452
|
+
* (and a subsequent `reconnect()`/`connect()`) and keep firing once the
|
|
453
|
+
* transport is active again. Only pending requests are rejected here.
|
|
454
|
+
* If `close()` is called while `connect()` is still awaiting
|
|
455
|
+
* `transport.start()`, the in-flight connect is rejected and the
|
|
456
|
+
* transport is closed deterministically once `start()` resolves.
|
|
457
|
+
*/
|
|
458
|
+
close(): Promise<void>;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Lightweight Chrome DevTools Protocol client over a {@link CDPTransportInterface}.
|
|
463
|
+
*
|
|
464
|
+
* @remarks
|
|
465
|
+
* - `connected` — true while the transport is active
|
|
466
|
+
* - `connect` — start the transport and begin dispatching
|
|
467
|
+
* - `reconnect` — close and re-establish the transport
|
|
468
|
+
* - `send` — issue a CDP method call, optionally session-scoped, optionally
|
|
469
|
+
* bounded by a per-call timeout that overrides the client-wide default for
|
|
470
|
+
* this one request
|
|
471
|
+
* - `subscribe` / `unsubscribe` — register/remove a handler for a CDP event,
|
|
472
|
+
* optionally session-scoped
|
|
473
|
+
* - `close` — tear down the transport and reject all pending requests
|
|
474
|
+
*/
|
|
475
|
+
export declare interface CDPClientInterface {
|
|
476
|
+
readonly connected: boolean;
|
|
477
|
+
connect(): Promise<void>;
|
|
478
|
+
reconnect(): Promise<void>;
|
|
479
|
+
send(method: string, params?: Readonly<Record<string, unknown>>, sessionId?: string, timeout?: number): Promise<unknown>;
|
|
480
|
+
subscribe(method: string, handler: CDPHandler, sessionId?: string): void;
|
|
481
|
+
unsubscribe(method: string, handler: CDPHandler, sessionId?: string): void;
|
|
482
|
+
close(): Promise<void>;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Options for creating a CDPClient.
|
|
487
|
+
*
|
|
488
|
+
* @remarks
|
|
489
|
+
* - `transport` — the text pipe the client sends/receives JSON-RPC frames over
|
|
490
|
+
* - `timeout` — ms before a pending request or connection attempt fails (default from constants)
|
|
491
|
+
*/
|
|
492
|
+
export declare interface CDPClientOptions {
|
|
493
|
+
readonly transport: CDPTransportInterface;
|
|
494
|
+
readonly timeout?: number;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* A CDP request could not be sent or completed because the client was not in
|
|
499
|
+
* a connectable state (not connected, closed while connecting, or the
|
|
500
|
+
* connection dropped mid-request).
|
|
501
|
+
*/
|
|
502
|
+
export declare class CDPConnectionError extends BrowserError {
|
|
503
|
+
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* A CDP request received an error response from the remote endpoint.
|
|
508
|
+
*
|
|
509
|
+
* @remarks
|
|
510
|
+
* Carries the originating `method` plus the CDP error's own `code`,
|
|
511
|
+
* `message`, and `data` (when present) in `context`, so callers can branch
|
|
512
|
+
* on the protocol-level error instead of parsing the message string.
|
|
513
|
+
*/
|
|
514
|
+
export declare class CDPError extends BrowserError {
|
|
515
|
+
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/** Handler invoked for a subscribed CDP event with its params record. */
|
|
519
|
+
export declare type CDPHandler = (params: Readonly<Record<string, unknown>>) => void;
|
|
520
|
+
|
|
521
|
+
/** One entry of the CDP `Target.getTargets` result. */
|
|
522
|
+
export declare interface CDPTarget {
|
|
523
|
+
readonly id: string;
|
|
524
|
+
readonly type: string;
|
|
525
|
+
readonly title: string;
|
|
526
|
+
readonly url: string;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* A pending CDP request was not answered within its timeout window.
|
|
531
|
+
*/
|
|
532
|
+
export declare class CDPTimeoutError extends BrowserError {
|
|
533
|
+
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Event map for a {@link CDPTransportInterface} — the raw text pipe a
|
|
538
|
+
* {@link CDPClientInterface} sends and receives JSON-RPC frames over.
|
|
539
|
+
*
|
|
540
|
+
* @remarks
|
|
541
|
+
* `message` carries one raw text frame; `close` signals the underlying
|
|
542
|
+
* connection ended; `error` carries a transport-level fault (unknown shape —
|
|
543
|
+
* narrow before use).
|
|
544
|
+
*/
|
|
545
|
+
export declare type CDPTransportEventMap = {
|
|
546
|
+
readonly message: readonly [data: string];
|
|
547
|
+
readonly close: readonly [];
|
|
548
|
+
readonly error: readonly [error: unknown];
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* A dumb text transport CDPClient sends and receives JSON-RPC frames over.
|
|
553
|
+
*
|
|
554
|
+
* @remarks
|
|
555
|
+
* The transport owns the connection (WebSocket, pipe, or any other duplex
|
|
556
|
+
* channel) and the endpoint URL; it does no JSON framing of its own — that
|
|
557
|
+
* stays in {@link CDPClientInterface}. Environment-specific transports
|
|
558
|
+
* (a Node `WebSocket`, a browser `WebSocket`) live outside core and satisfy
|
|
559
|
+
* this contract.
|
|
560
|
+
*/
|
|
561
|
+
export declare interface CDPTransportInterface {
|
|
562
|
+
readonly emitter: EmitterInterface<CDPTransportEventMap>;
|
|
563
|
+
start(): Promise<void>;
|
|
564
|
+
send(data: string): Promise<void>;
|
|
565
|
+
close(): Promise<void>;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Compile recorded codegen actions into a replayable script.
|
|
570
|
+
*
|
|
571
|
+
* @remarks
|
|
572
|
+
* Emits one statement per action against a `page` object shaped like
|
|
573
|
+
* {@link BrowserPageInterface} (`page.navigate(...)`, `page.click(...)`, …).
|
|
574
|
+
* Both target languages emit an `async function run(page)` body whose
|
|
575
|
+
* statements are `await`-ed; `language` only toggles whether the `page`
|
|
576
|
+
* parameter carries a TypeScript type annotation (default `'javascript'`).
|
|
577
|
+
*
|
|
578
|
+
* @param actions - Normalized actions to compile
|
|
579
|
+
* @param options - Compilation options (target language)
|
|
580
|
+
* @returns The compiled script source
|
|
581
|
+
*/
|
|
582
|
+
export declare function compileCodegenScript(actions: readonly BrowserCodegenAction[], options?: BrowserCodegenScriptOptions): string;
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Create a CDP client bound to the given transport.
|
|
586
|
+
*
|
|
587
|
+
* @param options - The transport (and optional timeout) the client uses
|
|
588
|
+
* @returns A {@link CDPClientInterface}
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```ts
|
|
592
|
+
* import { createCDPClient } from '@src/core'
|
|
593
|
+
*
|
|
594
|
+
* const client = createCDPClient({ transport })
|
|
595
|
+
* await client.connect()
|
|
596
|
+
* ```
|
|
597
|
+
*/
|
|
598
|
+
export declare function createCDPClient(options: CDPClientOptions): CDPClientInterface;
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Decode a base64-encoded string into raw bytes.
|
|
602
|
+
*
|
|
603
|
+
* @remarks
|
|
604
|
+
* Pure JS implementation — no `Buffer`, no `atob` (DOM-only) — so it runs
|
|
605
|
+
* identically in Node and browser environments. Whitespace and `=` padding
|
|
606
|
+
* are ignored; invalid characters are skipped.
|
|
607
|
+
*
|
|
608
|
+
* @param text - Base64-encoded input string
|
|
609
|
+
* @returns Decoded bytes
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* decodeBase64('aGVsbG8=') // Uint8Array [104, 101, 108, 108, 111]
|
|
614
|
+
* ```
|
|
615
|
+
*/
|
|
616
|
+
export declare function decodeBase64(text: string): Uint8Array;
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Wrap a `Runtime.evaluate` expression so the IN-PAGE code stringifies its
|
|
620
|
+
* own result and throws a recognizable error before an oversized result
|
|
621
|
+
* would overflow the CDP transport frame.
|
|
622
|
+
*
|
|
623
|
+
* @remarks
|
|
624
|
+
* A result whose `JSON.stringify` length exceeds `limit` throws
|
|
625
|
+
* `Error('BROWSER_RESULT_LIMIT: <length>')` inside the page instead of being
|
|
626
|
+
* returned — the caller maps that sentinel to a coded
|
|
627
|
+
* {@link BrowserResultLimitError}. A non-serializable result (`undefined`,
|
|
628
|
+
* a function, a symbol) makes `JSON.stringify` return `undefined`, so the
|
|
629
|
+
* length check is skipped and today's undefined-passthrough behavior is
|
|
630
|
+
* unchanged.
|
|
631
|
+
*
|
|
632
|
+
* The expression is placed on its own line inside the wrapper (rather than
|
|
633
|
+
* inline with the guard code) so a trailing `//` line comment in the
|
|
634
|
+
* expression cannot swallow the closing guard syntax that follows it.
|
|
635
|
+
*
|
|
636
|
+
* @param expression - The candidate JavaScript expression to evaluate
|
|
637
|
+
* @param limit - Maximum serialized-character length (see {@link BROWSER_RESULT_LIMIT})
|
|
638
|
+
* @returns The wrapped, guarded expression
|
|
639
|
+
*/
|
|
640
|
+
export declare function guardEvaluateExpression(expression: string, limit: number): string;
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Narrow an unknown value to BrowserError.
|
|
644
|
+
*
|
|
645
|
+
* @param value - Value to check
|
|
646
|
+
* @returns True when value is a BrowserError instance
|
|
647
|
+
*/
|
|
648
|
+
export declare function isBrowserError(value: unknown): value is BrowserError;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Narrow an unknown value to BrowserResultLimitError.
|
|
652
|
+
*
|
|
653
|
+
* @param value - Value to check
|
|
654
|
+
* @returns True when value is a BrowserResultLimitError instance
|
|
655
|
+
*/
|
|
656
|
+
export declare function isBrowserResultLimitError(value: unknown): value is BrowserResultLimitError;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Narrow an unknown value to BrowserSelectorError.
|
|
660
|
+
*
|
|
661
|
+
* @param value - Value to check
|
|
662
|
+
* @returns True when value is a BrowserSelectorError instance
|
|
663
|
+
*/
|
|
664
|
+
export declare function isBrowserSelectorError(value: unknown): value is BrowserSelectorError;
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Narrow an unknown value to CDPConnectionError.
|
|
668
|
+
*
|
|
669
|
+
* @param value - Value to check
|
|
670
|
+
* @returns True when value is a CDPConnectionError instance
|
|
671
|
+
*/
|
|
672
|
+
export declare function isCDPConnectionError(value: unknown): value is CDPConnectionError;
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Narrow an unknown value to CDPError.
|
|
676
|
+
*
|
|
677
|
+
* @param value - Value to check
|
|
678
|
+
* @returns True when value is a CDPError instance
|
|
679
|
+
*/
|
|
680
|
+
export declare function isCDPError(value: unknown): value is CDPError;
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Narrow an unknown value to CDPTimeoutError.
|
|
684
|
+
*
|
|
685
|
+
* @param value - Value to check
|
|
686
|
+
* @returns True when value is a CDPTimeoutError instance
|
|
687
|
+
*/
|
|
688
|
+
export declare function isCDPTimeoutError(value: unknown): value is CDPTimeoutError;
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Normalize a raw list of recorded codegen actions.
|
|
692
|
+
*
|
|
693
|
+
* @remarks
|
|
694
|
+
* Collapses consecutive `fill` actions on the same selector into the latest
|
|
695
|
+
* value (a text input fires one `input` event per keystroke) so the
|
|
696
|
+
* compiled script reflects the final typed value rather than every
|
|
697
|
+
* intermediate keystroke.
|
|
698
|
+
*
|
|
699
|
+
* @param actions - Raw recorded actions, in capture order
|
|
700
|
+
* @returns Normalized actions, in the same order
|
|
701
|
+
*/
|
|
702
|
+
export declare function normalizeCodegenActions(actions: readonly BrowserCodegenAction[]): readonly BrowserCodegenAction[];
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Parse a codegen binding payload into a typed action.
|
|
706
|
+
*
|
|
707
|
+
* @remarks
|
|
708
|
+
* The in-page recorder script calls the CDP binding with a JSON string
|
|
709
|
+
* payload shaped like a {@link BrowserCodegenAction}. Returns `undefined`
|
|
710
|
+
* when the payload is not valid JSON or does not match a known action shape.
|
|
711
|
+
*
|
|
712
|
+
* @param payload - Raw binding call payload (the CDP `payload` param)
|
|
713
|
+
* @returns The parsed action, or `undefined` when the payload is malformed
|
|
714
|
+
*/
|
|
715
|
+
export declare function parseCodegenActionPayload(payload: unknown): BrowserCodegenAction | undefined;
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Derive a `navigate` codegen action from a `Page.frameNavigated` CDP event.
|
|
719
|
+
*
|
|
720
|
+
* @remarks
|
|
721
|
+
* Only the top-level (main) frame's navigation is recorded — a frame
|
|
722
|
+
* carrying a `parentId` is a sub-frame and is ignored.
|
|
723
|
+
*
|
|
724
|
+
* @param params - The CDP `Page.frameNavigated` event params
|
|
725
|
+
* @returns A `navigate` action, or `undefined` when the event is not a
|
|
726
|
+
* top-level navigation with a resolvable URL
|
|
727
|
+
*/
|
|
728
|
+
export declare function readCodegenNavigateAction(params: Readonly<Record<string, unknown>>): BrowserCodegenAction | undefined;
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Pluggable sink for persisting screenshot bytes to a path.
|
|
732
|
+
*
|
|
733
|
+
* @remarks
|
|
734
|
+
* Core never touches a filesystem directly — a page accepts an optional
|
|
735
|
+
* writer (server supplies an `fs`-backed implementation) and calls it when a
|
|
736
|
+
* screenshot request carries a `path`.
|
|
737
|
+
*/
|
|
738
|
+
export declare interface ScreenshotWriterInterface {
|
|
739
|
+
write(path: string, data: Uint8Array): Promise<void>;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
export { }
|