@browserbasehq/orca 3.1.0-patch.4 → 3.2.0-preview.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.
Files changed (225) hide show
  1. package/dist/cjs/lib/inference.js +1 -4
  2. package/dist/cjs/lib/inference.js.map +1 -1
  3. package/dist/cjs/lib/v3/agent/AgentProvider.js +0 -1
  4. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/tools/act.d.ts +1 -1
  6. package/dist/cjs/lib/v3/agent/tools/act.js +20 -4
  7. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  8. package/dist/cjs/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  9. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +60 -22
  10. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/tools/click.js +23 -31
  12. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js +22 -30
  14. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/tools/extract.d.ts +2 -2
  16. package/dist/cjs/lib/v3/agent/tools/extract.js +16 -3
  17. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  18. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +30 -30
  19. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  20. package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +7 -1
  21. package/dist/cjs/lib/v3/agent/tools/fillform.js +60 -37
  22. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  23. package/dist/cjs/lib/v3/agent/tools/index.d.ts +5 -0
  24. package/dist/cjs/lib/v3/agent/tools/index.js +5 -5
  25. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  26. package/dist/cjs/lib/v3/agent/tools/screenshot.d.ts +8 -0
  27. package/dist/cjs/lib/v3/agent/tools/screenshot.js +32 -15
  28. package/dist/cjs/lib/v3/agent/tools/screenshot.js.map +1 -1
  29. package/dist/cjs/lib/v3/agent/tools/scroll.js +12 -0
  30. package/dist/cjs/lib/v3/agent/tools/scroll.js.map +1 -1
  31. package/dist/cjs/lib/v3/agent/tools/type.js +23 -31
  32. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  33. package/dist/cjs/lib/v3/agent/tools/wait.js +6 -0
  34. package/dist/cjs/lib/v3/agent/tools/wait.js.map +1 -1
  35. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  36. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  37. package/dist/cjs/lib/v3/api.d.ts +2 -2
  38. package/dist/cjs/lib/v3/api.js +1 -1
  39. package/dist/cjs/lib/v3/api.js.map +1 -1
  40. package/dist/cjs/lib/v3/cache/ActCache.d.ts +0 -1
  41. package/dist/cjs/lib/v3/cache/ActCache.js +2 -18
  42. package/dist/cjs/lib/v3/cache/ActCache.js.map +1 -1
  43. package/dist/cjs/lib/v3/handlers/actHandler.js +1 -2
  44. package/dist/cjs/lib/v3/handlers/actHandler.js.map +1 -1
  45. package/dist/cjs/lib/v3/handlers/extractHandler.js +2 -2
  46. package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
  47. package/dist/cjs/lib/v3/handlers/observeHandler.js +1 -2
  48. package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
  49. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +11 -16
  50. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  51. package/dist/cjs/lib/v3/index.d.ts +2 -1
  52. package/dist/cjs/lib/v3/launch/browserbase.d.ts +1 -1
  53. package/dist/cjs/lib/v3/launch/browserbase.js +4 -9
  54. package/dist/cjs/lib/v3/launch/browserbase.js.map +1 -1
  55. package/dist/cjs/lib/v3/llm/LLMProvider.js +0 -5
  56. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  57. package/dist/cjs/lib/v3/runtimePaths.js +2 -1
  58. package/dist/cjs/lib/v3/runtimePaths.js.map +1 -1
  59. package/dist/cjs/lib/v3/shutdown/supervisor.js +2 -2
  60. package/dist/cjs/lib/v3/shutdown/supervisor.js.map +1 -1
  61. package/dist/cjs/lib/v3/timeoutConfig.d.ts +1 -1
  62. package/dist/cjs/lib/v3/timeoutConfig.js +5 -0
  63. package/dist/cjs/lib/v3/timeoutConfig.js.map +1 -1
  64. package/dist/cjs/lib/v3/types/private/shutdown.d.ts +1 -1
  65. package/dist/cjs/lib/v3/types/private/shutdown.js.map +1 -1
  66. package/dist/cjs/lib/v3/types/public/agent.d.ts +12 -1
  67. package/dist/cjs/lib/v3/types/public/agent.js +0 -1
  68. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  69. package/dist/cjs/lib/v3/types/public/api.d.ts +3 -0
  70. package/dist/cjs/lib/v3/types/public/api.js +1 -0
  71. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  72. package/dist/cjs/lib/v3/types/public/model.d.ts +4 -2
  73. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  74. package/dist/cjs/lib/v3/types/public/options.d.ts +1 -0
  75. package/dist/cjs/lib/v3/understudy/cdp.d.ts +5 -1
  76. package/dist/cjs/lib/v3/understudy/cdp.js +54 -7
  77. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  78. package/dist/cjs/lib/v3/understudy/context.d.ts +1 -0
  79. package/dist/cjs/lib/v3/understudy/context.js +142 -60
  80. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  81. package/dist/cjs/lib/v3/understudy/frame.js +23 -6
  82. package/dist/cjs/lib/v3/understudy/frame.js.map +1 -1
  83. package/dist/cjs/lib/v3/understudy/page.d.ts +13 -0
  84. package/dist/cjs/lib/v3/understudy/page.js +56 -3
  85. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  86. package/dist/cjs/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  87. package/dist/cjs/lib/v3/understudy/screenshotUtils.js +0 -18
  88. package/dist/cjs/lib/v3/understudy/screenshotUtils.js.map +1 -1
  89. package/dist/cjs/lib/v3/v3.js +38 -24
  90. package/dist/cjs/lib/v3/v3.js.map +1 -1
  91. package/dist/cjs/tests/integration/cdp-session-detached.spec.js +1 -1
  92. package/dist/cjs/tests/integration/cdp-session-detached.spec.js.map +1 -1
  93. package/dist/cjs/tests/integration/context-addInitScript.spec.js +104 -11
  94. package/dist/cjs/tests/integration/context-addInitScript.spec.js.map +1 -1
  95. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  96. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js +219 -0
  97. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  98. package/dist/cjs/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  99. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js +85 -0
  100. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  101. package/dist/cjs/tests/integration/page-screenshot.spec.js +1 -1
  102. package/dist/cjs/tests/integration/page-screenshot.spec.js.map +1 -1
  103. package/dist/cjs/tests/integration/timeouts.spec.js +168 -0
  104. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  105. package/dist/cjs/tests/unit/model-deprecation.test.js +5 -8
  106. package/dist/cjs/tests/unit/model-deprecation.test.js.map +1 -1
  107. package/dist/cjs/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  108. package/dist/cjs/tests/unit/page-extra-http-headers.test.js +92 -0
  109. package/dist/cjs/tests/unit/page-extra-http-headers.test.js.map +1 -0
  110. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +13 -1
  111. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  112. package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
  113. package/dist/esm/lib/inference.js +1 -4
  114. package/dist/esm/lib/inference.js.map +1 -1
  115. package/dist/esm/lib/v3/agent/AgentProvider.js +0 -1
  116. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  117. package/dist/esm/lib/v3/agent/tools/act.d.ts +1 -1
  118. package/dist/esm/lib/v3/agent/tools/act.js +20 -4
  119. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  120. package/dist/esm/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  121. package/dist/esm/lib/v3/agent/tools/ariaTree.js +60 -22
  122. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  123. package/dist/esm/lib/v3/agent/tools/click.js +23 -31
  124. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  125. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js +22 -30
  126. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  127. package/dist/esm/lib/v3/agent/tools/extract.d.ts +2 -2
  128. package/dist/esm/lib/v3/agent/tools/extract.js +16 -3
  129. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  130. package/dist/esm/lib/v3/agent/tools/fillFormVision.js +30 -30
  131. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  132. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +7 -1
  133. package/dist/esm/lib/v3/agent/tools/fillform.js +60 -37
  134. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  135. package/dist/esm/lib/v3/agent/tools/index.d.ts +5 -0
  136. package/dist/esm/lib/v3/agent/tools/index.js +5 -5
  137. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  138. package/dist/esm/lib/v3/agent/tools/screenshot.d.ts +8 -0
  139. package/dist/esm/lib/v3/agent/tools/screenshot.js +32 -15
  140. package/dist/esm/lib/v3/agent/tools/screenshot.js.map +1 -1
  141. package/dist/esm/lib/v3/agent/tools/scroll.js +12 -0
  142. package/dist/esm/lib/v3/agent/tools/scroll.js.map +1 -1
  143. package/dist/esm/lib/v3/agent/tools/type.js +23 -31
  144. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  145. package/dist/esm/lib/v3/agent/tools/wait.js +6 -0
  146. package/dist/esm/lib/v3/agent/tools/wait.js.map +1 -1
  147. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  148. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  149. package/dist/esm/lib/v3/api.d.ts +2 -2
  150. package/dist/esm/lib/v3/api.js +1 -1
  151. package/dist/esm/lib/v3/api.js.map +1 -1
  152. package/dist/esm/lib/v3/cache/ActCache.d.ts +0 -1
  153. package/dist/esm/lib/v3/cache/ActCache.js +2 -18
  154. package/dist/esm/lib/v3/cache/ActCache.js.map +1 -1
  155. package/dist/esm/lib/v3/handlers/actHandler.js +1 -2
  156. package/dist/esm/lib/v3/handlers/actHandler.js.map +1 -1
  157. package/dist/esm/lib/v3/handlers/extractHandler.js +2 -2
  158. package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
  159. package/dist/esm/lib/v3/handlers/observeHandler.js +1 -2
  160. package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
  161. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +11 -16
  162. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  163. package/dist/esm/lib/v3/index.d.ts +2 -1
  164. package/dist/esm/lib/v3/launch/browserbase.d.ts +1 -1
  165. package/dist/esm/lib/v3/launch/browserbase.js +4 -9
  166. package/dist/esm/lib/v3/launch/browserbase.js.map +1 -1
  167. package/dist/esm/lib/v3/llm/LLMProvider.js +0 -5
  168. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  169. package/dist/esm/lib/v3/runtimePaths.js +2 -1
  170. package/dist/esm/lib/v3/runtimePaths.js.map +1 -1
  171. package/dist/esm/lib/v3/shutdown/supervisor.js +2 -2
  172. package/dist/esm/lib/v3/shutdown/supervisor.js.map +1 -1
  173. package/dist/esm/lib/v3/timeoutConfig.d.ts +1 -1
  174. package/dist/esm/lib/v3/timeoutConfig.js +5 -0
  175. package/dist/esm/lib/v3/timeoutConfig.js.map +1 -1
  176. package/dist/esm/lib/v3/types/private/shutdown.d.ts +1 -1
  177. package/dist/esm/lib/v3/types/private/shutdown.js.map +1 -1
  178. package/dist/esm/lib/v3/types/public/agent.d.ts +12 -1
  179. package/dist/esm/lib/v3/types/public/agent.js +0 -1
  180. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  181. package/dist/esm/lib/v3/types/public/api.d.ts +3 -0
  182. package/dist/esm/lib/v3/types/public/api.js +1 -0
  183. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  184. package/dist/esm/lib/v3/types/public/model.d.ts +4 -2
  185. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  186. package/dist/esm/lib/v3/types/public/options.d.ts +1 -0
  187. package/dist/esm/lib/v3/understudy/cdp.d.ts +5 -1
  188. package/dist/esm/lib/v3/understudy/cdp.js +55 -8
  189. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  190. package/dist/esm/lib/v3/understudy/context.d.ts +1 -0
  191. package/dist/esm/lib/v3/understudy/context.js +142 -60
  192. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  193. package/dist/esm/lib/v3/understudy/frame.js +23 -6
  194. package/dist/esm/lib/v3/understudy/frame.js.map +1 -1
  195. package/dist/esm/lib/v3/understudy/page.d.ts +13 -0
  196. package/dist/esm/lib/v3/understudy/page.js +58 -5
  197. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  198. package/dist/esm/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  199. package/dist/esm/lib/v3/understudy/screenshotUtils.js +0 -17
  200. package/dist/esm/lib/v3/understudy/screenshotUtils.js.map +1 -1
  201. package/dist/esm/lib/v3/v3.js +38 -24
  202. package/dist/esm/lib/v3/v3.js.map +1 -1
  203. package/dist/esm/tests/integration/cdp-session-detached.spec.js +1 -1
  204. package/dist/esm/tests/integration/cdp-session-detached.spec.js.map +1 -1
  205. package/dist/esm/tests/integration/context-addInitScript.spec.js +104 -11
  206. package/dist/esm/tests/integration/context-addInitScript.spec.js.map +1 -1
  207. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  208. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js +217 -0
  209. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  210. package/dist/esm/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  211. package/dist/esm/tests/integration/page-extra-http-headers.spec.js +83 -0
  212. package/dist/esm/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  213. package/dist/esm/tests/integration/page-screenshot.spec.js +1 -1
  214. package/dist/esm/tests/integration/page-screenshot.spec.js.map +1 -1
  215. package/dist/esm/tests/integration/timeouts.spec.js +168 -0
  216. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  217. package/dist/esm/tests/unit/model-deprecation.test.js +5 -8
  218. package/dist/esm/tests/unit/model-deprecation.test.js.map +1 -1
  219. package/dist/esm/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  220. package/dist/esm/tests/unit/page-extra-http-headers.test.js +90 -0
  221. package/dist/esm/tests/unit/page-extra-http-headers.test.js.map +1 -0
  222. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +13 -1
  223. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  224. package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
  225. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../../../../lib/v3/understudy/cdp.ts"],"names":[],"mappings":"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","sourcesContent":["// lib/v3/understudy/cdp.ts\nimport WebSocket from \"ws\";\nimport type { Protocol } from \"devtools-protocol\";\nimport { STAGEHAND_VERSION } from \"../../version.js\";\nimport { CdpConnectionClosedError } from \"../types/public/sdkErrors.js\";\n\n/**\n * CDP transport & session multiplexer\n *\n * Owns the browser WebSocket and multiplexes flattened Target sessions.\n * Tracks inflight CDP calls, routes responses to the right session, and forwards events.\n *\n * This does not interpret Page/DOM/Runtime semantics — callers own that logic.\n */\nexport interface CDPSessionLike {\n send<R = unknown>(method: string, params?: object): Promise<R>;\n on<P = unknown>(event: string, handler: (params: P) => void): void;\n off<P = unknown>(event: string, handler: (params: P) => void): void;\n close(): Promise<void>;\n readonly id: string | null;\n}\n\ntype Inflight = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n sessionId?: string | null;\n method: string;\n params?: object;\n stack?: string;\n ts: number;\n};\n\ntype EventHandler = (params: unknown) => void;\n\ntype RawMessage =\n | {\n id: number;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n sessionId?: string;\n }\n | { method: string; params?: unknown; sessionId?: string };\n\nexport class CdpConnection implements CDPSessionLike {\n private ws: WebSocket;\n private nextId = 1;\n private inflight = new Map<number, Inflight>();\n private eventHandlers = new Map<string, Set<EventHandler>>();\n private sessions = new Map<string, CdpSession>();\n /** Maps sessionId -> targetId (1:1 mapping) */\n private sessionToTarget = new Map<string, string>();\n public readonly id: string | null = null; // root\n private transportCloseHandlers = new Set<(why: string) => void>();\n\n /** Optional CDP logger - set this to receive all outgoing CDP method calls */\n public cdpLogger?: (info: {\n method: string;\n params?: object;\n targetId?: string | null;\n }) => void;\n\n /** Optional CDP event logger - set this to receive all incoming CDP events */\n public cdpEventLogger?: (info: {\n method: string;\n params?: unknown;\n targetId?: string | null;\n }) => void;\n\n public onTransportClosed(handler: (why: string) => void): void {\n this.transportCloseHandlers.add(handler);\n }\n public offTransportClosed(handler: (why: string) => void): void {\n this.transportCloseHandlers.delete(handler);\n }\n\n private emitTransportClosed(why: string) {\n for (const h of this.transportCloseHandlers) {\n try {\n h(why);\n } catch {\n //\n }\n }\n }\n\n private constructor(ws: WebSocket) {\n this.ws = ws;\n this.ws.on(\"close\", (code, reason) => {\n // Reason is a Buffer in ws; stringify defensively\n const why = `socket-close code=${code} reason=${String(reason || \"\")}`;\n this.rejectAllInflight(why);\n this.emitTransportClosed(why);\n });\n\n this.ws.on(\"error\", (err) => {\n const why = `socket-error ${err?.message ?? String(err)}`;\n this.rejectAllInflight(why);\n this.emitTransportClosed(why);\n });\n this.ws.on(\"message\", (data) => this.onMessage(data.toString()));\n }\n\n static async connect(wsUrl: string): Promise<CdpConnection> {\n // Include User-Agent header for server-side observability and version tracking\n const ws = new WebSocket(wsUrl, {\n headers: {\n \"User-Agent\": `Stagehand/${STAGEHAND_VERSION}`,\n },\n });\n await new Promise<void>((resolve, reject) => {\n ws.once(\"open\", () => resolve());\n ws.once(\"error\", (e) => reject(e));\n });\n return new CdpConnection(ws);\n }\n\n async enableAutoAttach(): Promise<void> {\n await this.send(\"Target.setAutoAttach\", {\n autoAttach: true,\n flatten: true,\n waitForDebuggerOnStart: true,\n });\n await this.send(\"Target.setDiscoverTargets\", { discover: true });\n }\n\n async send<R = unknown>(method: string, params?: object): Promise<R> {\n const id = this.nextId++;\n const payload = { id, method, params };\n const stack = new Error().stack?.split(\"\\n\").slice(1, 4).join(\"\\n\");\n const p = new Promise<R>((resolve, reject) => {\n this.inflight.set(id, {\n resolve,\n reject,\n sessionId: null,\n method,\n params,\n stack,\n ts: Date.now(),\n });\n });\n // Prevent unhandledRejection if a session detaches before the caller awaits.\n void p.catch(() => {});\n this.cdpLogger?.({ method, params, targetId: null });\n this.ws.send(JSON.stringify(payload));\n return p;\n }\n\n on<P = unknown>(event: string, handler: (params: P) => void): void {\n const set = this.eventHandlers.get(event) ?? new Set<EventHandler>();\n set.add(handler as EventHandler);\n this.eventHandlers.set(event, set);\n }\n\n off<P = unknown>(event: string, handler: (params: P) => void): void {\n const set = this.eventHandlers.get(event);\n if (set) set.delete(handler as EventHandler);\n }\n\n async close(): Promise<void> {\n if (this.ws.readyState === WebSocket.CLOSED) return;\n await new Promise<void>((resolve) => {\n this.ws.once(\"close\", () => resolve());\n this.ws.close();\n });\n }\n\n private rejectAllInflight(why: string): void {\n for (const [id, entry] of this.inflight.entries()) {\n entry.reject(new CdpConnectionClosedError(why));\n this.inflight.delete(id);\n }\n }\n\n getSession(sessionId: string): CdpSession | undefined {\n return this.sessions.get(sessionId);\n }\n\n async attachToTarget(targetId: string): Promise<CdpSession> {\n const { sessionId } = (await this.send<{ sessionId: string }>(\n \"Target.attachToTarget\",\n { targetId, flatten: true },\n )) as { sessionId: string };\n\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = new CdpSession(this, sessionId);\n this.sessions.set(sessionId, session);\n }\n this.sessionToTarget.set(sessionId, targetId);\n return session;\n }\n\n async getTargets(): Promise<Protocol.Target.TargetInfo[]> {\n const res = await this.send<{\n targetInfos: Protocol.Target.TargetInfo[];\n }>(\"Target.getTargets\");\n return res.targetInfos;\n }\n\n private onMessage(json: string): void {\n const msg = JSON.parse(json) as RawMessage;\n\n if (\"id\" in msg) {\n const rec = this.inflight.get(msg.id);\n if (!rec) return;\n\n this.inflight.delete(msg.id);\n\n if (\"error\" in msg && msg.error) {\n rec.reject(new Error(`${msg.error.code} ${msg.error.message}`));\n } else {\n rec.resolve((msg as { result?: unknown }).result);\n }\n return;\n }\n\n if (\"method\" in msg) {\n if (msg.method === \"Target.attachedToTarget\") {\n const p = (msg as { params: Protocol.Target.AttachedToTargetEvent })\n .params;\n if (!this.sessions.has(p.sessionId)) {\n this.sessions.set(p.sessionId, new CdpSession(this, p.sessionId));\n }\n this.sessionToTarget.set(p.sessionId, p.targetInfo.targetId);\n } else if (msg.method === \"Target.detachedFromTarget\") {\n const p = (msg as { params: Protocol.Target.DetachedFromTargetEvent })\n .params;\n for (const [id, entry] of this.inflight.entries()) {\n if (entry.sessionId === p.sessionId) {\n entry.reject(new Error(\"CDP session detached\"));\n this.inflight.delete(id);\n }\n }\n this.sessions.delete(p.sessionId);\n this.sessionToTarget.delete(p.sessionId);\n } else if (msg.method === \"Target.targetDestroyed\") {\n const p = (msg as { params: { targetId: string } }).params;\n // Remove any session mapping for this target\n for (const [sessionId, targetId] of this.sessionToTarget.entries()) {\n if (targetId === p.targetId) {\n this.sessionToTarget.delete(sessionId);\n break;\n }\n }\n }\n\n const { method, params, sessionId } = msg;\n\n // Log incoming CDP events\n const targetId = this.sessionToTarget.get(sessionId) || sessionId;\n this.cdpEventLogger?.({ method, params, targetId });\n\n if (sessionId) {\n const session = this.sessions.get(sessionId);\n session?.dispatch(method, params);\n } else {\n const handlers = this.eventHandlers.get(method);\n if (handlers) for (const h of handlers) h(params);\n }\n }\n }\n\n _sendViaSession<R = unknown>(\n sessionId: string,\n method: string,\n params?: object,\n ): Promise<R> {\n const id = this.nextId++;\n const payload = { id, method, params, sessionId };\n const stack = new Error().stack?.split(\"\\n\").slice(1, 4).join(\"\\n\");\n\n const p = new Promise<R>((resolve, reject) => {\n this.inflight.set(id, {\n resolve,\n reject,\n sessionId,\n method,\n params,\n stack,\n ts: Date.now(),\n });\n });\n // Prevent unhandledRejection if a session detaches before the caller awaits.\n void p.catch(() => {});\n const targetId = this.sessionToTarget.get(sessionId) ?? null;\n this.cdpLogger?.({ method, params, targetId });\n this.ws.send(JSON.stringify(payload));\n return p;\n }\n\n _onSessionEvent(\n sessionId: string,\n event: string,\n handler: EventHandler,\n ): void {\n const key = `${sessionId}:${event}`;\n const set = this.eventHandlers.get(key) ?? new Set<EventHandler>();\n set.add(handler);\n this.eventHandlers.set(key, set);\n }\n\n _offSessionEvent(\n sessionId: string,\n event: string,\n handler: EventHandler,\n ): void {\n const key = `${sessionId}:${event}`;\n const set = this.eventHandlers.get(key);\n if (set) set.delete(handler);\n }\n\n _dispatchToSession(sessionId: string, event: string, params: unknown): void {\n const key = `${sessionId}:${event}`;\n const handlers = this.eventHandlers.get(key);\n if (handlers) for (const h of handlers) h(params);\n }\n}\n\nexport class CdpSession implements CDPSessionLike {\n constructor(\n private readonly root: CdpConnection,\n public readonly id: string,\n ) {}\n\n send<R = unknown>(method: string, params?: object): Promise<R> {\n return this.root._sendViaSession<R>(this.id, method, params);\n }\n\n on<P = unknown>(event: string, handler: (params: P) => void): void {\n this.root._onSessionEvent(this.id, event, handler as EventHandler);\n }\n\n off<P = unknown>(event: string, handler: (params: P) => void): void {\n this.root._offSessionEvent(this.id, event, handler as EventHandler);\n }\n\n async close(): Promise<void> {\n await this.root.send<void>(\"Target.detachFromTarget\", {\n sessionId: this.id,\n });\n }\n\n dispatch(event: string, params: unknown): void {\n this.root._dispatchToSession(this.id, event, params);\n }\n}\n"]}
