@enricai/barnacle 1.6.6 → 1.6.8
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/README.md +2 -1
- package/dist/plugins/config-plugin.d.ts +2 -0
- package/dist/plugins/config-plugin.d.ts.map +1 -1
- package/dist/plugins/config-plugin.js +4 -0
- package/dist/plugins/config-plugin.js.map +1 -1
- package/dist/plugins/discover.d.ts.map +1 -1
- package/dist/plugins/discover.js +1 -0
- package/dist/plugins/discover.js.map +1 -1
- package/dist/plugins/loader.js +2 -2
- package/dist/plugins/loader.js.map +1 -1
- package/dist/scraper/behavioral-signals.d.ts +10 -3
- package/dist/scraper/behavioral-signals.d.ts.map +1 -1
- package/dist/scraper/behavioral-signals.js +17 -6
- package/dist/scraper/behavioral-signals.js.map +1 -1
- package/dist/scraper/deep-query.d.ts +8 -0
- package/dist/scraper/deep-query.d.ts.map +1 -1
- package/dist/scraper/deep-query.js +9 -1
- package/dist/scraper/deep-query.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +156 -24
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +234 -130
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/frame-target.d.ts +88 -0
- package/dist/scraper/frame-target.d.ts.map +1 -0
- package/dist/scraper/frame-target.js +164 -0
- package/dist/scraper/frame-target.js.map +1 -0
- package/dist/scraper/retry.d.ts +2 -2
- package/dist/scraper/retry.d.ts.map +1 -1
- package/dist/scraper/retry.js +8 -8
- package/dist/scraper/retry.js.map +1 -1
- package/dist/scraper/stagehand-guard.d.ts +31 -3
- package/dist/scraper/stagehand-guard.d.ts.map +1 -1
- package/dist/scraper/stagehand-guard.js +53 -7
- package/dist/scraper/stagehand-guard.js.map +1 -1
- package/dist/scraper/submit-control.d.ts +15 -2
- package/dist/scraper/submit-control.d.ts.map +1 -1
- package/dist/scraper/submit-control.js +17 -4
- package/dist/scraper/submit-control.js.map +1 -1
- package/dist/scripts/recon-browser.d.ts +80 -1
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +36 -8
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.d.ts +6 -0
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +9 -7
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/site-plugin.d.ts +7 -0
- package/dist/site-plugin.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-origin frame resolver: the single seam that lets every downstream
|
|
3
|
+
* helper (flow-runner primitives, guarded Stagehand calls) act on either the
|
|
4
|
+
* main frame or a resolved cross-origin OOPIF without knowing which. Some
|
|
5
|
+
* ATS integrations (e.g. UCHealth's Talemetry wizard) embed their entire
|
|
6
|
+
* application form inside a cross-origin `<iframe>` rather than navigating
|
|
7
|
+
* the top window to it, and `document`-rooted helpers (`page.evaluate`,
|
|
8
|
+
* `page.locator`) cannot reach across that boundary — `contentDocument` on a
|
|
9
|
+
* cross-origin iframe element is `null` from page script's perspective.
|
|
10
|
+
* `resolveFrameTarget` finds the child `Frame` Stagehand's CDP layer already
|
|
11
|
+
* attached to and wraps it in a uniform `FrameTarget` surface.
|
|
12
|
+
*/
|
|
13
|
+
import type { Page } from "@browserbasehq/stagehand";
|
|
14
|
+
/** The frame handle type `Page.frames()` returns, without a deep import into Stagehand's understudy internals. */
|
|
15
|
+
type StagehandFrame = ReturnType<Page["frames"]>[number];
|
|
16
|
+
/**
|
|
17
|
+
* Uniform evaluate/locator/url/title surface bound to either the main frame
|
|
18
|
+
* (`frame: null`) or a resolved cross-origin child frame. `frameSelector` is
|
|
19
|
+
* the CSS selector of the scoped frame (or `null` for main), carried so
|
|
20
|
+
* callers can pass it straight through to `ObserveOptions.selector` /
|
|
21
|
+
* `ExtractOptions.selector` and scope Stagehand's own observe/extract calls
|
|
22
|
+
* to the same frame this target evaluates and locates against.
|
|
23
|
+
*/
|
|
24
|
+
export interface FrameTarget {
|
|
25
|
+
/** The resolved child frame, or `null` when this target is bound to the main frame. */
|
|
26
|
+
readonly frame: StagehandFrame | null;
|
|
27
|
+
/** CSS selector for the Stagehand scope hint (`ObserveOptions.selector` / `ExtractOptions.selector`), or `null` for the main frame. */
|
|
28
|
+
readonly frameSelector: string | null;
|
|
29
|
+
/** Evaluate a function or expression against the resolved frame (or the main frame when unresolved). */
|
|
30
|
+
evaluate<R = unknown, Arg = unknown>(pageFunctionOrExpression: string | ((arg: Arg) => R | Promise<R>), arg?: Arg): Promise<R>;
|
|
31
|
+
/** Build a Locator scoped to the resolved frame (or the main frame when unresolved). */
|
|
32
|
+
locator(selector: string): ReturnType<Page["locator"]>;
|
|
33
|
+
/** Current URL of the resolved frame (or the main frame when unresolved). */
|
|
34
|
+
url(): Promise<string>;
|
|
35
|
+
/** Current document title. Cross-origin child frames have no accessible `document.title` distinct from the top document via CDP `Page.title`, so this always reads the top document's title. */
|
|
36
|
+
title(): Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds the main-frame `FrameTarget`: every method delegates straight to
|
|
40
|
+
* `Page`, matching today's behavior for every site whose ATS form never
|
|
41
|
+
* leaves the top window. Exported so call sites that have not yet resolved
|
|
42
|
+
* a `FrameTarget` from `deps.frameSelector` can still pass a target-shaped
|
|
43
|
+
* value to helpers that now require one.
|
|
44
|
+
*/
|
|
45
|
+
export declare function mainFrameTarget(page: Page): FrameTarget;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves the `FrameTarget` for `frameSelector` against `page`, falling
|
|
48
|
+
* back to the main-frame target whenever resolution can't confidently
|
|
49
|
+
* succeed rather than throwing:
|
|
50
|
+
*
|
|
51
|
+
* 1. `frameSelector` is `null`/`undefined` → main-frame target (today's
|
|
52
|
+
* behavior, unchanged).
|
|
53
|
+
* 2. No element in the main document matches `frameSelector`, or it isn't
|
|
54
|
+
* an `<iframe>`/has no `src` → main-frame target.
|
|
55
|
+
* 3. No frame in `page.frames()` has an origin matching the `<iframe>`
|
|
56
|
+
* element's `src` → main-frame target.
|
|
57
|
+
* 4. Otherwise → a child-frame target bound to the first matching frame.
|
|
58
|
+
*
|
|
59
|
+
* Step 2 reads the `src` attribute (not `contentDocument`) via `page.evaluate`
|
|
60
|
+
* on the main frame, which stays readable across the cross-origin boundary —
|
|
61
|
+
* only same-origin script access to the child's document is blocked.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveFrameTarget(page: Page, frameSelector?: string | null): Promise<FrameTarget>;
|
|
64
|
+
/**
|
|
65
|
+
* Composes a Stagehand hop-notation scope string from a frame selector and an
|
|
66
|
+
* inner selector, for callers building `ObserveOptions.selector` /
|
|
67
|
+
* `ExtractOptions.selector` values — kept separate from `FrameTarget` itself
|
|
68
|
+
* so `resolveFrameTarget` keeps receiving only the bare iframe-id hop (the
|
|
69
|
+
* contract `frame-resolve.test.ts` pins) rather than a pre-composed string.
|
|
70
|
+
*/
|
|
71
|
+
export declare function buildHopSelector(frameSelector: string | null | undefined, innerSelector: string): string;
|
|
72
|
+
/** Shared delay helper — `FrameTarget` has no `waitForTimeout` since it isn't frame-scoped. */
|
|
73
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Blocks until a resolved child frame has a live document (`document.readyState`
|
|
76
|
+
* is `"interactive"` or `"complete"`), so callers do not observe/act against a
|
|
77
|
+
* frame that CDP has attached to but that has not yet navigated past `about:blank`
|
|
78
|
+
* — the state right after `Target.setAutoAttach` fires and before the OOPIF's own
|
|
79
|
+
* navigation lands. Best-effort like `waitForSpaReady`: never throws, just resolves
|
|
80
|
+
* once ready or once `timeoutMs` elapses, so a frame that never becomes ready
|
|
81
|
+
* degrades to "proceed anyway" rather than hanging the flow.
|
|
82
|
+
*/
|
|
83
|
+
export declare function waitForChildFrameReady(target: FrameTarget, opts?: {
|
|
84
|
+
timeoutMs?: number;
|
|
85
|
+
pollMs?: number;
|
|
86
|
+
}): Promise<void>;
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=frame-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-target.d.ts","sourceRoot":"","sources":["../../src/scraper/frame-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAMrD,kHAAkH;AAClH,KAAK,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,uIAAuI;IACvI,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,wGAAwG;IACxG,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,EACjC,wBAAwB,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EACjE,GAAG,CAAC,EAAE,GAAG,GACR,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,wFAAwF;IACxF,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,6EAA6E;IAC7E,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvB,gMAAgM;IAChM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CASvD;AAoCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,OAAO,CAAC,WAAW,CAAC,CAsBtB;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,aAAa,EAAE,MAAM,GACpB,MAAM,CAOR;AAMD,+FAA+F;AAC/F,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cross-origin frame resolver: the single seam that lets every downstream
|
|
4
|
+
* helper (flow-runner primitives, guarded Stagehand calls) act on either the
|
|
5
|
+
* main frame or a resolved cross-origin OOPIF without knowing which. Some
|
|
6
|
+
* ATS integrations (e.g. UCHealth's Talemetry wizard) embed their entire
|
|
7
|
+
* application form inside a cross-origin `<iframe>` rather than navigating
|
|
8
|
+
* the top window to it, and `document`-rooted helpers (`page.evaluate`,
|
|
9
|
+
* `page.locator`) cannot reach across that boundary — `contentDocument` on a
|
|
10
|
+
* cross-origin iframe element is `null` from page script's perspective.
|
|
11
|
+
* `resolveFrameTarget` finds the child `Frame` Stagehand's CDP layer already
|
|
12
|
+
* attached to and wraps it in a uniform `FrameTarget` surface.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.mainFrameTarget = mainFrameTarget;
|
|
16
|
+
exports.resolveFrameTarget = resolveFrameTarget;
|
|
17
|
+
exports.buildHopSelector = buildHopSelector;
|
|
18
|
+
exports.sleep = sleep;
|
|
19
|
+
exports.waitForChildFrameReady = waitForChildFrameReady;
|
|
20
|
+
const logging_1 = require("../lib/logging");
|
|
21
|
+
const logger = (0, logging_1.getLogger)({ name: "scraper/frame-target" });
|
|
22
|
+
/**
|
|
23
|
+
* Builds the main-frame `FrameTarget`: every method delegates straight to
|
|
24
|
+
* `Page`, matching today's behavior for every site whose ATS form never
|
|
25
|
+
* leaves the top window. Exported so call sites that have not yet resolved
|
|
26
|
+
* a `FrameTarget` from `deps.frameSelector` can still pass a target-shaped
|
|
27
|
+
* value to helpers that now require one.
|
|
28
|
+
*/
|
|
29
|
+
function mainFrameTarget(page) {
|
|
30
|
+
return {
|
|
31
|
+
frame: null,
|
|
32
|
+
frameSelector: null,
|
|
33
|
+
evaluate: (pageFunctionOrExpression, arg) => page.evaluate(pageFunctionOrExpression, arg),
|
|
34
|
+
locator: (selector) => page.locator(selector),
|
|
35
|
+
url: () => Promise.resolve(page.url()),
|
|
36
|
+
title: () => page.title(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Builds a child-frame `FrameTarget`: `evaluate`/`locator` delegate to the
|
|
41
|
+
* resolved `Frame` (reaching across the cross-origin boundary via its own
|
|
42
|
+
* CDP session), while `url`/`title` fall back to the frame's own
|
|
43
|
+
* `location.href` and the top document's title respectively — `Frame` has
|
|
44
|
+
* no `title()` of its own.
|
|
45
|
+
*/
|
|
46
|
+
function childFrameTarget(page, frame, frameSelector) {
|
|
47
|
+
return {
|
|
48
|
+
frame,
|
|
49
|
+
frameSelector,
|
|
50
|
+
evaluate: (pageFunctionOrExpression, arg) => frame.evaluate(pageFunctionOrExpression, arg),
|
|
51
|
+
locator: (selector) => frame.locator(selector),
|
|
52
|
+
url: () => frame.evaluate("location.href"),
|
|
53
|
+
title: () => page.title(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reads the origin (scheme + host) off a URL string, or `null` if it isn't
|
|
58
|
+
* parseable — used to match a candidate `page.frames()` entry against the
|
|
59
|
+
* `<iframe>` element's `src` attribute without requiring an exact URL match
|
|
60
|
+
* (the iframe `src` and the frame's live `location.href` commonly differ by
|
|
61
|
+
* path/query after the child navigates, e.g. an application UUID appended
|
|
62
|
+
* post-load).
|
|
63
|
+
*/
|
|
64
|
+
function originOf(url) {
|
|
65
|
+
try {
|
|
66
|
+
return new URL(url).origin;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolves the `FrameTarget` for `frameSelector` against `page`, falling
|
|
74
|
+
* back to the main-frame target whenever resolution can't confidently
|
|
75
|
+
* succeed rather than throwing:
|
|
76
|
+
*
|
|
77
|
+
* 1. `frameSelector` is `null`/`undefined` → main-frame target (today's
|
|
78
|
+
* behavior, unchanged).
|
|
79
|
+
* 2. No element in the main document matches `frameSelector`, or it isn't
|
|
80
|
+
* an `<iframe>`/has no `src` → main-frame target.
|
|
81
|
+
* 3. No frame in `page.frames()` has an origin matching the `<iframe>`
|
|
82
|
+
* element's `src` → main-frame target.
|
|
83
|
+
* 4. Otherwise → a child-frame target bound to the first matching frame.
|
|
84
|
+
*
|
|
85
|
+
* Step 2 reads the `src` attribute (not `contentDocument`) via `page.evaluate`
|
|
86
|
+
* on the main frame, which stays readable across the cross-origin boundary —
|
|
87
|
+
* only same-origin script access to the child's document is blocked.
|
|
88
|
+
*/
|
|
89
|
+
async function resolveFrameTarget(page, frameSelector) {
|
|
90
|
+
if (!frameSelector)
|
|
91
|
+
return mainFrameTarget(page);
|
|
92
|
+
const iframeSrcExpr = `(() => {
|
|
93
|
+
const el = document.querySelector(${JSON.stringify(frameSelector)});
|
|
94
|
+
if (!el || el.tagName !== "IFRAME") return null;
|
|
95
|
+
return el.getAttribute("src");
|
|
96
|
+
})()`;
|
|
97
|
+
const iframeSrc = await page.evaluate(iframeSrcExpr);
|
|
98
|
+
if (!iframeSrc)
|
|
99
|
+
return mainFrameTarget(page);
|
|
100
|
+
const targetOrigin = originOf(iframeSrc);
|
|
101
|
+
if (!targetOrigin)
|
|
102
|
+
return mainFrameTarget(page);
|
|
103
|
+
const candidates = page.frames();
|
|
104
|
+
for (const candidate of candidates) {
|
|
105
|
+
const candidateUrl = await candidate.evaluate("location.href").catch(() => null);
|
|
106
|
+
if (candidateUrl && originOf(candidateUrl) === targetOrigin) {
|
|
107
|
+
return childFrameTarget(page, candidate, frameSelector);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return mainFrameTarget(page);
|
|
111
|
+
}
|
|
112
|
+
const HOP_SEPARATOR = " >> ";
|
|
113
|
+
/**
|
|
114
|
+
* Composes a Stagehand hop-notation scope string from a frame selector and an
|
|
115
|
+
* inner selector, for callers building `ObserveOptions.selector` /
|
|
116
|
+
* `ExtractOptions.selector` values — kept separate from `FrameTarget` itself
|
|
117
|
+
* so `resolveFrameTarget` keeps receiving only the bare iframe-id hop (the
|
|
118
|
+
* contract `frame-resolve.test.ts` pins) rather than a pre-composed string.
|
|
119
|
+
*/
|
|
120
|
+
function buildHopSelector(frameSelector, innerSelector) {
|
|
121
|
+
if (!frameSelector)
|
|
122
|
+
return innerSelector;
|
|
123
|
+
const trimmedFrameSelector = frameSelector.trimEnd();
|
|
124
|
+
if (trimmedFrameSelector.endsWith(">>")) {
|
|
125
|
+
return `${trimmedFrameSelector} ${innerSelector.trimStart()}`;
|
|
126
|
+
}
|
|
127
|
+
return `${trimmedFrameSelector}${HOP_SEPARATOR}${innerSelector.trimStart()}`;
|
|
128
|
+
}
|
|
129
|
+
/** Readiness-wait defaults — cheap poll, short timeout: an attached-but-not-yet-navigated child frame should settle in well under a second. */
|
|
130
|
+
const FRAME_READY_TIMEOUT_MS = 5_000;
|
|
131
|
+
const FRAME_READY_POLL_MS = 100;
|
|
132
|
+
/** Shared delay helper — `FrameTarget` has no `waitForTimeout` since it isn't frame-scoped. */
|
|
133
|
+
function sleep(ms) {
|
|
134
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Blocks until a resolved child frame has a live document (`document.readyState`
|
|
138
|
+
* is `"interactive"` or `"complete"`), so callers do not observe/act against a
|
|
139
|
+
* frame that CDP has attached to but that has not yet navigated past `about:blank`
|
|
140
|
+
* — the state right after `Target.setAutoAttach` fires and before the OOPIF's own
|
|
141
|
+
* navigation lands. Best-effort like `waitForSpaReady`: never throws, just resolves
|
|
142
|
+
* once ready or once `timeoutMs` elapses, so a frame that never becomes ready
|
|
143
|
+
* degrades to "proceed anyway" rather than hanging the flow.
|
|
144
|
+
*/
|
|
145
|
+
async function waitForChildFrameReady(target, opts = {}) {
|
|
146
|
+
if (!target.frame)
|
|
147
|
+
return;
|
|
148
|
+
const timeoutMs = opts.timeoutMs ?? FRAME_READY_TIMEOUT_MS;
|
|
149
|
+
const pollMs = opts.pollMs ?? FRAME_READY_POLL_MS;
|
|
150
|
+
const isReady = async () => {
|
|
151
|
+
const readyState = await target.evaluate("document.readyState").catch(() => null);
|
|
152
|
+
return readyState === "interactive" || readyState === "complete";
|
|
153
|
+
};
|
|
154
|
+
if (await isReady())
|
|
155
|
+
return;
|
|
156
|
+
const deadline = Date.now() + timeoutMs;
|
|
157
|
+
while (Date.now() < deadline) {
|
|
158
|
+
await sleep(pollMs);
|
|
159
|
+
if (await isReady())
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
logger.warn(`child frame ${target.frameSelector ?? "(unresolved)"} still not ready after ${timeoutMs}ms — proceeding anyway`);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=frame-target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-target.js","sourceRoot":"","sources":["../../src/scraper/frame-target.ts"],"names":[],"mappings":"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"}
|
package/dist/scraper/retry.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export interface RetryOptions {
|
|
|
16
16
|
* Wraps a scraper task with p-retry and a classification policy aligned
|
|
17
17
|
* with our ScraperError hierarchy:
|
|
18
18
|
*
|
|
19
|
-
* - CaptchaError + EmptyResultsError → AbortError, no retry.
|
|
20
|
-
* - SessionTimeoutError → invoke onSessionRestart
|
|
19
|
+
* - CaptchaError + EmptyResultsError + StepVerificationError → AbortError, no retry.
|
|
20
|
+
* - SessionTimeoutError → invoke onSessionRestart before every retry, then retry up to maxAttempts.
|
|
21
21
|
* - SelectorFailureError + UnknownScraperError → retry up to maxAttempts.
|
|
22
22
|
* - Anything non-ScraperError → wrap in UnknownScraperError and retry.
|
|
23
23
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,YAAY,
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,YAAY,EAKb,MAAM,kBAAkB,CAAC;AAI1B;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAoDZ;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAmB/D"}
|
package/dist/scraper/retry.js
CHANGED
|
@@ -44,8 +44,8 @@ const logger = (0, logging_1.getLogger)({ name: "scraper/retry" });
|
|
|
44
44
|
* Wraps a scraper task with p-retry and a classification policy aligned
|
|
45
45
|
* with our ScraperError hierarchy:
|
|
46
46
|
*
|
|
47
|
-
* - CaptchaError + EmptyResultsError → AbortError, no retry.
|
|
48
|
-
* - SessionTimeoutError → invoke onSessionRestart
|
|
47
|
+
* - CaptchaError + EmptyResultsError + StepVerificationError → AbortError, no retry.
|
|
48
|
+
* - SessionTimeoutError → invoke onSessionRestart before every retry, then retry up to maxAttempts.
|
|
49
49
|
* - SelectorFailureError + UnknownScraperError → retry up to maxAttempts.
|
|
50
50
|
* - Anything non-ScraperError → wrap in UnknownScraperError and retry.
|
|
51
51
|
*
|
|
@@ -54,7 +54,6 @@ const logger = (0, logging_1.getLogger)({ name: "scraper/retry" });
|
|
|
54
54
|
*/
|
|
55
55
|
async function withScraperRetry(task, options = {}) {
|
|
56
56
|
const maxAttempts = options.maxAttempts ?? 3;
|
|
57
|
-
const sessionRestartEntry = { done: false };
|
|
58
57
|
return (0, p_retry_1.default)(async () => {
|
|
59
58
|
try {
|
|
60
59
|
return await task();
|
|
@@ -72,11 +71,12 @@ async function withScraperRetry(task, options = {}) {
|
|
|
72
71
|
logger.warn(`scraper returned empty results — aborting retry: ${err.message}`);
|
|
73
72
|
throw new p_retry_1.AbortError(err.message);
|
|
74
73
|
}
|
|
75
|
-
if (err instanceof errors_2.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if (err instanceof errors_2.StepVerificationError) {
|
|
75
|
+
logger.warn(`step verification failed deterministically — aborting retry: ${err.message}`);
|
|
76
|
+
throw new p_retry_1.AbortError(err.message);
|
|
77
|
+
}
|
|
78
|
+
if (err instanceof errors_2.SessionTimeoutError && options.onSessionRestart) {
|
|
79
|
+
await options.onSessionRestart();
|
|
80
80
|
}
|
|
81
81
|
throw err;
|
|
82
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA6C;AAE7C,yCAA8C;AAC9C,2CAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/scraper/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
import type { Action, ActOptions, ActResult, ExtractOptions, ObserveOptions, Stagehand } from "@browserbasehq/stagehand";
|
|
40
40
|
import { z } from "zod/v4";
|
|
41
41
|
import { type LlmCallInput } from "../lib/telemetry/call-capture";
|
|
42
|
+
import { type FrameTarget } from "../scraper/frame-target";
|
|
42
43
|
/**
|
|
43
44
|
* Injectable capture function — matches `captureLlmCall`'s signature. Same
|
|
44
45
|
* shape as `JudgeCaptureFn` in `@/lib/llm/judge`. Lets each guard call route
|
|
@@ -109,20 +110,47 @@ export declare class StagehandSchemaError extends Error {
|
|
|
109
110
|
* `Action` (from a prior `observe`). On the happy path, returns Stagehand's
|
|
110
111
|
* `ActResult` verbatim. On envelope drift, throws `StagehandSchemaError`
|
|
111
112
|
* and logs `failureKind: "schema-validation-failed"`.
|
|
113
|
+
*
|
|
114
|
+
* Accepts the same trailing `frameTarget` param as `guardedObserve`/
|
|
115
|
+
* `guardedExtract` for signature symmetry, but does not forward it into
|
|
116
|
+
* `ActOptions` — `ActOptions` has no `selector` field, and its `page`
|
|
117
|
+
* override only accepts a full Playwright/Puppeteer/Patchright/understudy
|
|
118
|
+
* `Page`, not the `Frame` handle `FrameTarget.frame` exposes (the
|
|
119
|
+
* understudy `Page` constructor is private, so there is no way to
|
|
120
|
+
* synthesize a frame-scoped `Page`). Scope `act` at the call site instead:
|
|
121
|
+
* pair a frame-scoped `guardedObserve` (whose returned `Action.selector`
|
|
122
|
+
* already targets the resolved frame's DOM) with `guardedAct` called on
|
|
123
|
+
* that `Action` — the `observe(...)[0] -> act(target)` pattern already used
|
|
124
|
+
* throughout `flow-runner.ts`.
|
|
112
125
|
*/
|
|
113
|
-
export declare function guardedAct(stagehand: Stagehand, input: string | Action, options?: ActOptions, captureFn?: StagehandCaptureFn): Promise<ActResult>;
|
|
126
|
+
export declare function guardedAct(stagehand: Stagehand, input: string | Action, options?: ActOptions, captureFn?: StagehandCaptureFn, _frameTarget?: FrameTarget): Promise<ActResult>;
|
|
114
127
|
/**
|
|
115
128
|
* Schema-guarded wrapper around Stagehand's `observe`. Mirrors the
|
|
116
129
|
* Stagehand overloads: no args, options-only, instruction-only,
|
|
117
130
|
* instruction + options. On envelope drift (the `Action[]` shape changes),
|
|
118
131
|
* throws `StagehandSchemaError`.
|
|
132
|
+
*
|
|
133
|
+
* When `frameTarget` resolves to a cross-origin child frame, its
|
|
134
|
+
* `frameSelector` is merged into `ObserveOptions.selector` so Stagehand's
|
|
135
|
+
* snapshot/candidate search is scoped to that frame's DOM instead of only
|
|
136
|
+
* the top frame. A caller-supplied `options.selector` wins over
|
|
137
|
+
* `frameTarget.frameSelector` — the caller made an explicit choice. The
|
|
138
|
+
* main-frame target (`frameTarget` omitted, or its `frameSelector` is
|
|
139
|
+
* `null`) leaves `options` untouched, so every existing call site is
|
|
140
|
+
* byte-identical to today.
|
|
119
141
|
*/
|
|
120
|
-
export declare function guardedObserve(stagehand: Stagehand, instruction?: string, options?: ObserveOptions, captureFn?: StagehandCaptureFn): Promise<Action[]>;
|
|
142
|
+
export declare function guardedObserve(stagehand: Stagehand, instruction?: string, options?: ObserveOptions, captureFn?: StagehandCaptureFn, frameTarget?: FrameTarget): Promise<Action[]>;
|
|
121
143
|
/**
|
|
122
144
|
* Schema-guarded wrapper around Stagehand's `extract` 3-arg overload. The
|
|
123
145
|
* caller's Zod schema is what Stagehand asks the LLM to satisfy AND what we
|
|
124
146
|
* `safeParse` against caller-side. Refuse the 1-arg / 2-arg defaults; every
|
|
125
147
|
* extract call in the codebase must enforce a schema.
|
|
148
|
+
*
|
|
149
|
+
* When `frameTarget` resolves to a cross-origin child frame, its
|
|
150
|
+
* `frameSelector` is merged into `ExtractOptions.selector` so Stagehand
|
|
151
|
+
* extracts from that frame's DOM instead of only the top frame. A
|
|
152
|
+
* caller-supplied `options.selector` wins over `frameTarget.frameSelector`.
|
|
153
|
+
* The main-frame target leaves `options` untouched.
|
|
126
154
|
*/
|
|
127
|
-
export declare function guardedExtract<T extends z.ZodTypeAny>(stagehand: Stagehand, instruction: string, schema: T, options?: ExtractOptions, captureFn?: StagehandCaptureFn): Promise<z.infer<T>>;
|
|
155
|
+
export declare function guardedExtract<T extends z.ZodTypeAny>(stagehand: Stagehand, instruction: string, schema: T, options?: ExtractOptions, captureFn?: StagehandCaptureFn, frameTarget?: FrameTarget): Promise<z.infer<T>>;
|
|
128
156
|
//# sourceMappingURL=stagehand-guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stagehand-guard.d.ts","sourceRoot":"","sources":["../../src/scraper/stagehand-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,SAAS,EACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"stagehand-guard.d.ts","sourceRoot":"","sources":["../../src/scraper/stagehand-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,SAAS,EACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAExE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,aAAa;;;;;iBAKxB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;iBAM5B,CAAC;AAEH;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAG,0BAA0B,CAAU;IACpD,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B,YACE,SAAS,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,EACxC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EACpB,WAAW,EAAE,OAAO,EAOrB;CACF;AAwCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,CAAC,EAAE,UAAU,EACpB,SAAS,CAAC,EAAE,kBAAkB,EAC9B,YAAY,CAAC,EAAE,WAAW,GACzB,OAAO,CAAC,SAAS,CAAC,CAqEpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,cAAc,EACxB,SAAS,CAAC,EAAE,kBAAkB,EAC9B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAmEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACzD,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,cAAc,EACxB,SAAS,CAAC,EAAE,kBAAkB,EAC9B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAsErB"}
|
|
@@ -46,6 +46,7 @@ const node_crypto_1 = require("node:crypto");
|
|
|
46
46
|
const v4_1 = require("zod/v4");
|
|
47
47
|
const call_capture_1 = require("../lib/telemetry/call-capture");
|
|
48
48
|
const call_types_1 = require("../lib/telemetry/call-types");
|
|
49
|
+
const frame_target_1 = require("../scraper/frame-target");
|
|
49
50
|
/**
|
|
50
51
|
* Zod mirror of Stagehand's public `Action` shape (from
|
|
51
52
|
* `@browserbasehq/stagehand/.../public/methods.d.ts`):
|
|
@@ -118,14 +119,43 @@ function safeStringify(value, cap = 4000) {
|
|
|
118
119
|
function actInstructionOf(input) {
|
|
119
120
|
return typeof input === "string" ? input : input.description;
|
|
120
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Merges `frameTarget.frameSelector` into `options.selector` for
|
|
124
|
+
* `ObserveOptions`/`ExtractOptions`, composed as Stagehand `">>"` hop
|
|
125
|
+
* notation (`buildHopSelector`) rather than the bare iframe selector —
|
|
126
|
+
* `resolveCssFocusFrameAndTail` only crosses into the child frame's own CDP
|
|
127
|
+
* session when the selector has a hop segment before `>>`; a bare selector
|
|
128
|
+
* performs zero hops and scopes to the (empty) `<iframe>` element itself.
|
|
129
|
+
* The inner segment defaults to `*` (whole-frame scope) since callers don't
|
|
130
|
+
* supply one here. Returns `options` untouched when `frameTarget` is
|
|
131
|
+
* unresolved (main frame) or a caller-supplied `selector` is already
|
|
132
|
+
* present — both cases must leave today's call sites byte-identical.
|
|
133
|
+
*/
|
|
134
|
+
function frameScopedOptions(options, frameTarget) {
|
|
135
|
+
if (!frameTarget?.frameSelector || options?.selector !== undefined)
|
|
136
|
+
return options;
|
|
137
|
+
return { ...options, selector: (0, frame_target_1.buildHopSelector)(frameTarget.frameSelector, "*") };
|
|
138
|
+
}
|
|
121
139
|
/**
|
|
122
140
|
* Schema-guarded wrapper around Stagehand's `act`. Same signature as the
|
|
123
141
|
* underlying call: accepts either an instruction string or a structured
|
|
124
142
|
* `Action` (from a prior `observe`). On the happy path, returns Stagehand's
|
|
125
143
|
* `ActResult` verbatim. On envelope drift, throws `StagehandSchemaError`
|
|
126
144
|
* and logs `failureKind: "schema-validation-failed"`.
|
|
145
|
+
*
|
|
146
|
+
* Accepts the same trailing `frameTarget` param as `guardedObserve`/
|
|
147
|
+
* `guardedExtract` for signature symmetry, but does not forward it into
|
|
148
|
+
* `ActOptions` — `ActOptions` has no `selector` field, and its `page`
|
|
149
|
+
* override only accepts a full Playwright/Puppeteer/Patchright/understudy
|
|
150
|
+
* `Page`, not the `Frame` handle `FrameTarget.frame` exposes (the
|
|
151
|
+
* understudy `Page` constructor is private, so there is no way to
|
|
152
|
+
* synthesize a frame-scoped `Page`). Scope `act` at the call site instead:
|
|
153
|
+
* pair a frame-scoped `guardedObserve` (whose returned `Action.selector`
|
|
154
|
+
* already targets the resolved frame's DOM) with `guardedAct` called on
|
|
155
|
+
* that `Action` — the `observe(...)[0] -> act(target)` pattern already used
|
|
156
|
+
* throughout `flow-runner.ts`.
|
|
127
157
|
*/
|
|
128
|
-
async function guardedAct(stagehand, input, options, captureFn) {
|
|
158
|
+
async function guardedAct(stagehand, input, options, captureFn, _frameTarget) {
|
|
129
159
|
const callId = (0, node_crypto_1.randomUUID)();
|
|
130
160
|
const userContent = actInstructionOf(input);
|
|
131
161
|
const t0 = performance.now();
|
|
@@ -192,19 +222,29 @@ async function guardedAct(stagehand, input, options, captureFn) {
|
|
|
192
222
|
* Stagehand overloads: no args, options-only, instruction-only,
|
|
193
223
|
* instruction + options. On envelope drift (the `Action[]` shape changes),
|
|
194
224
|
* throws `StagehandSchemaError`.
|
|
225
|
+
*
|
|
226
|
+
* When `frameTarget` resolves to a cross-origin child frame, its
|
|
227
|
+
* `frameSelector` is merged into `ObserveOptions.selector` so Stagehand's
|
|
228
|
+
* snapshot/candidate search is scoped to that frame's DOM instead of only
|
|
229
|
+
* the top frame. A caller-supplied `options.selector` wins over
|
|
230
|
+
* `frameTarget.frameSelector` — the caller made an explicit choice. The
|
|
231
|
+
* main-frame target (`frameTarget` omitted, or its `frameSelector` is
|
|
232
|
+
* `null`) leaves `options` untouched, so every existing call site is
|
|
233
|
+
* byte-identical to today.
|
|
195
234
|
*/
|
|
196
|
-
async function guardedObserve(stagehand, instruction, options, captureFn) {
|
|
235
|
+
async function guardedObserve(stagehand, instruction, options, captureFn, frameTarget) {
|
|
197
236
|
const callId = (0, node_crypto_1.randomUUID)();
|
|
198
237
|
const userContent = instruction ?? "";
|
|
199
238
|
const t0 = performance.now();
|
|
239
|
+
const scopedOptions = frameScopedOptions(options, frameTarget);
|
|
200
240
|
try {
|
|
201
241
|
// Match Stagehand's overloads: pass instruction only when defined, so
|
|
202
242
|
// the SDK falls through to its no-arg/options-only path otherwise.
|
|
203
243
|
const raw = instruction === undefined
|
|
204
|
-
?
|
|
244
|
+
? scopedOptions === undefined
|
|
205
245
|
? await stagehand.observe()
|
|
206
|
-
: await stagehand.observe(
|
|
207
|
-
: await stagehand.observe(instruction,
|
|
246
|
+
: await stagehand.observe(scopedOptions)
|
|
247
|
+
: await stagehand.observe(instruction, scopedOptions);
|
|
208
248
|
const latencyMs = performance.now() - t0;
|
|
209
249
|
const parsed = v4_1.z.array(exports.ACTION_SCHEMA).safeParse(raw);
|
|
210
250
|
if (!parsed.success) {
|
|
@@ -257,8 +297,14 @@ async function guardedObserve(stagehand, instruction, options, captureFn) {
|
|
|
257
297
|
* caller's Zod schema is what Stagehand asks the LLM to satisfy AND what we
|
|
258
298
|
* `safeParse` against caller-side. Refuse the 1-arg / 2-arg defaults; every
|
|
259
299
|
* extract call in the codebase must enforce a schema.
|
|
300
|
+
*
|
|
301
|
+
* When `frameTarget` resolves to a cross-origin child frame, its
|
|
302
|
+
* `frameSelector` is merged into `ExtractOptions.selector` so Stagehand
|
|
303
|
+
* extracts from that frame's DOM instead of only the top frame. A
|
|
304
|
+
* caller-supplied `options.selector` wins over `frameTarget.frameSelector`.
|
|
305
|
+
* The main-frame target leaves `options` untouched.
|
|
260
306
|
*/
|
|
261
|
-
async function guardedExtract(stagehand, instruction, schema, options, captureFn) {
|
|
307
|
+
async function guardedExtract(stagehand, instruction, schema, options, captureFn, frameTarget) {
|
|
262
308
|
const callId = (0, node_crypto_1.randomUUID)();
|
|
263
309
|
const t0 = performance.now();
|
|
264
310
|
try {
|
|
@@ -270,7 +316,7 @@ async function guardedExtract(stagehand, instruction, schema, options, captureFn
|
|
|
270
316
|
// the cleanest public-API way to express "whatever overload-2 expects."
|
|
271
317
|
// The `as unknown` step is needed because TS won't accept a single
|
|
272
318
|
// direct cast across the entire overload set.
|
|
273
|
-
const raw = await stagehand.extract(instruction, schema, options);
|
|
319
|
+
const raw = await stagehand.extract(instruction, schema, frameScopedOptions(options, frameTarget));
|
|
274
320
|
const latencyMs = performance.now() - t0;
|
|
275
321
|
const parsed = schema.safeParse(raw);
|
|
276
322
|
if (!parsed.success) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stagehand-guard.js","sourceRoot":"","sources":["../../src/scraper/stagehand-guard.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;;;;;;AAEH,6CAAyC;AAUzC,+BAA2B;AAE3B,+DAIsC;AACtC,2DAIoC;
|
|
1
|
+
{"version":3,"file":"stagehand-guard.js","sourceRoot":"","sources":["../../src/scraper/stagehand-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,8 +22,16 @@
|
|
|
22
22
|
* re-runs the identical traversal and clicks the element at that index, so
|
|
23
23
|
* the caller can locate once, decide which candidate to try, then click by
|
|
24
24
|
* index without holding a live element handle across the two round trips.
|
|
25
|
+
*
|
|
26
|
+
* `root` overrides the traversal root expression (default `"document"`),
|
|
27
|
+
* interpolated verbatim into the generated code so a caller evaluating
|
|
28
|
+
* this expression via `Frame.evaluate` can pass `"document"` and still
|
|
29
|
+
* resolve that frame's own document — the expression never captures an
|
|
30
|
+
* outer `document` reference. {@link buildClickByDeepIndexExpr} must be
|
|
31
|
+
* given the same `root` so its re-run traversal produces the same
|
|
32
|
+
* `deepIndex` ordering as the one this call returned.
|
|
25
33
|
*/
|
|
26
|
-
export declare function buildRankSubmitCandidatesExpr(): string;
|
|
34
|
+
export declare function buildRankSubmitCandidatesExpr(root?: string): string;
|
|
27
35
|
/**
|
|
28
36
|
* Builds a self-contained `page.evaluate` expression string that re-runs
|
|
29
37
|
* the same deterministic deep traversal as {@link buildRankSubmitCandidatesExpr}
|
|
@@ -32,8 +40,13 @@ export declare function buildRankSubmitCandidatesExpr(): string;
|
|
|
32
40
|
* convention). Returns `{ clicked: false }` without throwing if the index is
|
|
33
41
|
* out of range for the current DOM (e.g. the page changed between the
|
|
34
42
|
* locate and click calls).
|
|
43
|
+
*
|
|
44
|
+
* `root` overrides the traversal root expression (default `"document"`)
|
|
45
|
+
* and must match the `root` passed to the {@link buildRankSubmitCandidatesExpr}
|
|
46
|
+
* call that produced `deepIndex`, or the re-run traversal order will not
|
|
47
|
+
* line up with the original ranking.
|
|
35
48
|
*/
|
|
36
|
-
export declare function buildClickByDeepIndexExpr(deepIndex: number): string;
|
|
49
|
+
export declare function buildClickByDeepIndexExpr(deepIndex: number, root?: string): string;
|
|
37
50
|
/** Confidence tier for a ranked submit candidate — higher is more confident. See {@link buildRankSubmitCandidatesExpr}. */
|
|
38
51
|
export type SubmitCandidateTier = 1 | 2 | 3;
|
|
39
52
|
/** One ranked candidate returned by {@link buildRankSubmitCandidatesExpr}'s `page.evaluate` call. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-control.d.ts","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyEH
|
|
1
|
+
{"version":3,"file":"submit-control.d.ts","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,SAAa,GAAG,MAAM,CAsBvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,SAAa,GAAG,MAAM,CAYtF;AAED,2HAA2H;AAC3H,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE5C,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC9B,mIAAmI;IACnI,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB"}
|