@ap3x/browser 0.1.0 → 0.2.0

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.
@@ -1,11 +1,12 @@
1
1
  import { CdpConnectionError } from "../errors";
2
2
  import type { CdpConnection } from "./connection";
3
- export interface ReconnectEvents {
3
+ export interface ReconnectEvents<T = CdpConnection> {
4
4
  onReconnecting?: (attempt: number, max: number) => void;
5
- onReconnected?: (connection: CdpConnection) => void;
5
+ onReconnected?: (connection: T) => void;
6
6
  onFailed?: (err: CdpConnectionError) => void;
7
7
  }
8
8
  export interface ReconnectOptions {
9
+ signal?: AbortSignal;
9
10
  /** Number of attempts (default 3). */
10
11
  attempts?: number;
11
12
  /** Backoff before attempts 2..N (default [1000, 2000, 4000] ms). */
@@ -18,5 +19,7 @@ export interface ReconnectOptions {
18
19
  * that fires when the per-attempt budget is exceeded. Resolves with the first
19
20
  * successful connection or throws a `reconnect_failed` {@link CdpConnectionError}.
20
21
  */
21
- export declare function reconnectWithBackoff(connect: (signal: AbortSignal) => Promise<CdpConnection>, events?: ReconnectEvents, options?: ReconnectOptions): Promise<CdpConnection>;
22
+ export declare function reconnectWithBackoff<T extends {
23
+ close(): Promise<void>;
24
+ } = CdpConnection>(connect: (signal: AbortSignal) => Promise<T>, events?: ReconnectEvents<T>, options?: ReconnectOptions): Promise<T>;
22
25
  //# sourceMappingURL=reconnect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/cdp/reconnect.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACpD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAiBD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,EACxD,MAAM,CAAC,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,aAAa,CAAC,CA2BxB"}
1
+ {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/cdp/reconnect.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,aAAa;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAiDD;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,SAAS;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,aAAa,EAC7F,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EAC5C,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,CAAC,CAAC,CAqCZ"}
package/dist/index.d.ts CHANGED
@@ -52,4 +52,5 @@ export * from "./session";
52
52
  export * from "./driver";
53
53
  export * from "./providers";
54
54
  export * from "./testing";
55
+ export { reconnectRemoteBrowser } from "./remote-reconnect";
55
56
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AACvC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAE9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AAIrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AACvC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAE9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AAIrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -355,31 +355,65 @@ function rewriteLoopbackWsHost(wsUrl, requestedUrl) {
355
355
  }
356
356
 
357
357
  // src/cdp/reconnect.ts
358
- var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
359
- async function withTimeout(connect, timeoutMs) {
358
+ function sleep(ms, signal) {
359
+ return new Promise((resolve) => {
360
+ const finish = () => {
361
+ clearTimeout(timer);
362
+ signal?.removeEventListener("abort", finish);
363
+ resolve();
364
+ };
365
+ const timer = setTimeout(finish, ms);
366
+ signal?.addEventListener("abort", finish, { once: true });
367
+ if (signal?.aborted) finish();
368
+ });
369
+ }
370
+ async function withTimeout(connect, timeoutMs, parent) {
360
371
  const controller = new AbortController();
361
- const timer = setTimeout(() => controller.abort(), timeoutMs);
372
+ let rejectTimeout;
373
+ const interrupted = new Promise((_resolve, reject) => {
374
+ rejectTimeout = reject;
375
+ });
376
+ const cancel = () => {
377
+ controller.abort();
378
+ rejectTimeout(new CdpConnectionError("connect_failed", "CDP reconnect cancelled or timed out"));
379
+ };
380
+ const timer = setTimeout(cancel, timeoutMs);
381
+ parent?.addEventListener("abort", cancel, { once: true });
382
+ if (parent?.aborted) cancel();
383
+ const pending = Promise.resolve().then(() => connect(controller.signal)).then(async (connection) => {
384
+ if (controller.signal.aborted) {
385
+ await connection.close();
386
+ throw new CdpConnectionError("connect_failed", "Late CDP connection discarded");
387
+ }
388
+ return connection;
389
+ });
362
390
  try {
363
- return await connect(controller.signal);
391
+ return await Promise.race([pending, interrupted]);
364
392
  } finally {
365
393
  clearTimeout(timer);
394
+ parent?.removeEventListener("abort", cancel);
366
395
  }
367
396
  }
368
397
  async function reconnectWithBackoff(connect, events, options) {
369
398
  const attempts = options?.attempts ?? 3;
370
399
  const delays = options?.delaysMs ?? [1e3, 2e3, 4e3];
371
400
  const attemptTimeoutMs = options?.attemptTimeoutMs ?? 15e3;
401
+ if (!Number.isInteger(attempts) || attempts < 1 || !Number.isFinite(attemptTimeoutMs) || attemptTimeoutMs <= 0)
402
+ throw new Error("Invalid reconnect budget");
372
403
  let lastError;
373
404
  for (let attempt = 1; attempt <= attempts; attempt++) {
405
+ if (options?.signal?.aborted)
406
+ throw new CdpConnectionError("reconnect_failed", "CDP reconnect cancelled");
374
407
  events?.onReconnecting?.(attempt, attempts);
375
408
  try {
376
- const connection = await withTimeout(connect, attemptTimeoutMs);
409
+ const connection = await withTimeout(connect, attemptTimeoutMs, options?.signal);
377
410
  events?.onReconnected?.(connection);
378
411
  return connection;
379
412
  } catch (err) {
380
413
  lastError = err;
414
+ if (options?.signal?.aborted) break;
381
415
  if (attempt < attempts) {
382
- await sleep(delays[attempt - 1] ?? delays[delays.length - 1] ?? 1e3);
416
+ await sleep(delays[attempt - 1] ?? delays[delays.length - 1] ?? 1e3, options?.signal);
383
417
  }
384
418
  }
385
419
  }
@@ -1009,7 +1043,7 @@ function findChromeExecutable(options) {
1009
1043
 
1010
1044
  // src/launch/local-browser.ts
1011
1045
  import { spawn } from "child_process";
1012
- import { mkdtempSync, rmSync } from "fs";
1046
+ import { existsSync, mkdtempSync, rmSync } from "fs";
1013
1047
  import { createServer } from "net";
1014
1048
  import { tmpdir } from "os";
1015
1049
  import { join as join2 } from "path";
@@ -1137,6 +1171,10 @@ function consolidateDisableFeatures(args) {
1137
1171
  if (features.size > 0) out.push(`${prefix}${[...features].join(",")}`);
1138
1172
  return out;
1139
1173
  }
1174
+ function resolveDockerFlag(explicit, env2 = process.env, dockerEnvPath = "/.dockerenv") {
1175
+ if (explicit !== void 0) return explicit;
1176
+ return env2.AP3X_BROWSER_DOCKER === "1" || existsSync(dockerEnvPath);
1177
+ }
1140
1178
  function buildChromeArgs(options) {
1141
1179
  const args = [...CHROME_DEFAULT_ARGS];
1142
1180
  args.push(`--user-data-dir=${options.userDataDir}`);
@@ -1200,7 +1238,7 @@ async function launchLocalBrowser(options = {}) {
1200
1238
  headless: options.headless,
1201
1239
  disableSecurity: options.disableSecurity,
1202
1240
  deterministicRendering: options.deterministicRendering,
1203
- docker: options.docker,
1241
+ docker: resolveDockerFlag(options.docker),
1204
1242
  sandbox: options.sandbox,
1205
1243
  extraArgs: options.extraArgs
1206
1244
  });
@@ -4726,13 +4764,13 @@ var BrowserSession = class _BrowserSession {
4726
4764
  * (`testing.ts`) builds on to assert real DOM effects (PRP T1) rather than
4727
4765
  * a tool's self-report.
4728
4766
  */
4729
- async evaluate(expression) {
4767
+ async evaluate(expression, options = {}) {
4730
4768
  const focus = this.registry.getFocusedSession();
4731
4769
  if (!focus) throw new NavigationError("no_focus", "No focused page target");
4732
4770
  const { result, exceptionDetails } = await this.transport.send(
4733
4771
  "Runtime.evaluate",
4734
4772
  { expression, returnByValue: true, awaitPromise: true },
4735
- { sessionId: focus.sessionId }
4773
+ { sessionId: focus.sessionId, signal: options.signal }
4736
4774
  );
4737
4775
  if (exceptionDetails) {
4738
4776
  throw new Error(
@@ -4955,6 +4993,38 @@ function openBrowserSession(config, seams = {}) {
4955
4993
  return createBrowserProvider(config, seams).connect(config);
4956
4994
  }
4957
4995
 
4996
+ // src/remote-reconnect.ts
4997
+ async function reconnectRemoteBrowser(previous, cdpUrl, options = {}) {
4998
+ await previous.stop();
4999
+ const connected = await reconnectWithBackoff(
5000
+ async (signal) => {
5001
+ let transport;
5002
+ const abort = () => {
5003
+ void transport?.close();
5004
+ };
5005
+ signal.addEventListener("abort", abort, { once: true });
5006
+ try {
5007
+ const session = await BrowserSession.connect(cdpUrl, options.config, {
5008
+ openTransport: async (url) => {
5009
+ transport = await CdpConnection.connect(url, { signal, headers: options.headers });
5010
+ if (signal.aborted) await transport.close();
5011
+ return transport;
5012
+ }
5013
+ });
5014
+ return { session, close: () => session.stop() };
5015
+ } catch (error) {
5016
+ await transport?.close();
5017
+ throw error;
5018
+ } finally {
5019
+ signal.removeEventListener("abort", abort);
5020
+ }
5021
+ },
5022
+ void 0,
5023
+ options
5024
+ );
5025
+ return { session: connected.session, driver: new BrowserDriver(connected.session) };
5026
+ }
5027
+
4958
5028
  // src/index.ts
4959
5029
  var PACKAGE = "@ap3x/browser";
4960
5030
  var VERSION = "0.1.0";
@@ -5050,9 +5120,11 @@ export {
5050
5120
  openWebSocket,
5051
5121
  parentBranchHash,
5052
5122
  parentBranchPath,
5123
+ reconnectRemoteBrowser,
5053
5124
  reconnectWithBackoff,
5054
5125
  resolveBrowserConfig,
5055
5126
  resolveCdpWebSocketUrl,
5127
+ resolveDockerFlag,
5056
5128
  sanitizeDownloadFilename,
5057
5129
  scrollInfo,
5058
5130
  serializeFromSnapshot,
@@ -28,6 +28,14 @@ export interface BuildArgsOptions {
28
28
  * de-duplicated flag (§9.6 test_security_flags GOLDEN). Order preserved.
29
29
  */
30
30
  export declare function consolidateDisableFeatures(args: string[]): string[];
31
+ /**
32
+ * Whether to apply the docker/no-sandbox arg pack. An explicit `docker` option
33
+ * always wins; otherwise it opts in when `AP3X_BROWSER_DOCKER=1` or a
34
+ * `/.dockerenv` marker is present. Chromium cannot start its sandbox as root
35
+ * inside a container, so a server image needs `--no-sandbox` without every
36
+ * caller knowing it's containerized.
37
+ */
38
+ export declare function resolveDockerFlag(explicit: boolean | undefined, env?: NodeJS.ProcessEnv, dockerEnvPath?: string): boolean;
31
39
  /** Build the final Chrome CLI args (deduped disable-features, port injected). */
32
40
  export declare function buildChromeArgs(options: BuildArgsOptions): string[];
33
41
  export interface LaunchOptions extends DiscoveryOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"local-browser.d.ts","sourceRoot":"","sources":["../../src/launch/local-browser.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAO9D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAwB,MAAM,aAAa,CAAC;AAE/F,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EA6BvD,CAAC;AAEF;gFACgF;AAChF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAqDhD,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAQ/C,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAQzD,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAOhE,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAanE;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAUnE;AAED,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,8EAA8E;AAC9E,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAc9C;AAmBD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CA0D9F"}
1
+ {"version":3,"file":"local-browser.d.ts","sourceRoot":"","sources":["../../src/launch/local-browser.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAO9D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAwB,MAAM,aAAa,CAAC;AAE/F,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EA6BvD,CAAC;AAEF;gFACgF;AAChF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAqDhD,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAQ/C,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAQzD,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAOhE,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAanE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,aAAa,SAAgB,GAC5B,OAAO,CAGT;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAUnE;AAED,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,8EAA8E;AAC9E,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAc9C;AAmBD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CA0D9F"}
@@ -0,0 +1,17 @@
1
+ import { type OpenWebSocketOptions } from "./cdp/connection";
2
+ import { type ReconnectOptions } from "./cdp/reconnect";
3
+ import type { BrowserConfigOverrides } from "./config";
4
+ import { BrowserDriver } from "./driver";
5
+ import { BrowserSession } from "./session";
6
+ /** Explicit remote recovery: tear down old sessions, then rediscover targets with a fresh driver.
7
+ * Read getState() and rematch before replay. Old element indices and session IDs are invalid.
8
+ * This never repeats the action whose result was uncertain when the socket disappeared.
9
+ */
10
+ export declare function reconnectRemoteBrowser(previous: BrowserSession, cdpUrl: string, options?: ReconnectOptions & {
11
+ config?: BrowserConfigOverrides;
12
+ headers?: OpenWebSocketOptions["headers"];
13
+ }): Promise<{
14
+ session: BrowserSession;
15
+ driver: BrowserDriver;
16
+ }>;
17
+ //# sourceMappingURL=remote-reconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-reconnect.d.ts","sourceRoot":"","sources":["../src/remote-reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAwB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAgB,GAAG;IAC1B,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;CACtC;;;GA8BP"}
package/dist/session.d.ts CHANGED
@@ -117,7 +117,9 @@ export declare class BrowserSession {
117
117
  * (`testing.ts`) builds on to assert real DOM effects (PRP T1) rather than
118
118
  * a tool's self-report.
119
119
  */
120
- evaluate<T = unknown>(expression: string): Promise<T>;
120
+ evaluate<T = unknown>(expression: string, options?: {
121
+ signal?: AbortSignal;
122
+ }): Promise<T>;
121
123
  /** Open a new tab (browser-level Target.createTarget). Returns its 4-char id. */
122
124
  openTab(url?: string): Promise<TabId>;
123
125
  /** Focus another tab by its 4-char id, bringing it to the foreground. */
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ap3x/browser",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Chrome DevTools Protocol browser control primitives",
5
5
  "repository": {
6
6
  "type": "git",