1
+ {"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../../../../lib/v3/understudy/cdp.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AA8CtC,MAAM,OAAO,aAAa;IAChB,EAAE,CAAY;IACd,MAAM,GAAG,CAAC,CAAC;IACX,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IACvC,aAAa,GAAG,IAAI,GAAG,EAA6B,CAAC;IACrD,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IACjD,+CAA+C;IACvC,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,sBAAsB,GAAG,IAAI,GAAG,EAAyB,CAAC;IAClD,EAAE,GAAkB,IAAI,CAAC,CAAC,OAAO;IACzC,sBAAsB,GAAG,IAAI,GAAG,EAAyB,CAAC;IAElE,8EAA8E;IACvE,SAAS,CAIL;IAEX,8EAA8E;IACvE,cAAc,CAIV;IAEJ,iBAAiB,CAAC,OAA8B;QACrD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IACM,kBAAkB,CAAC,OAA8B;QACtD,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAEO,mBAAmB,CAAC,GAAW;QACrC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC5C,IAAI,CAAC;gBACH,CAAC,CAAC,GAAG,CAAC,CAAC;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,EAAE;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAoB,EAAa;QAC/B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YACnC,kDAAkD;YAClD,MAAM,GAAG,GAAG,qBAAqB,IAAI,WAAW,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1B,MAAM,GAAG,GAAG,gBAAgB,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAClB,KAAa,EACb,OAA8C;QAE9C,+EAA+E;QAC/E,8DAA8D;QAC9D,MAAM,OAAO,GAAG;YACd,YAAY,EAAE,aAAa,iBAAiB,EAAE;YAC9C,GAAG,OAAO,EAAE,OAAO;SACpB,CAAC;QACF,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACjC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;YACtC,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,IAAI;YACb,sBAAsB,EAAE,IAAI;SAC7B,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,IAAI,CAAc,MAAc,EAAE,MAAe;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE;gBACpB,OAAO;gBACP,MAAM;gBACN,SAAS,EAAE,IAAI;gBACf,MAAM;gBACN,MAAM;gBACN,KAAK;gBACL,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;aACf,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,6EAA6E;QAC7E,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,EAAE,CAAc,KAAa,EAAE,OAA4B;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,EAAgB,CAAC;QACrE,GAAG,CAAC,GAAG,CAAC,OAAuB,CAAC,CAAC;QACjC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAc,KAAa,EAAE,OAA4B;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,GAAG;YAAE,GAAG,CAAC,MAAM,CAAC,OAAuB,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO;QACpD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB,CAAC,GAAW;QACnC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,KAAK,CAAC,MAAM,CAAC,IAAI,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,sBAAsB,CACpB,SAAiB,EACjB,MAAc,EACd,KAAoC;QAEpC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,MAAM,GAA0B;gBACpC,SAAS;gBACT,MAAM;gBACN,KAAK;gBACL,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC3C,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM,EAAE,CAAC,KAAY,EAAE,EAAE;oBACvB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC3C,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;aACF,CAAC;YACF,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CACpC,uBAAuB,EACvB,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAC5B,CAA0B,CAAC;QAE5B,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAExB,mBAAmB,CAAC,CAAC;QACxB,OAAO,GAAG,CAAC,WAAW,CAAC;IACzB,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;QAE3C,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG;gBAAE,OAAO;YAEjB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAE7B,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAChC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,OAAO,CAAE,GAA4B,CAAC,MAAM,CAAC,CAAC;YACpD,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;YACpB,IAAI,GAAG,CAAC,MAAM,KAAK,yBAAyB,EAAE,CAAC;gBAC7C,MAAM,CAAC,GAAI,GAAyD;qBACjE,MAAM,CAAC;gBACV,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACpE,CAAC;gBACD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC/D,CAAC;iBAAM,IAAI,GAAG,CAAC,MAAM,KAAK,2BAA2B,EAAE,CAAC;gBACtD,MAAM,CAAC,GAAI,GAA2D;qBACnE,MAAM,CAAC;gBACV,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;oBAClD,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;wBACpC,KAAK,CAAC,MAAM,CACV,IAAI,iBAAiB,CACnB,gDAAgD,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,QAAQ,GAAG,CACvF,CACF,CAAC;wBACF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC;oBAC7D,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;wBACrC,MAAM,CAAC,MAAM,CACX,IAAI,iBAAiB,CACnB,4CAA4C,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,QAAQ,GAAG,CACnF,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBAClC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;iBAAM,IAAI,GAAG,CAAC,MAAM,KAAK,wBAAwB,EAAE,CAAC;gBACnD,MAAM,CAAC,GAAI,GAAwC,CAAC,MAAM,CAAC;gBAC3D,6CAA6C;gBAC7C,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC;oBACnE,IAAI,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;wBAC5B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;wBACvC,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;YAE1C,0BAA0B;YAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;YAClE,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpD,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC7C,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAElC,6DAA6D;gBAC7D,qEAAqE;gBACrE,wDAAwD;gBACxD,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAChD,IAAI,QAAQ;wBAAE,KAAK,MAAM,CAAC,IAAI,QAAQ;4BAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAChD,IAAI,QAAQ;oBAAE,KAAK,MAAM,CAAC,IAAI,QAAQ;wBAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe,CACb,SAAiB,EACjB,MAAc,EACd,MAAe;QAEf,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEpE,MAAM,CAAC,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE;gBACpB,OAAO;gBACP,MAAM;gBACN,SAAS;gBACT,MAAM;gBACN,MAAM;gBACN,KAAK;gBACL,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;aACf,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,6EAA6E;QAC7E,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;QAC7D,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;gBAAE,SAAS;YAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAS;YACvC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,SAAS;YACpD,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM;QACR,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,eAAe,CACb,SAAiB,EACjB,KAAa,EACb,OAAqB;QAErB,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAgB,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB,CACd,SAAiB,EACjB,KAAa,EACb,OAAqB;QAErB,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,GAAG;YAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,kBAAkB,CAAC,SAAiB,EAAE,KAAa,EAAE,MAAe;QAClE,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,QAAQ;YAAE,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;CACF;AAED,MAAM,OAAO,UAAU;IAEF;IACD;IAFlB,YACmB,IAAmB,EACpB,EAAU;QADT,SAAI,GAAJ,IAAI,CAAe;QACpB,OAAE,GAAF,EAAE,CAAQ;IACzB,CAAC;IAEJ,IAAI,CAAc,MAAc,EAAE,MAAe;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED,EAAE,CAAc,KAAa,EAAE,OAA4B;QACzD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,OAAuB,CAAC,CAAC;IACrE,CAAC;IAED,GAAG,CAAc,KAAa,EAAE,OAA4B;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,OAAuB,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAO,yBAAyB,EAAE;YACpD,SAAS,EAAE,IAAI,CAAC,EAAE;SACnB,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,KAAa,EAAE,MAAe;QACrC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;CACF","sourcesContent":["// lib/v3/understudy/cdp.ts\nimport WebSocket from \"ws\";\nimport type { Protocol } from \"devtools-protocol\";\nimport { STAGEHAND_VERSION } from \"../../version.js\";\nimport {\n CdpConnectionClosedError,\n PageNotFoundError,\n} from \"../types/public/sdkErrors.js\";\n\n/**\n * CDP transport & session multiplexer\n *\n * Owns the browser WebSocket and multiplexes flattened Target sessions.\n * Tracks inflight CDP calls, routes responses to the right session, and forwards events.\n *\n * This does not interpret Page/DOM/Runtime semantics — callers own that logic.\n */\nexport interface CDPSessionLike {\n send<R = unknown>(method: string, params?: object): Promise<R>;\n on<P = unknown>(event: string, handler: (params: P) => void): void;\n off<P = unknown>(event: string, handler: (params: P) => void): void;\n close(): Promise<void>;\n readonly id: string | null;\n}\n\ntype Inflight = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n sessionId?: string | null;\n method: string;\n params?: object;\n stack?: string;\n ts: number;\n};\n\ntype EventHandler = (params: unknown) => void;\ntype SessionDispatchWaiter = {\n sessionId: string;\n method: string;\n match?: (params?: object) => boolean;\n resolve: () => void;\n reject: (error: Error) => void;\n};\n\ntype RawMessage =\n | {\n id: number;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n sessionId?: string;\n }\n | { method: string; params?: unknown; sessionId?: string };\n\nexport class CdpConnection implements CDPSessionLike {\n private ws: WebSocket;\n private nextId = 1;\n private inflight = new Map<number, Inflight>();\n private eventHandlers = new Map<string, Set<EventHandler>>();\n private sessions = new Map<string, CdpSession>();\n /** Maps sessionId -> targetId (1:1 mapping) */\n private sessionToTarget = new Map<string, string>();\n private sessionDispatchWaiters = new Set<SessionDispatchWaiter>();\n public readonly id: string | null = null; // root\n private transportCloseHandlers = new Set<(why: string) => void>();\n\n /** Optional CDP logger - set this to receive all outgoing CDP method calls */\n public cdpLogger?: (info: {\n method: string;\n params?: object;\n targetId?: string | null;\n }) => void;\n\n /** Optional CDP event logger - set this to receive all incoming CDP events */\n public cdpEventLogger?: (info: {\n method: string;\n params?: unknown;\n targetId?: string | null;\n }) => void;\n\n public onTransportClosed(handler: (why: string) => void): void {\n this.transportCloseHandlers.add(handler);\n }\n public offTransportClosed(handler: (why: string) => void): void {\n this.transportCloseHandlers.delete(handler);\n }\n\n private emitTransportClosed(why: string) {\n for (const h of this.transportCloseHandlers) {\n try {\n h(why);\n } catch {\n //\n }\n }\n }\n\n private constructor(ws: WebSocket) {\n this.ws = ws;\n this.ws.on(\"close\", (code, reason) => {\n // Reason is a Buffer in ws; stringify defensively\n const why = `socket-close code=${code} reason=${String(reason || \"\")}`;\n this.rejectAllInflight(why);\n this.emitTransportClosed(why);\n });\n\n this.ws.on(\"error\", (err) => {\n const why = `socket-error ${err?.message ?? String(err)}`;\n this.rejectAllInflight(why);\n this.emitTransportClosed(why);\n });\n this.ws.on(\"message\", (data) => this.onMessage(data.toString()));\n }\n\n static async connect(\n wsUrl: string,\n options?: { headers?: Record<string, string> },\n ): Promise<CdpConnection> {\n // Include User-Agent header for server-side observability and version tracking\n // Merge user-provided headers, letting them override defaults\n const headers = {\n \"User-Agent\": `Stagehand/${STAGEHAND_VERSION}`,\n ...options?.headers,\n };\n const ws = new WebSocket(wsUrl, { headers });\n await new Promise<void>((resolve, reject) => {\n ws.once(\"open\", () => resolve());\n ws.once(\"error\", (e) => reject(e));\n });\n return new CdpConnection(ws);\n }\n\n async enableAutoAttach(): Promise<void> {\n await this.send(\"Target.setAutoAttach\", {\n autoAttach: true,\n flatten: true,\n waitForDebuggerOnStart: true,\n });\n await this.send(\"Target.setDiscoverTargets\", { discover: true });\n }\n\n async send<R = unknown>(method: string, params?: object): Promise<R> {\n const id = this.nextId++;\n const payload = { id, method, params };\n const stack = new Error().stack?.split(\"\\n\").slice(1, 4).join(\"\\n\");\n const p = new Promise<R>((resolve, reject) => {\n this.inflight.set(id, {\n resolve,\n reject,\n sessionId: null,\n method,\n params,\n stack,\n ts: Date.now(),\n });\n });\n // Prevent unhandledRejection if a session detaches before the caller awaits.\n void p.catch(() => {});\n this.cdpLogger?.({ method, params, targetId: null });\n this.ws.send(JSON.stringify(payload));\n return p;\n }\n\n on<P = unknown>(event: string, handler: (params: P) => void): void {\n const set = this.eventHandlers.get(event) ?? new Set<EventHandler>();\n set.add(handler as EventHandler);\n this.eventHandlers.set(event, set);\n }\n\n off<P = unknown>(event: string, handler: (params: P) => void): void {\n const set = this.eventHandlers.get(event);\n if (set) set.delete(handler as EventHandler);\n }\n\n async close(): Promise<void> {\n if (this.ws.readyState === WebSocket.CLOSED) return;\n await new Promise<void>((resolve) => {\n this.ws.once(\"close\", () => resolve());\n this.ws.close();\n });\n }\n\n private rejectAllInflight(why: string): void {\n for (const [id, entry] of this.inflight.entries()) {\n entry.reject(new CdpConnectionClosedError(why));\n this.inflight.delete(id);\n }\n for (const waiter of Array.from(this.sessionDispatchWaiters)) {\n waiter.reject(new CdpConnectionClosedError(why));\n }\n }\n\n getSession(sessionId: string): CdpSession | undefined {\n return this.sessions.get(sessionId);\n }\n\n waitForSessionDispatch(\n sessionId: string,\n method: string,\n match?: (params?: object) => boolean,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const waiter: SessionDispatchWaiter = {\n sessionId,\n method,\n match,\n resolve: () => {\n this.sessionDispatchWaiters.delete(waiter);\n resolve();\n },\n reject: (error: Error) => {\n this.sessionDispatchWaiters.delete(waiter);\n reject(error);\n },\n };\n this.sessionDispatchWaiters.add(waiter);\n });\n }\n\n async attachToTarget(targetId: string): Promise<CdpSession> {\n const { sessionId } = (await this.send<{ sessionId: string }>(\n \"Target.attachToTarget\",\n { targetId, flatten: true },\n )) as { sessionId: string };\n\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = new CdpSession(this, sessionId);\n this.sessions.set(sessionId, session);\n }\n this.sessionToTarget.set(sessionId, targetId);\n return session;\n }\n\n async getTargets(): Promise<Protocol.Target.TargetInfo[]> {\n const res = await this.send<{\n targetInfos: Protocol.Target.TargetInfo[];\n }>(\"Target.getTargets\");\n return res.targetInfos;\n }\n\n private onMessage(json: string): void {\n const msg = JSON.parse(json) as RawMessage;\n\n if (\"id\" in msg) {\n const rec = this.inflight.get(msg.id);\n if (!rec) return;\n\n this.inflight.delete(msg.id);\n\n if (\"error\" in msg && msg.error) {\n rec.reject(new Error(`${msg.error.code} ${msg.error.message}`));\n } else {\n rec.resolve((msg as { result?: unknown }).result);\n }\n return;\n }\n\n if (\"method\" in msg) {\n if (msg.method === \"Target.attachedToTarget\") {\n const p = (msg as { params: Protocol.Target.AttachedToTargetEvent })\n .params;\n if (!this.sessions.has(p.sessionId)) {\n this.sessions.set(p.sessionId, new CdpSession(this, p.sessionId));\n }\n this.sessionToTarget.set(p.sessionId, p.targetInfo.targetId);\n } else if (msg.method === \"Target.detachedFromTarget\") {\n const p = (msg as { params: Protocol.Target.DetachedFromTargetEvent })\n .params;\n for (const [id, entry] of this.inflight.entries()) {\n if (entry.sessionId === p.sessionId) {\n entry.reject(\n new PageNotFoundError(\n `target closed before CDP response (sessionId=${p.sessionId}, targetId=${p.targetId})`,\n ),\n );\n this.inflight.delete(id);\n }\n }\n for (const waiter of Array.from(this.sessionDispatchWaiters)) {\n if (waiter.sessionId === p.sessionId) {\n waiter.reject(\n new PageNotFoundError(\n `target closed before CDP send (sessionId=${p.sessionId}, targetId=${p.targetId})`,\n ),\n );\n }\n }\n this.sessions.delete(p.sessionId);\n this.sessionToTarget.delete(p.sessionId);\n } else if (msg.method === \"Target.targetDestroyed\") {\n const p = (msg as { params: { targetId: string } }).params;\n // Remove any session mapping for this target\n for (const [sessionId, targetId] of this.sessionToTarget.entries()) {\n if (targetId === p.targetId) {\n this.sessionToTarget.delete(sessionId);\n break;\n }\n }\n }\n\n const { method, params, sessionId } = msg;\n\n // Log incoming CDP events\n const targetId = this.sessionToTarget.get(sessionId) || sessionId;\n this.cdpEventLogger?.({ method, params, targetId });\n\n if (sessionId) {\n const session = this.sessions.get(sessionId);\n session?.dispatch(method, params);\n\n // Forward target lifecycle events to root listeners as well.\n // Some browsers emit these via a parent session rather than the root\n // connection; fan-out keeps target tracking consistent.\n if (method.startsWith(\"Target.\")) {\n const handlers = this.eventHandlers.get(method);\n if (handlers) for (const h of handlers) h(params);\n }\n } else {\n const handlers = this.eventHandlers.get(method);\n if (handlers) for (const h of handlers) h(params);\n }\n }\n }\n\n _sendViaSession<R = unknown>(\n sessionId: string,\n method: string,\n params?: object,\n ): Promise<R> {\n const id = this.nextId++;\n const payload = { id, method, params, sessionId };\n const stack = new Error().stack?.split(\"\\n\").slice(1, 4).join(\"\\n\");\n\n const p = new Promise<R>((resolve, reject) => {\n this.inflight.set(id, {\n resolve,\n reject,\n sessionId,\n method,\n params,\n stack,\n ts: Date.now(),\n });\n });\n // Prevent unhandledRejection if a session detaches before the caller awaits.\n void p.catch(() => {});\n const targetId = this.sessionToTarget.get(sessionId) ?? null;\n this.cdpLogger?.({ method, params, targetId });\n for (const waiter of Array.from(this.sessionDispatchWaiters)) {\n if (waiter.sessionId !== sessionId) continue;\n if (waiter.method !== method) continue;\n if (waiter.match && !waiter.match(params)) continue;\n waiter.resolve();\n break;\n }\n this.ws.send(JSON.stringify(payload));\n return p;\n }\n\n _onSessionEvent(\n sessionId: string,\n event: string,\n handler: EventHandler,\n ): void {\n const key = `${sessionId}:${event}`;\n const set = this.eventHandlers.get(key) ?? new Set<EventHandler>();\n set.add(handler);\n this.eventHandlers.set(key, set);\n }\n\n _offSessionEvent(\n sessionId: string,\n event: string,\n handler: EventHandler,\n ): void {\n const key = `${sessionId}:${event}`;\n const set = this.eventHandlers.get(key);\n if (set) set.delete(handler);\n }\n\n _dispatchToSession(sessionId: string, event: string, params: unknown): void {\n const key = `${sessionId}:${event}`;\n const handlers = this.eventHandlers.get(key);\n if (handlers) for (const h of handlers) h(params);\n }\n}\n\nexport class CdpSession implements CDPSessionLike {\n constructor(\n private readonly root: CdpConnection,\n public readonly id: string,\n ) {}\n\n send<R = unknown>(method: string, params?: object): Promise<R> {\n return this.root._sendViaSession<R>(this.id, method, params);\n }\n\n on<P = unknown>(event: string, handler: (params: P) => void): void {\n this.root._onSessionEvent(this.id, event, handler as EventHandler);\n }\n\n off<P = unknown>(event: string, handler: (params: P) => void): void {\n this.root._offSessionEvent(this.id, event, handler as EventHandler);\n }\n\n async close(): Promise<void> {\n await this.root.send<void>(\"Target.detachFromTarget\", {\n sessionId: this.id,\n });\n }\n\n dispatch(event: string, params: unknown): void {\n this.root._dispatchToSession(this.id, event, params);\n }\n}\n"]}
@@ -45,6 +45,7 @@ export declare class V3Context {
45
45
  env?: "LOCAL" | "BROWSERBASE";
46
46
  apiClient?: StagehandAPIClient | null;
47
47
  localBrowserLaunchOptions?: LocalBrowserLaunchOptions | null;
48
+ cdpHeaders?: Record<string, string>;
48
49
  }): Promise<V3Context>;
