@browserbasehq/orca 3.2.1-preview.3 → 3.4.0-preview.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.
- package/dist/cjs/lib/inference.js +1 -8
- package/dist/cjs/lib/inference.js.map +1 -1
- package/dist/cjs/lib/prompt.js +3 -1
- package/dist/cjs/lib/prompt.js.map +1 -1
- package/dist/cjs/lib/v3/agent/AgentProvider.js +3 -0
- package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +16 -12
- package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
- package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
- package/dist/cjs/lib/v3/api.d.ts +1 -0
- package/dist/cjs/lib/v3/api.js +15 -3
- package/dist/cjs/lib/v3/api.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js +12 -12
- package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js +48 -48
- package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js +2 -2
- package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.js +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/extractHandler.js +3 -1
- package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +3 -5
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/index.d.ts +1 -1
- package/dist/cjs/lib/v3/llm/CerebrasClient.js +1 -1
- package/dist/cjs/lib/v3/llm/CerebrasClient.js.map +1 -1
- package/dist/cjs/lib/v3/llm/GroqClient.js +1 -1
- package/dist/cjs/lib/v3/llm/GroqClient.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/agent.d.ts +5 -0
- package/dist/cjs/lib/v3/types/private/agent.js +11 -0
- package/dist/cjs/lib/v3/types/private/agent.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/handlers.d.ts +1 -0
- package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/snapshot.d.ts +8 -0
- package/dist/cjs/lib/v3/types/private/snapshot.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/agent.d.ts +2 -3
- package/dist/cjs/lib/v3/types/public/agent.js +3 -0
- package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/api.d.ts +5 -1
- package/dist/cjs/lib/v3/types/public/api.js +15 -2
- package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/methods.d.ts +1 -0
- package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js +268 -21
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/frameRegistry.js +16 -5
- package/dist/cjs/lib/v3/understudy/frameRegistry.js.map +1 -1
- package/dist/cjs/lib/v3/v3.d.ts +1 -0
- package/dist/cjs/lib/v3/v3.js +15 -14
- package/dist/cjs/lib/v3/v3.js.map +1 -1
- package/dist/cjs/lib/version.d.ts +1 -1
- package/dist/cjs/lib/version.js +1 -1
- package/dist/cjs/lib/version.js.map +1 -1
- package/dist/cjs/tests/integration/observe-element-id-format.spec.js +130 -0
- package/dist/cjs/tests/integration/observe-element-id-format.spec.js.map +1 -0
- package/dist/cjs/tests/unit/agent-mode-routing.test.js +88 -0
- package/dist/cjs/tests/unit/agent-mode-routing.test.js.map +1 -0
- package/dist/cjs/tests/unit/agent-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-temperature.test.js +191 -0
- package/dist/cjs/tests/unit/agent-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.js +43 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.js.map +1 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js +47 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -1
- package/dist/cjs/tests/unit/api-optional-model-api-key.test.js +60 -0
- package/dist/cjs/tests/unit/api-optional-model-api-key.test.js.map +1 -1
- package/dist/cjs/tests/unit/api-variables-schema.test.js +25 -0
- package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -1
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js +60 -0
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
- package/dist/cjs/tests/unit/inference-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/inference-temperature.test.js +65 -0
- package/dist/cjs/tests/unit/inference-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.js +84 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js +6 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -1
- package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +3 -0
- package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
- package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
- package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
- package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js +119 -9
- package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
- package/dist/esm/lib/inference.js +1 -8
- package/dist/esm/lib/inference.js.map +1 -1
- package/dist/esm/lib/prompt.js +3 -1
- package/dist/esm/lib/prompt.js.map +1 -1
- package/dist/esm/lib/v3/agent/AgentProvider.js +3 -0
- package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/fillFormVision.js +16 -12
- package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
- package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
- package/dist/esm/lib/v3/api.d.ts +1 -0
- package/dist/esm/lib/v3/api.js +15 -3
- package/dist/esm/lib/v3/api.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js +12 -12
- package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js +48 -48
- package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js +2 -2
- package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.js +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.js.map +1 -1
- package/dist/esm/lib/v3/handlers/extractHandler.js +3 -1
- package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js +3 -5
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/index.d.ts +1 -1
- package/dist/esm/lib/v3/llm/CerebrasClient.js +1 -1
- package/dist/esm/lib/v3/llm/CerebrasClient.js.map +1 -1
- package/dist/esm/lib/v3/llm/GroqClient.js +1 -1
- package/dist/esm/lib/v3/llm/GroqClient.js.map +1 -1
- package/dist/esm/lib/v3/types/private/agent.d.ts +5 -0
- package/dist/esm/lib/v3/types/private/agent.js +10 -1
- package/dist/esm/lib/v3/types/private/agent.js.map +1 -1
- package/dist/esm/lib/v3/types/private/handlers.d.ts +1 -0
- package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/esm/lib/v3/types/private/snapshot.d.ts +8 -0
- package/dist/esm/lib/v3/types/private/snapshot.js.map +1 -1
- package/dist/esm/lib/v3/types/public/agent.d.ts +2 -3
- package/dist/esm/lib/v3/types/public/agent.js +3 -0
- package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
- package/dist/esm/lib/v3/types/public/api.d.ts +5 -1
- package/dist/esm/lib/v3/types/public/api.js +15 -2
- package/dist/esm/lib/v3/types/public/api.js.map +1 -1
- package/dist/esm/lib/v3/types/public/methods.d.ts +1 -0
- package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
- package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js +267 -22
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
- package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
- package/dist/esm/lib/v3/understudy/frameRegistry.js +16 -5
- package/dist/esm/lib/v3/understudy/frameRegistry.js.map +1 -1
- package/dist/esm/lib/v3/v3.d.ts +1 -0
- package/dist/esm/lib/v3/v3.js +15 -14
- package/dist/esm/lib/v3/v3.js.map +1 -1
- package/dist/esm/lib/version.d.ts +1 -1
- package/dist/esm/lib/version.js +1 -1
- package/dist/esm/lib/version.js.map +1 -1
- package/dist/esm/tests/integration/observe-element-id-format.spec.d.ts +1 -0
- package/dist/esm/tests/integration/observe-element-id-format.spec.js +128 -0
- package/dist/esm/tests/integration/observe-element-id-format.spec.js.map +1 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.js +86 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.js.map +1 -0
- package/dist/esm/tests/unit/agent-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-temperature.test.js +189 -0
- package/dist/esm/tests/unit/agent-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.js +41 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.js.map +1 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js +47 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -1
- package/dist/esm/tests/unit/api-optional-model-api-key.test.js +60 -0
- package/dist/esm/tests/unit/api-optional-model-api-key.test.js.map +1 -1
- package/dist/esm/tests/unit/api-variables-schema.test.js +25 -0
- package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -1
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js +58 -0
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
- package/dist/esm/tests/unit/inference-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/inference-temperature.test.js +63 -0
- package/dist/esm/tests/unit/inference-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.js +82 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js +6 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -1
- package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +3 -0
- package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
- package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
- package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
- package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js +119 -9
- package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +0 -56
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +0 -54
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
- /package/dist/cjs/tests/integration/{agent-captcha-autosolve.spec.d.ts → observe-element-id-format.spec.d.ts} +0 -0
- /package/dist/{esm/tests/integration/agent-captcha-autosolve.spec.d.ts → cjs/tests/unit/agent-mode-routing.test.d.ts} +0 -0
|
@@ -169,7 +169,7 @@ async function domMapsForSession(session, frameId, pierce, encode, attemptOwnerL
|
|
|
169
169
|
const { node, xpath } = stack.pop();
|
|
170
170
|
if (node.backendNodeId) {
|
|
171
171
|
const encId = encode(frameId, node.backendNodeId);
|
|
172
|
-
tagNameMap[encId] =
|
|
172
|
+
tagNameMap[encId] = enrichedTagName(node);
|
|
173
173
|
xpathMap[encId] = xpath || "/";
|
|
174
174
|
const isScrollable = node?.isScrollable === true;
|
|
175
175
|
if (isScrollable)
|
|
@@ -209,33 +209,61 @@ async function buildSessionDomIndex(session, pierce) {
|
|
|
209
209
|
const scrollByBe = new Map();
|
|
210
210
|
const docRootOf = new Map();
|
|
211
211
|
const contentDocRootByIframe = new Map();
|
|
212
|
+
const enterByBe = new Map();
|
|
213
|
+
const exitByBe = new Map();
|
|
212
214
|
const rootBe = root.backendNodeId;
|
|
213
|
-
const stack = [
|
|
215
|
+
const stack = [
|
|
216
|
+
{ node: root, xp: "/", docRootBe: rootBe, phase: "enter" },
|
|
217
|
+
];
|
|
218
|
+
let dfsIndex = 0;
|
|
214
219
|
while (stack.length) {
|
|
215
|
-
const { node, xp, docRootBe } = stack.pop();
|
|
220
|
+
const { node, xp, docRootBe, phase } = stack.pop();
|
|
221
|
+
if (phase === "exit") {
|
|
222
|
+
if (node.backendNodeId) {
|
|
223
|
+
exitByBe.set(node.backendNodeId, dfsIndex++);
|
|
224
|
+
}
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
216
227
|
if (node.backendNodeId) {
|
|
228
|
+
enterByBe.set(node.backendNodeId, dfsIndex++);
|
|
217
229
|
absByBe.set(node.backendNodeId, xp || "/");
|
|
218
|
-
tagByBe.set(node.backendNodeId,
|
|
230
|
+
tagByBe.set(node.backendNodeId, enrichedTagName(node));
|
|
219
231
|
if (node?.isScrollable === true)
|
|
220
232
|
scrollByBe.set(node.backendNodeId, true);
|
|
221
233
|
docRootOf.set(node.backendNodeId, docRootBe);
|
|
222
234
|
}
|
|
235
|
+
stack.push({ node, xp, docRootBe, phase: "exit" });
|
|
223
236
|
const kids = node.children ?? [];
|
|
224
237
|
if (kids.length) {
|
|
225
238
|
const segs = (0, xpathUtils_js_1.buildChildXPathSegments)(kids);
|
|
226
239
|
for (let i = kids.length - 1; i >= 0; i--) {
|
|
227
240
|
const child = kids[i];
|
|
228
241
|
const step = segs[i];
|
|
229
|
-
stack.push({
|
|
242
|
+
stack.push({
|
|
243
|
+
node: child,
|
|
244
|
+
xp: (0, xpathUtils_js_1.joinXPath)(xp, step),
|
|
245
|
+
docRootBe,
|
|
246
|
+
phase: "enter",
|
|
247
|
+
});
|
|
230
248
|
}
|
|
231
249
|
}
|
|
232
250
|
for (const sr of node.shadowRoots ?? []) {
|
|
233
|
-
stack.push({
|
|
251
|
+
stack.push({
|
|
252
|
+
node: sr,
|
|
253
|
+
xp: (0, xpathUtils_js_1.joinXPath)(xp, "//"),
|
|
254
|
+
docRootBe,
|
|
255
|
+
phase: "enter",
|
|
256
|
+
});
|
|
234
257
|
}
|
|
235
258
|
const cd = node.contentDocument;
|
|
236
259
|
if (cd && typeof cd.backendNodeId === "number") {
|
|
237
260
|
contentDocRootByIframe.set(node.backendNodeId, cd.backendNodeId);
|
|
238
|
-
stack.push({
|
|
261
|
+
stack.push({
|
|
262
|
+
node: cd,
|
|
263
|
+
xp,
|
|
264
|
+
docRootBe: cd.backendNodeId,
|
|
265
|
+
phase: "enter",
|
|
266
|
+
});
|
|
239
267
|
}
|
|
240
268
|
}
|
|
241
269
|
return {
|
|
@@ -245,6 +273,8 @@ async function buildSessionDomIndex(session, pierce) {
|
|
|
245
273
|
scrollByBe,
|
|
246
274
|
docRootOf,
|
|
247
275
|
contentDocRootByIframe,
|
|
276
|
+
enterByBe,
|
|
277
|
+
exitByBe,
|
|
248
278
|
};
|
|
249
279
|
}
|
|
250
280
|
/**
|
|
@@ -266,6 +296,29 @@ function relativizeXPath(baseAbs, nodeAbs) {
|
|
|
266
296
|
return abs;
|
|
267
297
|
return abs;
|
|
268
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Extract an attribute value from a CDP DOM node's flat attributes array.
|
|
301
|
+
* Attributes are stored as [name1, value1, name2, value2, ...].
|
|
302
|
+
*/
|
|
303
|
+
function getAttr(attrs, name) {
|
|
304
|
+
if (!attrs)
|
|
305
|
+
return undefined;
|
|
306
|
+
for (let i = 0; i < attrs.length; i += 2) {
|
|
307
|
+
if (attrs[i] === name)
|
|
308
|
+
return attrs[i + 1];
|
|
309
|
+
}
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
/** Build an enriched tag name that includes the type attribute for inputs. */
|
|
313
|
+
function enrichedTagName(node) {
|
|
314
|
+
const tag = String(node.nodeName).toLowerCase();
|
|
315
|
+
if (tag === "input") {
|
|
316
|
+
const type = getAttr(node.attributes, "type");
|
|
317
|
+
if (type)
|
|
318
|
+
return `input, ${type}`;
|
|
319
|
+
}
|
|
320
|
+
return tag;
|
|
321
|
+
}
|
|
269
322
|
/** Find a node by backendNodeId inside a DOM.getDocument tree. */
|
|
270
323
|
function findNodeByBackendId(root, backendNodeId) {
|
|
271
324
|
const stack = [root];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domTree.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/domTree.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { StagehandDomProcessError } from \"../../../types/public/sdkErrors.js\";\nimport type { SessionDomIndex } from \"../../../types/private/snapshot.js\";\nimport {\n buildChildXPathSegments,\n joinXPath,\n normalizeXPath,\n} from \"./xpathUtils.js\";\n\n// starting from infinite depth (-1), exponentially shrink down to 1\nconst DOM_DEPTH_ATTEMPTS = [-1, 256, 128, 64, 32, 16, 8, 4, 2, 1];\nconst DESCRIBE_DEPTH_ATTEMPTS = [-1, 64, 32, 16, 8, 4, 2, 1];\n\n/** Identify CDP failures caused by deep DOM trees blowing the CBOR encoder stack. */\nfunction isCborStackError(message: string): boolean {\n return message.includes(\"CBOR: stack limit exceeded\");\n}\n\n/**\n * Determine if CDP truncated a node's children when streaming the DOM tree.\n * childNodeCount stays accurate even when `children` are omitted; we use this to\n * decide whether DOM.describeNode must be re-run for that node.\n */\nexport function shouldExpandNode(node: Protocol.DOM.Node): boolean {\n const declaredChildren = node.childNodeCount ?? 0;\n const realizedChildren = node.children?.length ?? 0;\n return declaredChildren > realizedChildren;\n}\n\n/** Merge an expanded DescribeNode payload back into the original shallow node. */\nexport function mergeDomNodes(\n target: Protocol.DOM.Node,\n source: Protocol.DOM.Node,\n): void {\n target.childNodeCount = source.childNodeCount ?? target.childNodeCount;\n target.children = source.children ?? target.children;\n target.shadowRoots = source.shadowRoots ?? target.shadowRoots;\n target.contentDocument = source.contentDocument ?? target.contentDocument;\n}\n\n/** Helper that returns every nested collection we recurse through uniformly. */\nexport function collectDomTraversalTargets(\n node: Protocol.DOM.Node,\n): Protocol.DOM.Node[] {\n const targets: Protocol.DOM.Node[] = [];\n if (node.children) targets.push(...node.children);\n if (node.shadowRoots) targets.push(...node.shadowRoots);\n if (node.contentDocument) targets.push(node.contentDocument);\n return targets;\n}\n\n/**\n * Rehydrate a truncated DOM tree by repeatedly calling DOM.describeNode with\n * decreasing depths. Any non-CBOR failure is surfaced as a StagehandDomProcessError.\n */\nexport async function hydrateDomTree(\n session: CDPSessionLike,\n root: Protocol.DOM.Node,\n pierce: boolean,\n): Promise<void> {\n const stack: Protocol.DOM.Node[] = [root];\n const expandedNodeIds = new Set<number>();\n const expandedBackendIds = new Set<number>();\n\n while (stack.length) {\n const node = stack.pop()!;\n const nodeId =\n typeof node.nodeId === \"number\" && node.nodeId > 0\n ? node.nodeId\n : undefined;\n const backendId =\n typeof node.backendNodeId === \"number\" && node.backendNodeId > 0\n ? node.backendNodeId\n : undefined;\n\n const seenByNode = nodeId ? expandedNodeIds.has(nodeId) : false;\n const seenByBackend =\n !nodeId && backendId ? expandedBackendIds.has(backendId) : false;\n if (seenByNode || seenByBackend) continue;\n if (nodeId) expandedNodeIds.add(nodeId);\n else if (backendId) expandedBackendIds.add(backendId);\n\n const needsExpansion = shouldExpandNode(node);\n if (needsExpansion && (nodeId || backendId)) {\n const describeParamsBase = nodeId\n ? { nodeId }\n : { backendNodeId: backendId! };\n let expanded = false;\n for (const depth of DESCRIBE_DEPTH_ATTEMPTS) {\n try {\n const described =\n await session.send<Protocol.DOM.DescribeNodeResponse>(\n \"DOM.describeNode\",\n {\n ...describeParamsBase,\n depth,\n pierce,\n },\n );\n mergeDomNodes(node, described.node);\n if (!nodeId && described.node.nodeId && described.node.nodeId > 0) {\n node.nodeId = described.node.nodeId;\n expandedNodeIds.add(described.node.nodeId);\n }\n expanded = true;\n break;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (isCborStackError(message)) {\n continue;\n }\n const identifier = nodeId ?? backendId ?? \"unknown\";\n throw new StagehandDomProcessError(\n `Failed to expand DOM node ${identifier}: ${String(err)}`,\n );\n }\n }\n if (!expanded) {\n const identifier = nodeId ?? backendId ?? \"unknown\";\n throw new StagehandDomProcessError(\n `Unable to expand DOM node ${identifier} after describeNode depth retries`,\n );\n }\n }\n\n for (const child of collectDomTraversalTargets(node)) {\n stack.push(child);\n }\n }\n}\n\n/**\n * Attempt DOM.getDocument with progressively shallower depths until CBOR stops\n * complaining. When a shallower snapshot is returned we hydrate the missing\n * branches so downstream DOM traversals see the full tree shape.\n */\nexport async function getDomTreeWithFallback(\n session: CDPSessionLike,\n pierce: boolean,\n): Promise<Protocol.DOM.Node> {\n let lastCborMessage = \"\";\n\n for (const depth of DOM_DEPTH_ATTEMPTS) {\n try {\n const { root } = await session.send<{ root: Protocol.DOM.Node }>(\n \"DOM.getDocument\",\n { depth, pierce },\n );\n\n if (depth !== -1) {\n await hydrateDomTree(session, root, pierce);\n }\n\n return root;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (isCborStackError(message)) {\n lastCborMessage = message;\n continue;\n }\n throw err;\n }\n }\n\n throw new StagehandDomProcessError(\n lastCborMessage\n ? `CDP DOM.getDocument failed after adaptive depth retries: ${lastCborMessage}`\n : \"CDP DOM.getDocument failed after adaptive depth retries.\",\n );\n}\n\n/**\n * Build tag name and XPath maps for a single frame session.\n * EncodedId is produced by a frame-aware encoder provided by the caller.\n */\nexport async function domMapsForSession(\n session: CDPSessionLike,\n frameId: string,\n pierce: boolean,\n encode: (fid: string, backendNodeId: number) => string,\n attemptOwnerLookup = true,\n): Promise<{\n tagNameMap: Record<string, string>;\n xpathMap: Record<string, string>;\n scrollableMap: Record<string, boolean>;\n}> {\n await session.send(\"DOM.enable\").catch(() => {});\n const root = await getDomTreeWithFallback(session, pierce);\n\n let startNode: Protocol.DOM.Node = root;\n if (attemptOwnerLookup) {\n try {\n const owner = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n const ownerBackendId = owner.backendNodeId;\n if (typeof ownerBackendId === \"number\") {\n const ownerEl = findNodeByBackendId(root, ownerBackendId);\n if (ownerEl?.contentDocument) {\n startNode = ownerEl.contentDocument;\n }\n }\n } catch {\n // OOPIF or race → keep startNode = root\n }\n }\n\n const tagNameMap: Record<string, string> = {};\n const xpathMap: Record<string, string> = {};\n const scrollableMap: Record<string, boolean> = {};\n\n type StackEntry = { node: Protocol.DOM.Node; xpath: string };\n const stack: StackEntry[] = [{ node: startNode, xpath: \"\" }];\n\n while (stack.length) {\n const { node, xpath } = stack.pop()!;\n\n if (node.backendNodeId) {\n const encId = encode(frameId, node.backendNodeId);\n tagNameMap[encId] = String(node.nodeName).toLowerCase();\n xpathMap[encId] = xpath || \"/\";\n const isScrollable = node?.isScrollable === true;\n if (isScrollable) scrollableMap[encId] = true;\n }\n\n const kids = node.children ?? [];\n if (kids.length) {\n const segs = buildChildXPathSegments(kids);\n for (let i = kids.length - 1; i >= 0; i--) {\n const child = kids[i]!;\n const step = segs[i]!;\n stack.push({\n node: child,\n xpath: joinXPath(xpath, step),\n });\n }\n }\n\n for (const sr of node.shadowRoots ?? []) {\n stack.push({\n node: sr,\n xpath: joinXPath(xpath, \"//\"),\n });\n }\n }\n\n return { tagNameMap, xpathMap, scrollableMap };\n}\n\n/**\n * Build an index of absolute XPath/tag metadata for an entire CDP session.\n * Once the index is cached, per-frame slices are derived without extra DOM\n * calls, which keeps snapshot capture linear in the number of frames.\n */\nexport async function buildSessionDomIndex(\n session: CDPSessionLike,\n pierce: boolean,\n): Promise<SessionDomIndex> {\n await session.send(\"DOM.enable\").catch(() => {});\n const root = await getDomTreeWithFallback(session, pierce);\n\n const absByBe = new Map<number, string>();\n const tagByBe = new Map<number, string>();\n const scrollByBe = new Map<number, boolean>();\n const docRootOf = new Map<number, number>();\n const contentDocRootByIframe = new Map<number, number>();\n\n type Entry = { node: Protocol.DOM.Node; xp: string; docRootBe: number };\n const rootBe = root.backendNodeId!;\n const stack: Entry[] = [{ node: root, xp: \"/\", docRootBe: rootBe }];\n\n while (stack.length) {\n const { node, xp, docRootBe } = stack.pop()!;\n if (node.backendNodeId) {\n absByBe.set(node.backendNodeId, xp || \"/\");\n tagByBe.set(node.backendNodeId, String(node.nodeName).toLowerCase());\n if (node?.isScrollable === true) scrollByBe.set(node.backendNodeId, true);\n docRootOf.set(node.backendNodeId, docRootBe);\n }\n\n const kids = node.children ?? [];\n if (kids.length) {\n const segs = buildChildXPathSegments(kids);\n for (let i = kids.length - 1; i >= 0; i--) {\n const child = kids[i]!;\n const step = segs[i]!;\n stack.push({ node: child, xp: joinXPath(xp, step), docRootBe });\n }\n }\n\n for (const sr of node.shadowRoots ?? []) {\n stack.push({ node: sr, xp: joinXPath(xp, \"//\"), docRootBe });\n }\n\n const cd = node.contentDocument as Protocol.DOM.Node | undefined;\n if (cd && typeof cd.backendNodeId === \"number\") {\n contentDocRootByIframe.set(node.backendNodeId!, cd.backendNodeId);\n stack.push({ node: cd, xp, docRootBe: cd.backendNodeId });\n }\n }\n\n return {\n rootBackend: rootBe,\n absByBe,\n tagByBe,\n scrollByBe,\n docRootOf,\n contentDocRootByIframe,\n };\n}\n\n/**\n * Relativize an absolute XPath against a document root's absolute path.\n * When the node lives outside the document we return the absolute path as-is.\n */\nexport function relativizeXPath(baseAbs: string, nodeAbs: string): string {\n const base = normalizeXPath(baseAbs);\n const abs = normalizeXPath(nodeAbs);\n if (abs === base) return \"/\";\n if (abs.startsWith(base)) {\n const tail = abs.slice(base.length);\n if (!tail) return \"/\";\n return tail.startsWith(\"/\") || tail.startsWith(\"//\") ? tail : `/${tail}`;\n }\n if (base === \"/\") return abs;\n return abs;\n}\n\n/** Find a node by backendNodeId inside a DOM.getDocument tree. */\nexport function findNodeByBackendId(\n root: Protocol.DOM.Node,\n backendNodeId: number,\n): Protocol.DOM.Node | undefined {\n const stack: Protocol.DOM.Node[] = [root];\n while (stack.length) {\n const n = stack.pop()!;\n if (n.backendNodeId === backendNodeId) return n;\n if (n.children) for (const c of n.children) stack.push(c);\n if (n.shadowRoots) for (const s of n.shadowRoots) stack.push(s);\n }\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"domTree.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/domTree.ts"],"names":[],"mappings":";;AAwBA,4CAIC;AAGD,sCAQC;AAGD,gEAQC;AAMD,wCA0EC;AAOD,wDAiCC;AAMD,8CAyEC;AAOD,oDA4FC;AAMD,0CAWC;AA4BD,kDAYC;AAnZD,qEAA8E;AAE9E,mDAIyB;AAEzB,oEAAoE;AACpE,MAAM,kBAAkB,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAClE,MAAM,uBAAuB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAE7D,qFAAqF;AACrF,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,IAAuB;IACtD,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;IAClD,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;IACpD,OAAO,gBAAgB,GAAG,gBAAgB,CAAC;AAC7C,CAAC;AAED,kFAAkF;AAClF,SAAgB,aAAa,CAC3B,MAAyB,EACzB,MAAyB;IAEzB,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC;IACvE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;IACrD,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;IAC9D,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC;AAC5E,CAAC;AAED,gFAAgF;AAChF,SAAgB,0BAA0B,CACxC,IAAuB;IAEvB,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,eAAe;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,cAAc,CAClC,OAAuB,EACvB,IAAuB,EACvB,MAAe;IAEf,MAAM,KAAK,GAAwB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE7C,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAC1B,MAAM,MAAM,GACV,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAChD,CAAC,CAAC,IAAI,CAAC,MAAM;YACb,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,SAAS,GACb,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC;YAC9D,CAAC,CAAC,IAAI,CAAC,aAAa;YACpB,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAChE,MAAM,aAAa,GACjB,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACnE,IAAI,UAAU,IAAI,aAAa;YAAE,SAAS;QAC1C,IAAI,MAAM;YAAE,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;aACnC,IAAI,SAAS;YAAE,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEtD,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,cAAc,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,CAAC;YAC5C,MAAM,kBAAkB,GAAG,MAAM;gBAC/B,CAAC,CAAC,EAAE,MAAM,EAAE;gBACZ,CAAC,CAAC,EAAE,aAAa,EAAE,SAAU,EAAE,CAAC;YAClC,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,KAAK,MAAM,KAAK,IAAI,uBAAuB,EAAE,CAAC;gBAC5C,IAAI,CAAC;oBACH,MAAM,SAAS,GACb,MAAM,OAAO,CAAC,IAAI,CAChB,kBAAkB,EAClB;wBACE,GAAG,kBAAkB;wBACrB,KAAK;wBACL,MAAM;qBACP,CACF,CAAC;oBACJ,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;oBACpC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAClE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;wBACpC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC7C,CAAC;oBACD,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM;gBACR,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjE,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC9B,SAAS;oBACX,CAAC;oBACD,MAAM,UAAU,GAAG,MAAM,IAAI,SAAS,IAAI,SAAS,CAAC;oBACpD,MAAM,IAAI,uCAAwB,CAChC,6BAA6B,UAAU,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAC1D,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,UAAU,GAAG,MAAM,IAAI,SAAS,IAAI,SAAS,CAAC;gBACpD,MAAM,IAAI,uCAAwB,CAChC,6BAA6B,UAAU,mCAAmC,CAC3E,CAAC;YACJ,CAAC;QACH,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,sBAAsB,CAC1C,OAAuB,EACvB,MAAe;IAEf,IAAI,eAAe,GAAG,EAAE,CAAC;IAEzB,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CACjC,iBAAiB,EACjB,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;YAEF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC9C,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,eAAe,GAAG,OAAO,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,IAAI,uCAAwB,CAChC,eAAe;QACb,CAAC,CAAC,4DAA4D,eAAe,EAAE;QAC/E,CAAC,CAAC,0DAA0D,CAC/D,CAAC;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,OAAe,EACf,MAAe,EACf,MAAsD,EACtD,kBAAkB,GAAG,IAAI;IAMzB,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE3D,IAAI,SAAS,GAAsB,IAAI,CAAC;IACxC,IAAI,kBAAkB,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAC9B,mBAAmB,EACnB,EAAE,OAAO,EAAE,CACZ,CAAC;YACF,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC;YAC3C,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;gBACvC,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBAC1D,IAAI,OAAO,EAAE,eAAe,EAAE,CAAC;oBAC7B,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,aAAa,GAA4B,EAAE,CAAC;IAGlD,MAAM,KAAK,GAAiB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAE7D,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAErC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAClD,UAAU,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;YAC1C,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC;YAC/B,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;YACjD,IAAI,YAAY;gBAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAChD,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,IAAA,uCAAuB,EAAC,IAAI,CAAC,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,KAAK;oBACX,KAAK,EAAE,IAAA,yBAAS,EAAC,KAAK,EAAE,IAAI,CAAC;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,EAAE;gBACR,KAAK,EAAE,IAAA,yBAAS,EAAC,KAAK,EAAE,IAAI,CAAC;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAuB,EACvB,MAAe;IAEf,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE3D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAQ3C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAc,CAAC;IACnC,MAAM,KAAK,GAAY;QACrB,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE;KAC3D,CAAC;IACF,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACpD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE,YAAY,KAAK,IAAI;gBAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAC1E,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEnD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,IAAA,uCAAuB,EAAC,IAAI,CAAC,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,IAAA,yBAAS,EAAC,EAAE,EAAE,IAAI,CAAC;oBACvB,SAAS;oBACT,KAAK,EAAE,OAAO;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,EAAE;gBACR,EAAE,EAAE,IAAA,yBAAS,EAAC,EAAE,EAAE,IAAI,CAAC;gBACvB,SAAS;gBACT,KAAK,EAAE,OAAO;aACf,CAAC,CAAC;QACL,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,eAAgD,CAAC;QACjE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC/C,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,aAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;YAClE,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,EAAE;gBACR,EAAE;gBACF,SAAS,EAAE,EAAE,CAAC,aAAa;gBAC3B,KAAK,EAAE,OAAO;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW,EAAE,MAAM;QACnB,OAAO;QACP,OAAO;QACP,UAAU;QACV,SAAS;QACT,sBAAsB;QACtB,SAAS;QACT,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,OAAe,EAAE,OAAe;IAC9D,MAAM,IAAI,GAAG,IAAA,8BAAc,EAAC,OAAO,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,IAAA,8BAAc,EAAC,OAAO,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC7B,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO,GAAG,CAAC;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAC3E,CAAC;IACD,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,GAAG,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CACd,KAA2B,EAC3B,IAAY;IAEZ,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,SAAS,eAAe,CAAC,IAAuB;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,IAAI;YAAE,OAAO,UAAU,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kEAAkE;AAClE,SAAgB,mBAAmB,CACjC,IAAuB,EACvB,aAAqB;IAErB,MAAM,KAAK,GAAwB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACvB,IAAI,CAAC,CAAC,aAAa,KAAK,aAAa;YAAE,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,CAAC,QAAQ;YAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,CAAC,WAAW;YAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { StagehandDomProcessError } from \"../../../types/public/sdkErrors.js\";\nimport type { SessionDomIndex } from \"../../../types/private/snapshot.js\";\nimport {\n buildChildXPathSegments,\n joinXPath,\n normalizeXPath,\n} from \"./xpathUtils.js\";\n\n// starting from infinite depth (-1), exponentially shrink down to 1\nconst DOM_DEPTH_ATTEMPTS = [-1, 256, 128, 64, 32, 16, 8, 4, 2, 1];\nconst DESCRIBE_DEPTH_ATTEMPTS = [-1, 64, 32, 16, 8, 4, 2, 1];\n\n/** Identify CDP failures caused by deep DOM trees blowing the CBOR encoder stack. */\nfunction isCborStackError(message: string): boolean {\n return message.includes(\"CBOR: stack limit exceeded\");\n}\n\n/**\n * Determine if CDP truncated a node's children when streaming the DOM tree.\n * childNodeCount stays accurate even when `children` are omitted; we use this to\n * decide whether DOM.describeNode must be re-run for that node.\n */\nexport function shouldExpandNode(node: Protocol.DOM.Node): boolean {\n const declaredChildren = node.childNodeCount ?? 0;\n const realizedChildren = node.children?.length ?? 0;\n return declaredChildren > realizedChildren;\n}\n\n/** Merge an expanded DescribeNode payload back into the original shallow node. */\nexport function mergeDomNodes(\n target: Protocol.DOM.Node,\n source: Protocol.DOM.Node,\n): void {\n target.childNodeCount = source.childNodeCount ?? target.childNodeCount;\n target.children = source.children ?? target.children;\n target.shadowRoots = source.shadowRoots ?? target.shadowRoots;\n target.contentDocument = source.contentDocument ?? target.contentDocument;\n}\n\n/** Helper that returns every nested collection we recurse through uniformly. */\nexport function collectDomTraversalTargets(\n node: Protocol.DOM.Node,\n): Protocol.DOM.Node[] {\n const targets: Protocol.DOM.Node[] = [];\n if (node.children) targets.push(...node.children);\n if (node.shadowRoots) targets.push(...node.shadowRoots);\n if (node.contentDocument) targets.push(node.contentDocument);\n return targets;\n}\n\n/**\n * Rehydrate a truncated DOM tree by repeatedly calling DOM.describeNode with\n * decreasing depths. Any non-CBOR failure is surfaced as a StagehandDomProcessError.\n */\nexport async function hydrateDomTree(\n session: CDPSessionLike,\n root: Protocol.DOM.Node,\n pierce: boolean,\n): Promise<void> {\n const stack: Protocol.DOM.Node[] = [root];\n const expandedNodeIds = new Set<number>();\n const expandedBackendIds = new Set<number>();\n\n while (stack.length) {\n const node = stack.pop()!;\n const nodeId =\n typeof node.nodeId === \"number\" && node.nodeId > 0\n ? node.nodeId\n : undefined;\n const backendId =\n typeof node.backendNodeId === \"number\" && node.backendNodeId > 0\n ? node.backendNodeId\n : undefined;\n\n const seenByNode = nodeId ? expandedNodeIds.has(nodeId) : false;\n const seenByBackend =\n !nodeId && backendId ? expandedBackendIds.has(backendId) : false;\n if (seenByNode || seenByBackend) continue;\n if (nodeId) expandedNodeIds.add(nodeId);\n else if (backendId) expandedBackendIds.add(backendId);\n\n const needsExpansion = shouldExpandNode(node);\n if (needsExpansion && (nodeId || backendId)) {\n const describeParamsBase = nodeId\n ? { nodeId }\n : { backendNodeId: backendId! };\n let expanded = false;\n for (const depth of DESCRIBE_DEPTH_ATTEMPTS) {\n try {\n const described =\n await session.send<Protocol.DOM.DescribeNodeResponse>(\n \"DOM.describeNode\",\n {\n ...describeParamsBase,\n depth,\n pierce,\n },\n );\n mergeDomNodes(node, described.node);\n if (!nodeId && described.node.nodeId && described.node.nodeId > 0) {\n node.nodeId = described.node.nodeId;\n expandedNodeIds.add(described.node.nodeId);\n }\n expanded = true;\n break;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (isCborStackError(message)) {\n continue;\n }\n const identifier = nodeId ?? backendId ?? \"unknown\";\n throw new StagehandDomProcessError(\n `Failed to expand DOM node ${identifier}: ${String(err)}`,\n );\n }\n }\n if (!expanded) {\n const identifier = nodeId ?? backendId ?? \"unknown\";\n throw new StagehandDomProcessError(\n `Unable to expand DOM node ${identifier} after describeNode depth retries`,\n );\n }\n }\n\n for (const child of collectDomTraversalTargets(node)) {\n stack.push(child);\n }\n }\n}\n\n/**\n * Attempt DOM.getDocument with progressively shallower depths until CBOR stops\n * complaining. When a shallower snapshot is returned we hydrate the missing\n * branches so downstream DOM traversals see the full tree shape.\n */\nexport async function getDomTreeWithFallback(\n session: CDPSessionLike,\n pierce: boolean,\n): Promise<Protocol.DOM.Node> {\n let lastCborMessage = \"\";\n\n for (const depth of DOM_DEPTH_ATTEMPTS) {\n try {\n const { root } = await session.send<{ root: Protocol.DOM.Node }>(\n \"DOM.getDocument\",\n { depth, pierce },\n );\n\n if (depth !== -1) {\n await hydrateDomTree(session, root, pierce);\n }\n\n return root;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (isCborStackError(message)) {\n lastCborMessage = message;\n continue;\n }\n throw err;\n }\n }\n\n throw new StagehandDomProcessError(\n lastCborMessage\n ? `CDP DOM.getDocument failed after adaptive depth retries: ${lastCborMessage}`\n : \"CDP DOM.getDocument failed after adaptive depth retries.\",\n );\n}\n\n/**\n * Build tag name and XPath maps for a single frame session.\n * EncodedId is produced by a frame-aware encoder provided by the caller.\n */\nexport async function domMapsForSession(\n session: CDPSessionLike,\n frameId: string,\n pierce: boolean,\n encode: (fid: string, backendNodeId: number) => string,\n attemptOwnerLookup = true,\n): Promise<{\n tagNameMap: Record<string, string>;\n xpathMap: Record<string, string>;\n scrollableMap: Record<string, boolean>;\n}> {\n await session.send(\"DOM.enable\").catch(() => {});\n const root = await getDomTreeWithFallback(session, pierce);\n\n let startNode: Protocol.DOM.Node = root;\n if (attemptOwnerLookup) {\n try {\n const owner = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n const ownerBackendId = owner.backendNodeId;\n if (typeof ownerBackendId === \"number\") {\n const ownerEl = findNodeByBackendId(root, ownerBackendId);\n if (ownerEl?.contentDocument) {\n startNode = ownerEl.contentDocument;\n }\n }\n } catch {\n // OOPIF or race → keep startNode = root\n }\n }\n\n const tagNameMap: Record<string, string> = {};\n const xpathMap: Record<string, string> = {};\n const scrollableMap: Record<string, boolean> = {};\n\n type StackEntry = { node: Protocol.DOM.Node; xpath: string };\n const stack: StackEntry[] = [{ node: startNode, xpath: \"\" }];\n\n while (stack.length) {\n const { node, xpath } = stack.pop()!;\n\n if (node.backendNodeId) {\n const encId = encode(frameId, node.backendNodeId);\n tagNameMap[encId] = enrichedTagName(node);\n xpathMap[encId] = xpath || \"/\";\n const isScrollable = node?.isScrollable === true;\n if (isScrollable) scrollableMap[encId] = true;\n }\n\n const kids = node.children ?? [];\n if (kids.length) {\n const segs = buildChildXPathSegments(kids);\n for (let i = kids.length - 1; i >= 0; i--) {\n const child = kids[i]!;\n const step = segs[i]!;\n stack.push({\n node: child,\n xpath: joinXPath(xpath, step),\n });\n }\n }\n\n for (const sr of node.shadowRoots ?? []) {\n stack.push({\n node: sr,\n xpath: joinXPath(xpath, \"//\"),\n });\n }\n }\n\n return { tagNameMap, xpathMap, scrollableMap };\n}\n\n/**\n * Build an index of absolute XPath/tag metadata for an entire CDP session.\n * Once the index is cached, per-frame slices are derived without extra DOM\n * calls, which keeps snapshot capture linear in the number of frames.\n */\nexport async function buildSessionDomIndex(\n session: CDPSessionLike,\n pierce: boolean,\n): Promise<SessionDomIndex> {\n await session.send(\"DOM.enable\").catch(() => {});\n const root = await getDomTreeWithFallback(session, pierce);\n\n const absByBe = new Map<number, string>();\n const tagByBe = new Map<number, string>();\n const scrollByBe = new Map<number, boolean>();\n const docRootOf = new Map<number, number>();\n const contentDocRootByIframe = new Map<number, number>();\n const enterByBe = new Map<number, number>();\n const exitByBe = new Map<number, number>();\n\n type Entry = {\n node: Protocol.DOM.Node;\n xp: string;\n docRootBe: number;\n phase: \"enter\" | \"exit\";\n };\n const rootBe = root.backendNodeId!;\n const stack: Entry[] = [\n { node: root, xp: \"/\", docRootBe: rootBe, phase: \"enter\" },\n ];\n let dfsIndex = 0;\n\n while (stack.length) {\n const { node, xp, docRootBe, phase } = stack.pop()!;\n if (phase === \"exit\") {\n if (node.backendNodeId) {\n exitByBe.set(node.backendNodeId, dfsIndex++);\n }\n continue;\n }\n\n if (node.backendNodeId) {\n enterByBe.set(node.backendNodeId, dfsIndex++);\n absByBe.set(node.backendNodeId, xp || \"/\");\n tagByBe.set(node.backendNodeId, enrichedTagName(node));\n if (node?.isScrollable === true) scrollByBe.set(node.backendNodeId, true);\n docRootOf.set(node.backendNodeId, docRootBe);\n }\n\n stack.push({ node, xp, docRootBe, phase: \"exit\" });\n\n const kids = node.children ?? [];\n if (kids.length) {\n const segs = buildChildXPathSegments(kids);\n for (let i = kids.length - 1; i >= 0; i--) {\n const child = kids[i]!;\n const step = segs[i]!;\n stack.push({\n node: child,\n xp: joinXPath(xp, step),\n docRootBe,\n phase: \"enter\",\n });\n }\n }\n\n for (const sr of node.shadowRoots ?? []) {\n stack.push({\n node: sr,\n xp: joinXPath(xp, \"//\"),\n docRootBe,\n phase: \"enter\",\n });\n }\n\n const cd = node.contentDocument as Protocol.DOM.Node | undefined;\n if (cd && typeof cd.backendNodeId === \"number\") {\n contentDocRootByIframe.set(node.backendNodeId!, cd.backendNodeId);\n stack.push({\n node: cd,\n xp,\n docRootBe: cd.backendNodeId,\n phase: \"enter\",\n });\n }\n }\n\n return {\n rootBackend: rootBe,\n absByBe,\n tagByBe,\n scrollByBe,\n docRootOf,\n contentDocRootByIframe,\n enterByBe,\n exitByBe,\n };\n}\n\n/**\n * Relativize an absolute XPath against a document root's absolute path.\n * When the node lives outside the document we return the absolute path as-is.\n */\nexport function relativizeXPath(baseAbs: string, nodeAbs: string): string {\n const base = normalizeXPath(baseAbs);\n const abs = normalizeXPath(nodeAbs);\n if (abs === base) return \"/\";\n if (abs.startsWith(base)) {\n const tail = abs.slice(base.length);\n if (!tail) return \"/\";\n return tail.startsWith(\"/\") || tail.startsWith(\"//\") ? tail : `/${tail}`;\n }\n if (base === \"/\") return abs;\n return abs;\n}\n\n/**\n * Extract an attribute value from a CDP DOM node's flat attributes array.\n * Attributes are stored as [name1, value1, name2, value2, ...].\n */\nfunction getAttr(\n attrs: string[] | undefined,\n name: string,\n): string | undefined {\n if (!attrs) return undefined;\n for (let i = 0; i < attrs.length; i += 2) {\n if (attrs[i] === name) return attrs[i + 1];\n }\n return undefined;\n}\n\n/** Build an enriched tag name that includes the type attribute for inputs. */\nfunction enrichedTagName(node: Protocol.DOM.Node): string {\n const tag = String(node.nodeName).toLowerCase();\n if (tag === \"input\") {\n const type = getAttr(node.attributes, \"type\");\n if (type) return `input, ${type}`;\n }\n return tag;\n}\n\n/** Find a node by backendNodeId inside a DOM.getDocument tree. */\nexport function findNodeByBackendId(\n root: Protocol.DOM.Node,\n backendNodeId: number,\n): Protocol.DOM.Node | undefined {\n const stack: Protocol.DOM.Node[] = [root];\n while (stack.length) {\n const n = stack.pop()!;\n if (n.backendNodeId === backendNodeId) return n;\n if (n.children) for (const c of n.children) stack.push(c);\n if (n.shadowRoots) for (const s of n.shadowRoots) stack.push(s);\n }\n return undefined;\n}\n"]}
|
|
@@ -144,14 +144,25 @@ class FrameRegistry {
|
|
|
144
144
|
seedFromFrameTree(sessionId, frameTree) {
|
|
145
145
|
const walk = (tree, parent) => {
|
|
146
146
|
this.ensureNode(tree.frame.id);
|
|
147
|
+
const info = this.frames.get(tree.frame.id);
|
|
148
|
+
const previousParent = info.parentId;
|
|
149
|
+
const nextParent = parent ?? tree.frame.parentId ?? previousParent ?? null;
|
|
147
150
|
// topology
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
if (previousParent && previousParent !== nextParent) {
|
|
152
|
+
this.frames.get(previousParent)?.children.delete(tree.frame.id);
|
|
153
|
+
}
|
|
154
|
+
info.parentId = nextParent;
|
|
155
|
+
if (nextParent) {
|
|
156
|
+
this.ensureNode(nextParent);
|
|
157
|
+
this.frames.get(nextParent).children.add(tree.frame.id);
|
|
158
|
+
}
|
|
151
159
|
// last-seen frame
|
|
152
|
-
|
|
160
|
+
info.lastSeen =
|
|
161
|
+
nextParent && !tree.frame.parentId
|
|
162
|
+
? { ...tree.frame, parentId: nextParent }
|
|
163
|
+
: tree.frame;
|
|
153
164
|
// ownership (only if unknown)
|
|
154
|
-
if (!
|
|
165
|
+
if (!info.ownerSessionId) {
|
|
155
166
|
this.setOwnerSessionIdInternal(tree.frame.id, sessionId);
|
|
156
167
|
}
|
|
157
168
|
for (const c of tree.childFrames ?? [])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frameRegistry.js","sourceRoot":"","sources":["../../../../../lib/v3/understudy/frameRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["// lib/v3/understudy/frameRegistry.ts\nimport type { Protocol } from \"devtools-protocol\";\n\n/**\n * FrameRegistry\n *\n * Purpose:\n * A single, authoritative source of truth for **both**:\n * 1) Frame topology (parent/children, current main/root id, last-seen CDP `Frame`)\n * 2) Frame → Session ownership (which CDP session owns a given frameId)\n * 3) Optional iframe-owner metadata (backendNodeId of the <iframe> element in the parent doc)\n *\n *\n * Model:\n * - This class is **CDP-agnostic**; it stores **sessionId strings** (not session objects).\n * - Context bridges (wiring Target/Page events) must call the mutators below (onAttached,\n * onNavigated, onDetached, adoptChildSession, seedFromFrameTree, setOwnerBackendNodeId).\n * - Consumers ask read APIs (getOwnerSessionId, getParent, asProtocolFrameTree, listAll, …)\n * and never probe ownership at run time.\n */\n\ntype FrameId = string;\ntype SessionId = string;\n\ntype FrameInfo = {\n /** Parent frame id, or null for root */\n parentId: FrameId | null;\n /** Children frame ids (direct) */\n children: Set<FrameId>;\n /** Last-seen CDP Frame metadata for this id (may be a shell if never seen) */\n lastSeen?: Protocol.Page.Frame;\n\n /** Owning session id (CDP child session for OOPIF, top-level session for same-process) */\n ownerSessionId?: SessionId;\n\n /**\n * The backendNodeId of the <iframe> element **in the parent document** that hosts this frame.\n * Useful for building absolute XPath prefixes or DOM scoping in the parent session.\n */\n ownerBackendNodeId?: number;\n};\n\n/** Minimal “shell” CDP frame used when we haven’t yet seen a real Frame from events. */\nfunction shellFrame(id: FrameId): Protocol.Page.Frame {\n return {\n id,\n loaderId: \"\",\n url: \"\",\n domainAndRegistry: \"\",\n securityOrigin: \"\",\n mimeType: \"text/html\",\n secureContextType: \"InsecureScheme\",\n crossOriginIsolatedContextType: \"NotIsolated\",\n gatedAPIFeatures: [],\n } as Protocol.Page.Frame;\n}\n\nexport class FrameRegistry {\n /** Owner target id (top-level target); informational only */\n private readonly ownerTargetId: string;\n\n /** Current main/root frame id (changes on root swaps) */\n private rootFrameId: FrameId;\n\n /** frameId → FrameInfo */\n private frames = new Map<FrameId, FrameInfo>();\n\n /** sessionId → Set<frameId> (inverse map for diagnostics/fast membership checks) */\n private framesBySession = new Map<SessionId, Set<FrameId>>();\n\n constructor(ownerTargetId: string, mainFrameId: FrameId) {\n this.ownerTargetId = ownerTargetId;\n this.rootFrameId = mainFrameId;\n this.ensureNode(mainFrameId);\n }\n\n // ---------------------- Mutators (called by Context/Page bridges) ----------------------\n\n /**\n * Record that a frame attached. If `parentId` is null and `frameId` differs from the current\n * root, this is a root swap and we rename the root id.\n *\n * IMPORTANT: The emitter's `sessionId` is the **owner** for the new/attached frame.\n */\n onFrameAttached(\n frameId: FrameId,\n parentId: FrameId | null,\n sessionId: SessionId,\n ): void {\n // Root swap (parentId === null for main frames).\n if (!parentId && frameId !== this.rootFrameId) {\n this.renameNodeId(this.rootFrameId, frameId);\n this.rootFrameId = frameId;\n // ownership moves to this session as well\n this.setOwnerSessionIdInternal(frameId, sessionId);\n return;\n }\n\n // Normal attach\n this.ensureNode(frameId);\n if (parentId) this.ensureNode(parentId);\n\n const info = this.frames.get(frameId)!;\n info.parentId = parentId ?? null;\n\n if (parentId) {\n this.frames.get(parentId)!.children.add(frameId);\n }\n\n // Ownership: the session that emitted frameAttached owns this frame.\n this.setOwnerSessionIdInternal(frameId, sessionId);\n }\n\n /**\n * Record a navigation with the full CDP `Frame`. Also updates ownership based on the emitting\n * session id. Handles root swap if the navigated frame is the new main (no parentId).\n */\n onFrameNavigated(frame: Protocol.Page.Frame, sessionId: SessionId): void {\n this.ensureNode(frame.id);\n const info = this.frames.get(frame.id)!;\n info.lastSeen = frame;\n\n // Ownership follows the session that reported the navigation\n this.setOwnerSessionIdInternal(frame.id, sessionId);\n\n // If this frame has no parent, it might be the (new) main/root\n if (!(\"parentId\" in frame) || !frame.parentId) {\n if (frame.id !== this.rootFrameId) {\n // carry ordinal semantics by renaming the root id\n this.renameNodeId(this.rootFrameId, frame.id);\n this.rootFrameId = frame.id;\n }\n }\n }\n\n onNavigatedWithinDocument(\n frameId: FrameId,\n url: string,\n sessionId: SessionId,\n ): void {\n this.ensureNode(frameId);\n const info = this.frames.get(frameId)!;\n const lastSeen = info.lastSeen ?? shellFrame(frameId);\n info.lastSeen = { ...lastSeen, url };\n this.setOwnerSessionIdInternal(frameId, sessionId);\n }\n\n /**\n * Record that a frame detached. If `reason !== \"swap\"`, remove the subtree from the graph,\n * and clean the inverse maps. For “swap” we keep the node to preserve continuity.\n */\n onFrameDetached(\n frameId: FrameId,\n reason: \"remove\" | \"swap\" | string = \"remove\",\n ): void {\n if (reason === \"swap\") return;\n\n // Collect subtree starting from frameId.\n const toRemove: FrameId[] = [];\n const collect = (fid: FrameId) => {\n toRemove.push(fid);\n const kids = this.frames.get(fid)?.children ?? new Set<FrameId>();\n for (const k of kids) collect(k);\n };\n collect(frameId);\n\n // Remove nodes, fix parents and inverse maps\n for (const fid of toRemove) {\n const info = this.frames.get(fid);\n if (!info) continue;\n\n // unlink from parent\n if (info.parentId) {\n const p = this.frames.get(info.parentId);\n p?.children.delete(fid);\n }\n\n // unlink inverse session map\n if (info.ownerSessionId) {\n const bag = this.framesBySession.get(info.ownerSessionId);\n bag?.delete(fid);\n if (bag && bag.size === 0)\n this.framesBySession.delete(info.ownerSessionId);\n }\n\n this.frames.delete(fid);\n }\n\n // Guard root if we removed it; assign a placeholder root if needed\n if (!this.frames.has(this.rootFrameId)) {\n // Choose an arbitrary remaining node as root\n const iter = this.frames.keys().next();\n if (!iter.done) this.rootFrameId = iter.value;\n }\n }\n\n /**\n * An adopted OOPIF child session was created whose **main** frame id equals the parent iframe’s frameId.\n * We mark the entire child subtree as owned by `childSessionId`.\n * (Topology edges remain aligned by the parent session’s `frameAttached` events.)\n */\n adoptChildSession(\n childSessionId: SessionId,\n childMainFrameId: FrameId,\n ): void {\n // The child session will emit its own navigations/attachments; as a seed,\n // mark the root frame as owned by the child session.\n this.setOwnerSessionIdInternal(childMainFrameId, childSessionId);\n }\n\n /**\n * Seed topology and ownership from an existing `Page.getFrameTree` snapshot, typically right after\n * a session is attached. This is a best-effort: we record frames and set the provided `sessionId`\n * as owner for the subtree **if** an owner isn't already set.\n */\n seedFromFrameTree(\n sessionId: SessionId,\n frameTree: Protocol.Page.FrameTree,\n ): void {\n const walk = (tree: Protocol.Page.FrameTree, parent: FrameId | null) => {\n this.ensureNode(tree.frame.id);\n // topology\n this.frames.get(tree.frame.id)!.parentId = parent;\n if (parent) this.frames.get(parent)!.children.add(tree.frame.id);\n // last-seen frame\n this.frames.get(tree.frame.id)!.lastSeen = tree.frame;\n // ownership (only if unknown)\n if (!this.frames.get(tree.frame.id)!.ownerSessionId) {\n this.setOwnerSessionIdInternal(tree.frame.id, sessionId);\n }\n for (const c of tree.childFrames ?? []) walk(c, tree.frame.id);\n };\n walk(frameTree, null);\n }\n\n /**\n * Set the backendNodeId of the `<iframe>` element for a child frame **as seen from its parent**.\n * This is useful for building absolute XPath prefixes later (from the parent document).\n */\n setOwnerBackendNodeId(childFrameId: FrameId, backendNodeId: number): void {\n this.ensureNode(childFrameId);\n this.frames.get(childFrameId)!.ownerBackendNodeId = backendNodeId;\n }\n\n // ---------------------- Readers (consumed by Page/snapshot/locators) ----------------------\n\n mainFrameId(): FrameId {\n return this.rootFrameId;\n }\n\n /**\n * Return the owner session id for this frame. If unknown, returns `undefined`.\n */\n getOwnerSessionId(frameId: FrameId): SessionId | undefined {\n return this.frames.get(frameId)?.ownerSessionId;\n }\n\n /**\n * Return the owner backendNodeId (iframe element) if recorded.\n * This is in the **parent** document; pair it with `getParent`.\n */\n getOwnerBackendNodeId(frameId: FrameId): number | undefined {\n return this.frames.get(frameId)?.ownerBackendNodeId;\n }\n\n /**\n * Return the parent frame id, or null for root/unknown.\n */\n getParent(frameId: FrameId): FrameId | null {\n return this.frames.get(frameId)?.parentId ?? null;\n }\n\n /**\n * List frame ids in root-first DFS order (same shape as CDP’s FrameTree traversal).\n */\n listAllFrames(): FrameId[] {\n const out: FrameId[] = [];\n const dfs = (fid: FrameId) => {\n out.push(fid);\n const kids = this.frames.get(fid)?.children ?? new Set<FrameId>();\n for (const k of kids) dfs(k);\n };\n if (this.frames.has(this.rootFrameId)) dfs(this.rootFrameId);\n return out;\n }\n\n /**\n * Serialize to `Protocol.Page.FrameTree` starting at the given root id (typically mainFrameId()).\n */\n asProtocolFrameTree(rootId: FrameId): Protocol.Page.FrameTree {\n const build = (fid: FrameId): Protocol.Page.FrameTree => {\n const info = this.frames.get(fid);\n const frame = info?.lastSeen ?? shellFrame(fid);\n\n const kids = info?.children ?? new Set<FrameId>();\n const childFrames = kids.size\n ? [...kids].map((k) => build(k))\n : undefined;\n\n return childFrames ? { frame, childFrames } : { frame };\n };\n\n return build(rootId);\n }\n\n /**\n * For diagnostics: return the current owner sessions for a frame id (0..n),\n * usually 0 or 1, but helpful to see potential inconsistencies during wiring.\n */\n sessionsForFrame(frameId: FrameId): SessionId[] {\n const info = this.frames.get(frameId);\n return info?.ownerSessionId ? [info.ownerSessionId] : [];\n }\n\n /**\n * For diagnostics: return current frame set per session.\n */\n framesForSession(sessionId: SessionId): FrameId[] {\n return [...(this.framesBySession.get(sessionId) ?? new Set())];\n }\n\n // ---------------------- Internal helpers ----------------------\n\n private ensureNode(fid: FrameId): void {\n if (this.frames.has(fid)) return;\n this.frames.set(fid, {\n parentId: null,\n children: new Set<FrameId>(),\n lastSeen: shellFrame(fid),\n ownerSessionId: undefined,\n ownerBackendNodeId: undefined,\n });\n }\n\n private renameNodeId(oldId: FrameId, newId: FrameId): void {\n if (oldId === newId) return;\n this.ensureNode(oldId);\n\n const info = this.frames.get(oldId)!;\n\n // Move info under new id\n this.frames.delete(oldId);\n this.frames.set(newId, { ...info });\n\n // Fix parent’s children set\n if (info.parentId) {\n const p = this.frames.get(info.parentId);\n if (p) {\n p.children.delete(oldId);\n p.children.add(newId);\n }\n }\n\n // Fix children’s parent pointers\n for (const c of info.children) {\n const ci = this.frames.get(c);\n if (ci) ci.parentId = newId;\n }\n\n // Fix inverse map (session -> frames)\n if (info.ownerSessionId) {\n const bag = this.framesBySession.get(info.ownerSessionId);\n if (bag) {\n bag.delete(oldId);\n bag.add(newId);\n }\n }\n\n // If root moved, keep the root id updated is handled by caller\n }\n\n private setOwnerSessionIdInternal(\n frameId: FrameId,\n sessionId: SessionId,\n ): void {\n this.ensureNode(frameId);\n const info = this.frames.get(frameId)!;\n\n // If the owner is unchanged, do nothing\n if (info.ownerSessionId === sessionId) return;\n\n // Remove from previous owner bag\n if (info.ownerSessionId) {\n const prev = this.framesBySession.get(info.ownerSessionId);\n prev?.delete(frameId);\n if (prev && prev.size === 0)\n this.framesBySession.delete(info.ownerSessionId);\n }\n\n // Set new owner and update bag\n info.ownerSessionId = sessionId;\n const bag = this.framesBySession.get(sessionId) ?? new Set<FrameId>();\n bag.add(frameId);\n this.framesBySession.set(sessionId, bag);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"frameRegistry.js","sourceRoot":"","sources":["../../../../../lib/v3/understudy/frameRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["// lib/v3/understudy/frameRegistry.ts\nimport type { Protocol } from \"devtools-protocol\";\n\n/**\n * FrameRegistry\n *\n * Purpose:\n * A single, authoritative source of truth for **both**:\n * 1) Frame topology (parent/children, current main/root id, last-seen CDP `Frame`)\n * 2) Frame → Session ownership (which CDP session owns a given frameId)\n * 3) Optional iframe-owner metadata (backendNodeId of the <iframe> element in the parent doc)\n *\n *\n * Model:\n * - This class is **CDP-agnostic**; it stores **sessionId strings** (not session objects).\n * - Context bridges (wiring Target/Page events) must call the mutators below (onAttached,\n * onNavigated, onDetached, adoptChildSession, seedFromFrameTree, setOwnerBackendNodeId).\n * - Consumers ask read APIs (getOwnerSessionId, getParent, asProtocolFrameTree, listAll, …)\n * and never probe ownership at run time.\n */\n\ntype FrameId = string;\ntype SessionId = string;\n\ntype FrameInfo = {\n /** Parent frame id, or null for root */\n parentId: FrameId | null;\n /** Children frame ids (direct) */\n children: Set<FrameId>;\n /** Last-seen CDP Frame metadata for this id (may be a shell if never seen) */\n lastSeen?: Protocol.Page.Frame;\n\n /** Owning session id (CDP child session for OOPIF, top-level session for same-process) */\n ownerSessionId?: SessionId;\n\n /**\n * The backendNodeId of the <iframe> element **in the parent document** that hosts this frame.\n * Useful for building absolute XPath prefixes or DOM scoping in the parent session.\n */\n ownerBackendNodeId?: number;\n};\n\n/** Minimal “shell” CDP frame used when we haven’t yet seen a real Frame from events. */\nfunction shellFrame(id: FrameId): Protocol.Page.Frame {\n return {\n id,\n loaderId: \"\",\n url: \"\",\n domainAndRegistry: \"\",\n securityOrigin: \"\",\n mimeType: \"text/html\",\n secureContextType: \"InsecureScheme\",\n crossOriginIsolatedContextType: \"NotIsolated\",\n gatedAPIFeatures: [],\n } as Protocol.Page.Frame;\n}\n\nexport class FrameRegistry {\n /** Owner target id (top-level target); informational only */\n private readonly ownerTargetId: string;\n\n /** Current main/root frame id (changes on root swaps) */\n private rootFrameId: FrameId;\n\n /** frameId → FrameInfo */\n private frames = new Map<FrameId, FrameInfo>();\n\n /** sessionId → Set<frameId> (inverse map for diagnostics/fast membership checks) */\n private framesBySession = new Map<SessionId, Set<FrameId>>();\n\n constructor(ownerTargetId: string, mainFrameId: FrameId) {\n this.ownerTargetId = ownerTargetId;\n this.rootFrameId = mainFrameId;\n this.ensureNode(mainFrameId);\n }\n\n // ---------------------- Mutators (called by Context/Page bridges) ----------------------\n\n /**\n * Record that a frame attached. If `parentId` is null and `frameId` differs from the current\n * root, this is a root swap and we rename the root id.\n *\n * IMPORTANT: The emitter's `sessionId` is the **owner** for the new/attached frame.\n */\n onFrameAttached(\n frameId: FrameId,\n parentId: FrameId | null,\n sessionId: SessionId,\n ): void {\n // Root swap (parentId === null for main frames).\n if (!parentId && frameId !== this.rootFrameId) {\n this.renameNodeId(this.rootFrameId, frameId);\n this.rootFrameId = frameId;\n // ownership moves to this session as well\n this.setOwnerSessionIdInternal(frameId, sessionId);\n return;\n }\n\n // Normal attach\n this.ensureNode(frameId);\n if (parentId) this.ensureNode(parentId);\n\n const info = this.frames.get(frameId)!;\n info.parentId = parentId ?? null;\n\n if (parentId) {\n this.frames.get(parentId)!.children.add(frameId);\n }\n\n // Ownership: the session that emitted frameAttached owns this frame.\n this.setOwnerSessionIdInternal(frameId, sessionId);\n }\n\n /**\n * Record a navigation with the full CDP `Frame`. Also updates ownership based on the emitting\n * session id. Handles root swap if the navigated frame is the new main (no parentId).\n */\n onFrameNavigated(frame: Protocol.Page.Frame, sessionId: SessionId): void {\n this.ensureNode(frame.id);\n const info = this.frames.get(frame.id)!;\n info.lastSeen = frame;\n\n // Ownership follows the session that reported the navigation\n this.setOwnerSessionIdInternal(frame.id, sessionId);\n\n // If this frame has no parent, it might be the (new) main/root\n if (!(\"parentId\" in frame) || !frame.parentId) {\n if (frame.id !== this.rootFrameId) {\n // carry ordinal semantics by renaming the root id\n this.renameNodeId(this.rootFrameId, frame.id);\n this.rootFrameId = frame.id;\n }\n }\n }\n\n onNavigatedWithinDocument(\n frameId: FrameId,\n url: string,\n sessionId: SessionId,\n ): void {\n this.ensureNode(frameId);\n const info = this.frames.get(frameId)!;\n const lastSeen = info.lastSeen ?? shellFrame(frameId);\n info.lastSeen = { ...lastSeen, url };\n this.setOwnerSessionIdInternal(frameId, sessionId);\n }\n\n /**\n * Record that a frame detached. If `reason !== \"swap\"`, remove the subtree from the graph,\n * and clean the inverse maps. For “swap” we keep the node to preserve continuity.\n */\n onFrameDetached(\n frameId: FrameId,\n reason: \"remove\" | \"swap\" | string = \"remove\",\n ): void {\n if (reason === \"swap\") return;\n\n // Collect subtree starting from frameId.\n const toRemove: FrameId[] = [];\n const collect = (fid: FrameId) => {\n toRemove.push(fid);\n const kids = this.frames.get(fid)?.children ?? new Set<FrameId>();\n for (const k of kids) collect(k);\n };\n collect(frameId);\n\n // Remove nodes, fix parents and inverse maps\n for (const fid of toRemove) {\n const info = this.frames.get(fid);\n if (!info) continue;\n\n // unlink from parent\n if (info.parentId) {\n const p = this.frames.get(info.parentId);\n p?.children.delete(fid);\n }\n\n // unlink inverse session map\n if (info.ownerSessionId) {\n const bag = this.framesBySession.get(info.ownerSessionId);\n bag?.delete(fid);\n if (bag && bag.size === 0)\n this.framesBySession.delete(info.ownerSessionId);\n }\n\n this.frames.delete(fid);\n }\n\n // Guard root if we removed it; assign a placeholder root if needed\n if (!this.frames.has(this.rootFrameId)) {\n // Choose an arbitrary remaining node as root\n const iter = this.frames.keys().next();\n if (!iter.done) this.rootFrameId = iter.value;\n }\n }\n\n /**\n * An adopted OOPIF child session was created whose **main** frame id equals the parent iframe’s frameId.\n * We mark the entire child subtree as owned by `childSessionId`.\n * (Topology edges remain aligned by the parent session’s `frameAttached` events.)\n */\n adoptChildSession(\n childSessionId: SessionId,\n childMainFrameId: FrameId,\n ): void {\n // The child session will emit its own navigations/attachments; as a seed,\n // mark the root frame as owned by the child session.\n this.setOwnerSessionIdInternal(childMainFrameId, childSessionId);\n }\n\n /**\n * Seed topology and ownership from an existing `Page.getFrameTree` snapshot, typically right after\n * a session is attached. This is a best-effort: we record frames and set the provided `sessionId`\n * as owner for the subtree **if** an owner isn't already set.\n */\n seedFromFrameTree(\n sessionId: SessionId,\n frameTree: Protocol.Page.FrameTree,\n ): void {\n const walk = (tree: Protocol.Page.FrameTree, parent: FrameId | null) => {\n this.ensureNode(tree.frame.id);\n const info = this.frames.get(tree.frame.id)!;\n const previousParent = info.parentId;\n const nextParent =\n parent ?? tree.frame.parentId ?? previousParent ?? null;\n\n // topology\n if (previousParent && previousParent !== nextParent) {\n this.frames.get(previousParent)?.children.delete(tree.frame.id);\n }\n info.parentId = nextParent;\n if (nextParent) {\n this.ensureNode(nextParent);\n this.frames.get(nextParent)!.children.add(tree.frame.id);\n }\n // last-seen frame\n info.lastSeen =\n nextParent && !tree.frame.parentId\n ? { ...tree.frame, parentId: nextParent }\n : tree.frame;\n // ownership (only if unknown)\n if (!info.ownerSessionId) {\n this.setOwnerSessionIdInternal(tree.frame.id, sessionId);\n }\n for (const c of tree.childFrames ?? []) walk(c, tree.frame.id);\n };\n walk(frameTree, null);\n }\n\n /**\n * Set the backendNodeId of the `<iframe>` element for a child frame **as seen from its parent**.\n * This is useful for building absolute XPath prefixes later (from the parent document).\n */\n setOwnerBackendNodeId(childFrameId: FrameId, backendNodeId: number): void {\n this.ensureNode(childFrameId);\n this.frames.get(childFrameId)!.ownerBackendNodeId = backendNodeId;\n }\n\n // ---------------------- Readers (consumed by Page/snapshot/locators) ----------------------\n\n mainFrameId(): FrameId {\n return this.rootFrameId;\n }\n\n /**\n * Return the owner session id for this frame. If unknown, returns `undefined`.\n */\n getOwnerSessionId(frameId: FrameId): SessionId | undefined {\n return this.frames.get(frameId)?.ownerSessionId;\n }\n\n /**\n * Return the owner backendNodeId (iframe element) if recorded.\n * This is in the **parent** document; pair it with `getParent`.\n */\n getOwnerBackendNodeId(frameId: FrameId): number | undefined {\n return this.frames.get(frameId)?.ownerBackendNodeId;\n }\n\n /**\n * Return the parent frame id, or null for root/unknown.\n */\n getParent(frameId: FrameId): FrameId | null {\n return this.frames.get(frameId)?.parentId ?? null;\n }\n\n /**\n * List frame ids in root-first DFS order (same shape as CDP’s FrameTree traversal).\n */\n listAllFrames(): FrameId[] {\n const out: FrameId[] = [];\n const dfs = (fid: FrameId) => {\n out.push(fid);\n const kids = this.frames.get(fid)?.children ?? new Set<FrameId>();\n for (const k of kids) dfs(k);\n };\n if (this.frames.has(this.rootFrameId)) dfs(this.rootFrameId);\n return out;\n }\n\n /**\n * Serialize to `Protocol.Page.FrameTree` starting at the given root id (typically mainFrameId()).\n */\n asProtocolFrameTree(rootId: FrameId): Protocol.Page.FrameTree {\n const build = (fid: FrameId): Protocol.Page.FrameTree => {\n const info = this.frames.get(fid);\n const frame = info?.lastSeen ?? shellFrame(fid);\n\n const kids = info?.children ?? new Set<FrameId>();\n const childFrames = kids.size\n ? [...kids].map((k) => build(k))\n : undefined;\n\n return childFrames ? { frame, childFrames } : { frame };\n };\n\n return build(rootId);\n }\n\n /**\n * For diagnostics: return the current owner sessions for a frame id (0..n),\n * usually 0 or 1, but helpful to see potential inconsistencies during wiring.\n */\n sessionsForFrame(frameId: FrameId): SessionId[] {\n const info = this.frames.get(frameId);\n return info?.ownerSessionId ? [info.ownerSessionId] : [];\n }\n\n /**\n * For diagnostics: return current frame set per session.\n */\n framesForSession(sessionId: SessionId): FrameId[] {\n return [...(this.framesBySession.get(sessionId) ?? new Set())];\n }\n\n // ---------------------- Internal helpers ----------------------\n\n private ensureNode(fid: FrameId): void {\n if (this.frames.has(fid)) return;\n this.frames.set(fid, {\n parentId: null,\n children: new Set<FrameId>(),\n lastSeen: shellFrame(fid),\n ownerSessionId: undefined,\n ownerBackendNodeId: undefined,\n });\n }\n\n private renameNodeId(oldId: FrameId, newId: FrameId): void {\n if (oldId === newId) return;\n this.ensureNode(oldId);\n\n const info = this.frames.get(oldId)!;\n\n // Move info under new id\n this.frames.delete(oldId);\n this.frames.set(newId, { ...info });\n\n // Fix parent’s children set\n if (info.parentId) {\n const p = this.frames.get(info.parentId);\n if (p) {\n p.children.delete(oldId);\n p.children.add(newId);\n }\n }\n\n // Fix children’s parent pointers\n for (const c of info.children) {\n const ci = this.frames.get(c);\n if (ci) ci.parentId = newId;\n }\n\n // Fix inverse map (session -> frames)\n if (info.ownerSessionId) {\n const bag = this.framesBySession.get(info.ownerSessionId);\n if (bag) {\n bag.delete(oldId);\n bag.add(newId);\n }\n }\n\n // If root moved, keep the root id updated is handled by caller\n }\n\n private setOwnerSessionIdInternal(\n frameId: FrameId,\n sessionId: SessionId,\n ): void {\n this.ensureNode(frameId);\n const info = this.frames.get(frameId)!;\n\n // If the owner is unchanged, do nothing\n if (info.ownerSessionId === sessionId) return;\n\n // Remove from previous owner bag\n if (info.ownerSessionId) {\n const prev = this.framesBySession.get(info.ownerSessionId);\n prev?.delete(frameId);\n if (prev && prev.size === 0)\n this.framesBySession.delete(info.ownerSessionId);\n }\n\n // Set new owner and update bag\n info.ownerSessionId = sessionId;\n const bag = this.framesBySession.get(sessionId) ?? new Set<FrameId>();\n bag.add(frameId);\n this.framesBySession.set(sessionId, bag);\n }\n}\n"]}
|
package/dist/cjs/lib/v3/v3.d.ts
CHANGED
|
@@ -111,6 +111,7 @@ export declare class V3 {
|
|
|
111
111
|
private mergeAgentMetricsWithLocalFallback;
|
|
112
112
|
private updateAgentMetricsFromUsage;
|
|
113
113
|
private resolveLlmClient;
|
|
114
|
+
private resolveDefaultAgentMode;
|
|
114
115
|
private beginAgentReplayRecording;
|
|
115
116
|
private endAgentReplayRecording;
|
|
116
117
|
private discardAgentReplayRecording;
|
package/dist/cjs/lib/v3/v3.js
CHANGED
|
@@ -97,6 +97,7 @@ const logger_js_2 = require("./logger.js");
|
|
|
97
97
|
const cleanupLocal_js_1 = require("./shutdown/cleanupLocal.js");
|
|
98
98
|
const supervisorClient_js_1 = require("./shutdown/supervisorClient.js");
|
|
99
99
|
const utils_js_2 = require("./mcp/utils.js");
|
|
100
|
+
const agent_js_1 = require("./types/private/agent.js");
|
|
100
101
|
const index_js_1 = require("./types/public/index.js");
|
|
101
102
|
const context_js_1 = require("./understudy/context.js");
|
|
102
103
|
const modelUtils_js_2 = require("../modelUtils.js");
|
|
@@ -551,6 +552,11 @@ let V3 = (() => {
|
|
|
551
552
|
this.overrideLlmClients.set(cacheKey, client);
|
|
552
553
|
return client;
|
|
553
554
|
}
|
|
555
|
+
resolveDefaultAgentMode(model) {
|
|
556
|
+
const modelName = (0, modelUtils_js_1.extractModelName)(model) ?? this.modelName;
|
|
557
|
+
const matchedPattern = agent_js_1.HYBRID_CAPABLE_MODEL_PATTERNS.find((pattern) => modelName.includes(pattern));
|
|
558
|
+
return matchedPattern ? "hybrid" : "dom";
|
|
559
|
+
}
|
|
554
560
|
beginAgentReplayRecording() {
|
|
555
561
|
this.agentCache.beginRecording();
|
|
556
562
|
}
|
|
@@ -1135,6 +1141,7 @@ let V3 = (() => {
|
|
|
1135
1141
|
model: options?.model,
|
|
1136
1142
|
timeout: options?.timeout,
|
|
1137
1143
|
selector: options?.selector,
|
|
1144
|
+
ignoreSelectors: options?.ignoreSelectors,
|
|
1138
1145
|
page,
|
|
1139
1146
|
};
|
|
1140
1147
|
let result;
|
|
@@ -1157,6 +1164,7 @@ let V3 = (() => {
|
|
|
1157
1164
|
this.addToHistory("extract", {
|
|
1158
1165
|
instruction,
|
|
1159
1166
|
selector: options?.selector,
|
|
1167
|
+
ignoreSelectors: options?.ignoreSelectors,
|
|
1160
1168
|
timeout: options?.timeout,
|
|
1161
1169
|
schema: historySchemaDescriptor,
|
|
1162
1170
|
}, result);
|
|
@@ -1456,14 +1464,6 @@ let V3 = (() => {
|
|
|
1456
1464
|
*/
|
|
1457
1465
|
async prepareAgentExecution(options, instructionOrOptions, agentConfigSignature) {
|
|
1458
1466
|
// Note: experimental validation is done at the call site before this method
|
|
1459
|
-
// Warn if mode is not explicitly set (defaults to "dom")
|
|
1460
|
-
if (options?.mode === undefined) {
|
|
1461
|
-
this.logger({
|
|
1462
|
-
category: "agent",
|
|
1463
|
-
message: "Using agent in default DOM mode (legacy). Agent will default to 'hybrid' on an upcoming release for improved performance.\n → https://docs.stagehand.dev/v3/basics/agent\n",
|
|
1464
|
-
level: 0,
|
|
1465
|
-
});
|
|
1466
|
-
}
|
|
1467
1467
|
const tools = options?.integrations
|
|
1468
1468
|
? await (0, utils_js_2.resolveTools)(options.integrations, options.tools)
|
|
1469
1469
|
: (options?.tools ?? {});
|
|
@@ -1471,7 +1471,8 @@ let V3 = (() => {
|
|
|
1471
1471
|
? this.resolveLlmClient(options.model)
|
|
1472
1472
|
: this.llmClient;
|
|
1473
1473
|
const resolvedExecutionModel = options?.executionModel ?? options?.model;
|
|
1474
|
-
const
|
|
1474
|
+
const resolvedMode = options?.mode ?? this.resolveDefaultAgentMode(options?.model);
|
|
1475
|
+
const handler = new v3AgentHandler_js_1.V3AgentHandler(this, this.logger, agentLlmClient, resolvedExecutionModel, options?.systemPrompt, tools, resolvedMode, this.isCaptchaAutoSolveEnabled);
|
|
1475
1476
|
const resolvedOptions = typeof instructionOrOptions === "string"
|
|
1476
1477
|
? {
|
|
1477
1478
|
instruction: instructionOrOptions,
|
|
@@ -1510,10 +1511,8 @@ let V3 = (() => {
|
|
|
1510
1511
|
};
|
|
1511
1512
|
}
|
|
1512
1513
|
agent(options) {
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
? options.mode === "cua"
|
|
1516
|
-
: options?.cua === true;
|
|
1514
|
+
const isCuaMode = options?.mode === "cua" ||
|
|
1515
|
+
(options?.mode === undefined && options?.cua === true);
|
|
1517
1516
|
// Emit deprecation warning for cua: true
|
|
1518
1517
|
if (options?.cua === true) {
|
|
1519
1518
|
this.logger({
|
|
@@ -1523,13 +1522,15 @@ let V3 = (() => {
|
|
|
1523
1522
|
});
|
|
1524
1523
|
console.warn('[Stagehand] DEPRECATED: The "cua: true" option is deprecated. Use "mode: \'cua\'" instead.');
|
|
1525
1524
|
}
|
|
1525
|
+
const loggedMode = options?.mode ??
|
|
1526
|
+
(isCuaMode ? "cua" : this.resolveDefaultAgentMode(options?.model));
|
|
1526
1527
|
this.logger({
|
|
1527
1528
|
category: "agent",
|
|
1528
1529
|
message: "Creating v3 agent instance",
|
|
1529
1530
|
level: 1,
|
|
1530
1531
|
auxiliary: {
|
|
1531
1532
|
cua: { value: isCuaMode ? "true" : "false", type: "boolean" },
|
|
1532
|
-
mode: { value:
|
|
1533
|
+
mode: { value: loggedMode, type: "string" },
|
|
1533
1534
|
model: {
|
|
1534
1535
|
value: (0, modelUtils_js_1.extractModelName)(options?.model) ?? this.llmClient.modelName,
|
|
1535
1536
|
type: "string",
|