@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.
@@ -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 { }