49
50
  private hasTopLevelPage;
50
51
  private ensureFirstTopLevelPage;
@@ -108,7 +108,9 @@ export class V3Context {
108
108
  */
109
109
  static async create(wsUrl, opts) {
110
110
  const connectTask = async () => {
111
- const conn = await CdpConnection.connect(wsUrl);
111
+ const conn = await CdpConnection.connect(wsUrl, {
112
+ headers: opts?.cdpHeaders,
113
+ });
112
114
  const ctx = new V3Context(conn, opts?.env ?? "LOCAL", opts?.apiClient ?? null, opts?.localBrowserLaunchOptions ?? null);
113
115
  await ctx.bootstrap();
114
116
  await ctx.ensureFirstTopLevelPage(getFirstTopLevelPageTimeoutMs());
@@ -488,77 +490,148 @@ export class V3Context {
488
490
  // any "must happen before first document" work.
489
491
  await session.send("Runtime.runIfWaitingForDebugger").catch(() => { });
490
492
  };
491
- // Install any context-level init scripts as early as possible on this session.
492
- // If this throws, we still resume the target but avoid re-installing later.
493
- let scriptsInstalled = true;
494
- let piercerPreRegistered = false;
495
- const installPromises = [];
496
- try {
497
- const send = (method, params) => session.send(method, params).catch(() => { });
498
- // make sure init scripts land before any subframe work.
499
- installPromises.push(send("Page.enable"));
500
- installPromises.push(send("Runtime.enable"));
501
- installPromises.push(session
502
- .send("Target.setAutoAttach", {
493
+ // Attach lifecycle (per target session):
494
+ // 1) while paused, enable domains + child auto-attach and register init scripts;
495
+ // 2) resume target execution;
496
+ // 3) build/adopt Page ownership and frame bridges.
497
+ // Some CDP backends defer *.enable() responses until after resume, so we
498
+ // cannot await those responses before resuming. Instead we:
499
+ // - wait for transport-level dispatch of required pre-resume commands;
500
+ // - then dispatch resume;
501
+ // - then await responses.
502
+ const queuePreResume = (method, params, match) => {
503
+ const dispatched = this.conn
504
+ .waitForSessionDispatch(sessionId, method, match)
505
+ .then(() => true)
506
+ .catch(() => false);
507
+ const response = session
508
+ .send(method, params)
509
+ .then(() => true)
510
+ .catch(() => false);
511
+ return { dispatched, response };
512
+ };
513
+ const initScriptOps = [];
514
+ // Pre-resume ordering matters:
515
+ // - enable domains;
516
+ // - enable child auto-attach with waitForDebuggerOnStart;
517
+ // - register init scripts.
518
+ // Commands are sent in-order on the same session before resume.
519
+ const corePreResumeOps = [
520
+ queuePreResume("Page.enable"),
521
+ queuePreResume("Runtime.enable"),
522
+ queuePreResume("Target.setAutoAttach", {
503
523
  autoAttach: true,
504
524
  waitForDebuggerOnStart: true,
505
525
  flatten: true,
506
- })
507
- .catch(() => { }));
508
- if (this.extraHttpHeaders) {
509
- const headers = { ...this.extraHttpHeaders };
510
- installPromises.push(send("Network.enable"));
511
- installPromises.push(send("Network.setExtraHTTPHeaders", { headers }));
512
- }
513
- // Send init scripts only after auto-attach has been issued.
514
- if (this.initScripts.length) {
515
- for (const source of this.initScripts) {
516
- installPromises.push(session.send("Page.addScriptToEvaluateOnNewDocument", {
517
- source,
518
- runImmediately: true,
519
- }));
520
- }
526
+ }),
527
+ ];
528
+ const headerPreResumeOps = [];
529
+ if (this.extraHttpHeaders) {
530
+ const headers = { ...this.extraHttpHeaders };
531
+ headerPreResumeOps.push(queuePreResume("Network.enable"));
532
+ headerPreResumeOps.push(queuePreResume("Network.setExtraHTTPHeaders", { headers }));
533
+ }
534
+ // Send init scripts only after auto-attach has been queued.
535
+ if (this.initScripts.length) {
536
+ for (const source of this.initScripts) {
537
+ initScriptOps.push(queuePreResume("Page.addScriptToEvaluateOnNewDocument", {
538
+ source,
539
+ runImmediately: true,
540
+ }, (sentParams) => sentParams?.source ===
541
+ source));
521
542
  }
522
- // register piercer (shadow-DOM hook) before resume so it runs
523
- // before page scripts
524
- installPromises.push(session
525
- .send("Page.addScriptToEvaluateOnNewDocument", {
526
- source: v3ScriptContent,
527
- runImmediately: true,
528
- })
529
- .then(() => {
530
- piercerPreRegistered = true;
531
- })
532
- .catch(() => { }));
533
- installPromises.push(resume());
534
543
  }
535
- catch {
536
- scriptsInstalled = false;
537
- }
538
- if (installPromises.length) {
539
- const results = await Promise.allSettled(installPromises);
540
- if (results.some((r) => r.status === "rejected")) {
541
- scriptsInstalled = false;
544
+ const piercerPreloadOp = queuePreResume("Page.addScriptToEvaluateOnNewDocument", {
545
+ source: v3ScriptContent,
546
+ runImmediately: true,
547
+ }, (sentParams) => sentParams?.source ===
548
+ v3ScriptContent);
549
+ const preResumeDispatched = (await Promise.all([
550
+ ...corePreResumeOps.map((op) => op.dispatched),
551
+ ...headerPreResumeOps.map((op) => op.dispatched),
552
+ ...initScriptOps.map((op) => op.dispatched),
553
+ piercerPreloadOp.dispatched,
554
+ ])).every(Boolean);
555
+ // Dispatch resume only after pre-resume setup has actually been sent.
556
+ const resumeOp = queuePreResume("Runtime.runIfWaitingForDebugger");
557
+ const [resumedDispatched, resumedOk] = await Promise.all([
558
+ resumeOp.dispatched,
559
+ resumeOp.response,
560
+ ]);
561
+ const [coreResults, headerResults, initScriptResults, piercerPreRegistered,] = await Promise.all([
562
+ Promise.all(corePreResumeOps.map((op) => op.response)),
563
+ Promise.all(headerPreResumeOps.map((op) => op.response)),
564
+ Promise.all(initScriptOps.map((op) => op.response)),
565
+ piercerPreloadOp.response,
566
+ ]);
567
+ // Header propagation is independent of init-script determinism but still
568
+ // part of pre-resume attach setup; awaited above for ordering/lifecycle.
569
+ void headerResults;
570
+ if (!preResumeDispatched || !resumedDispatched || !resumedOk) {
571
+ // Short-lived child targets can detach before resume is acknowledged.
572
+ // Keep this noisy only for top-level pages where missing attach is fatal.
573
+ if (isTopLevelPage(info)) {
574
+ v3Logger({
575
+ category: "ctx",
576
+ message: "Failed target pre-resume setup ordering",
577
+ level: 2,
578
+ auxiliary: {
579
+ targetId: { value: String(info.targetId), type: "string" },
580
+ targetType: { value: String(info.type), type: "string" },
581
+ preResumeDispatched: {
582
+ value: String(preResumeDispatched),
583
+ type: "string",
584
+ },
585
+ resumedDispatched: {
586
+ value: String(resumedDispatched),
587
+ type: "string",
588
+ },
589
+ resumedOk: { value: String(resumedOk), type: "string" },
590
+ },
591
+ });
542
592
  }
593
+ return;
543
594
  }
544
- // Only mark the piercer as installed when the pre-registration actually
545
- // succeeded. This lets ensurePiercer() short-circuit (avoiding sequential
546
- // CDP round-trips that delay Page.create / installFrameEventBridges and
547
- // cause same-process iframe frame-events to be missed) while still falling
548
- // back to the full install path when registration failed.
549
- if (piercerPreRegistered) {
550
- this._piercerInstalled.add(sessionId);
551
- }
595
+ resumed = true;
596
+ const scriptsInstalled = coreResults.every(Boolean) && initScriptResults.every(Boolean);
552
597
  try {
553
- const piercerReady = await this.ensurePiercer(session);
554
- if (!piercerReady)
555
- return;
556
- await session
598
+ // Best-effort lifecycle events; do not block top-level page registration
599
+ // on this optional signal stream.
600
+ void session
557
601
  .send("Page.setLifecycleEventsEnabled", { enabled: true })
558
602
  .catch(() => { });
559
603
  // Top-level handling
560
604
  if (isTopLevelPage(info)) {
561
- const page = await Page.create(this.conn, session, info.targetId, this.apiClient, this.localBrowserLaunchOptions, this.env === "BROWSERBASE");
605
+ let page = null;
606
+ let createError;
607
+ // Deterministic contract: never drop a newly attached top-level target
608
+ // because an arbitrary local timeout fired. We wait for Page.create and
609
+ // let it finish regardless of CDP call latency.
610
+ try {
611
+ page = await Page.create(this.conn, session, info.targetId, this.apiClient, this.localBrowserLaunchOptions, this.env === "BROWSERBASE");
612
+ }
613
+ catch (error) {
614
+ createError = error;
615
+ }
616
+ if (!page) {
617
+ v3Logger({
618
+ category: "ctx",
619
+ message: "Failed to create top-level Page",
620
+ level: 2,
621
+ auxiliary: {
622
+ targetId: { value: String(info.targetId), type: "string" },
623
+ targetType: { value: String(info.type), type: "string" },
624
+ targetUrl: { value: String(info.url ?? ""), type: "string" },
625
+ error: {
626
+ value: String(createError instanceof Error
627
+ ? createError.message
628
+ : createError),
629
+ type: "string",
630
+ },
631
+ },
632
+ });
633
+ return;
634
+ }
562
635
  this.wireSessionToOwnerPage(sessionId, page);
563
636
  this.pagesByTarget.set(info.targetId, page);
564
637
  this.mainFrameToTarget.set(page.mainFrameId(), info.targetId);
@@ -573,13 +646,22 @@ export class V3Context {
573
646
  page.seedCurrentUrl(pendingSeedUrl ?? info.url ?? "");
574
647
  this._pushActive(info.targetId);
575
648
  this.installFrameEventBridges(sessionId, page);
649
+ if (piercerPreRegistered) {
650
+ this._piercerInstalled.add(sessionId);
651
+ }
576
652
  // If we already installed scripts at the session level, only seed the
577
653
  // Page's registry to avoid double-installing DOMContentLoaded handlers.
578
654
  await this.applyInitScriptsToPage(page, {
579
655
  seedOnly: scriptsInstalled,
580
656
  });
657
+ if (!piercerPreRegistered) {
658
+ void this.ensurePiercer(session).catch(() => { });
659
+ }
581
660
  return;
582
661
  }
662
+ const piercerReady = await this.ensurePiercer(session).catch(() => false);
663
+ if (!piercerReady)
664
+ return;
583
665
  // Child (iframe / OOPIF)
584
666
  try {
585
667
  const { frameTree } = await session.send("Page.getFrameTree");