@opensteer/engine-abp 0.8.1 → 0.8.3

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/index.cjs CHANGED
@@ -1259,6 +1259,282 @@ function sleep(ms) {
1259
1259
  return new Promise((resolve) => setTimeout(resolve, ms));
1260
1260
  }
1261
1261
 
1262
+ // ../browser-core/src/post-load-tracker.ts
1263
+ var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
1264
+ var DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS = 100;
1265
+ function isRecord(value) {
1266
+ return typeof value === "object" && value !== null;
1267
+ }
1268
+ function readFiniteNumber(value) {
1269
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1270
+ }
1271
+ function readNonNegativeNumber(value) {
1272
+ const parsed = readFiniteNumber(value);
1273
+ return parsed === void 0 || parsed < 0 ? 0 : parsed;
1274
+ }
1275
+ function normalizePostLoadTrackerState(value) {
1276
+ if (!isRecord(value)) {
1277
+ return void 0;
1278
+ }
1279
+ const installedAt = readFiniteNumber(value.installedAt);
1280
+ const lastMutationAt = readFiniteNumber(value.lastMutationAt);
1281
+ const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
1282
+ const now = readFiniteNumber(value.now);
1283
+ const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
1284
+ if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
1285
+ return void 0;
1286
+ }
1287
+ return {
1288
+ installedAt,
1289
+ lastMutationAt,
1290
+ lastNetworkActivityAt,
1291
+ now,
1292
+ pendingFetches: readNonNegativeNumber(value.pendingFetches),
1293
+ pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
1294
+ pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
1295
+ readyState
1296
+ };
1297
+ }
1298
+ function buildPostLoadTrackerInstallScript() {
1299
+ return `(() => {
1300
+ const globalObject = globalThis;
1301
+ if (globalObject.__opensteerActionBoundaryTrackerInstalled) {
1302
+ return true;
1303
+ }
1304
+
1305
+ const tracker = {
1306
+ installedAt: performance.now(),
1307
+ lastMutationAt: performance.now(),
1308
+ lastNetworkActivityAt: performance.now(),
1309
+ pendingFetches: 0,
1310
+ pendingTimeouts: 0,
1311
+ pendingXhrs: 0,
1312
+ readyState: document.readyState,
1313
+ timeoutIds: new Set(),
1314
+ };
1315
+ globalObject.__opensteerActionBoundaryTrackerInstalled = true;
1316
+ globalObject.__opensteerActionBoundaryTracker = tracker;
1317
+
1318
+ const markMutation = () => {
1319
+ tracker.lastMutationAt = performance.now();
1320
+ tracker.readyState = document.readyState;
1321
+ };
1322
+ const markNetwork = () => {
1323
+ tracker.lastNetworkActivityAt = performance.now();
1324
+ tracker.readyState = document.readyState;
1325
+ };
1326
+
1327
+ const startObserver = () => {
1328
+ const target = document.documentElement ?? document;
1329
+ if (!(target instanceof Node)) {
1330
+ return;
1331
+ }
1332
+ const observer = new MutationObserver(markMutation);
1333
+ observer.observe(target, {
1334
+ subtree: true,
1335
+ childList: true,
1336
+ characterData: true,
1337
+ attributes: true,
1338
+ });
1339
+ markMutation();
1340
+ };
1341
+
1342
+ if (document.documentElement) {
1343
+ startObserver();
1344
+ } else {
1345
+ document.addEventListener("DOMContentLoaded", startObserver, { once: true });
1346
+ }
1347
+
1348
+ document.addEventListener("readystatechange", markMutation);
1349
+ addEventListener("load", markMutation, { once: true });
1350
+
1351
+ const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
1352
+ const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
1353
+ globalObject.setTimeout = function(callback, delay, ...args) {
1354
+ tracker.pendingTimeouts += 1;
1355
+ markNetwork();
1356
+ let handle;
1357
+ const wrapped =
1358
+ typeof callback === "function"
1359
+ ? (...callbackArgs) => {
1360
+ if (tracker.timeoutIds.delete(handle)) {
1361
+ tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1362
+ }
1363
+ try {
1364
+ return callback(...callbackArgs);
1365
+ } finally {
1366
+ markMutation();
1367
+ }
1368
+ }
1369
+ : callback;
1370
+ handle = nativeSetTimeout(wrapped, delay, ...args);
1371
+ tracker.timeoutIds.add(handle);
1372
+ return handle;
1373
+ };
1374
+ globalObject.clearTimeout = function(handle) {
1375
+ if (tracker.timeoutIds.delete(handle)) {
1376
+ tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1377
+ }
1378
+ return nativeClearTimeout(handle);
1379
+ };
1380
+
1381
+ if (typeof globalObject.fetch === "function") {
1382
+ const nativeFetch = globalObject.fetch.bind(globalObject);
1383
+ globalObject.fetch = (...args) => {
1384
+ tracker.pendingFetches += 1;
1385
+ markNetwork();
1386
+ return nativeFetch(...args)
1387
+ .finally(() => {
1388
+ tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
1389
+ markNetwork();
1390
+ });
1391
+ };
1392
+ }
1393
+
1394
+ if (typeof globalObject.XMLHttpRequest === "function") {
1395
+ const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
1396
+ const nativeSend = NativeXMLHttpRequest.prototype.send;
1397
+ NativeXMLHttpRequest.prototype.send = function(...args) {
1398
+ tracker.pendingXhrs += 1;
1399
+ markNetwork();
1400
+ const finalize = () => {
1401
+ this.removeEventListener("loadend", finalize);
1402
+ tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
1403
+ markNetwork();
1404
+ };
1405
+ this.addEventListener("loadend", finalize, { once: true });
1406
+ return nativeSend.apply(this, args);
1407
+ };
1408
+ }
1409
+
1410
+ return true;
1411
+ })()`;
1412
+ }
1413
+ function buildPostLoadTrackerReadExpression() {
1414
+ return `(() => {
1415
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
1416
+ if (!tracker) {
1417
+ return null;
1418
+ }
1419
+
1420
+ return {
1421
+ installedAt: Number(tracker.installedAt ?? 0),
1422
+ lastMutationAt: Number(tracker.lastMutationAt ?? 0),
1423
+ lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
1424
+ now: Number(performance.now()),
1425
+ pendingFetches: Number(tracker.pendingFetches ?? 0),
1426
+ pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
1427
+ pendingXhrs: Number(tracker.pendingXhrs ?? 0),
1428
+ readyState: String(document.readyState),
1429
+ };
1430
+ })()`;
1431
+ }
1432
+ function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
1433
+ if (!tracker) {
1434
+ return false;
1435
+ }
1436
+ if (tracker.readyState !== "complete") {
1437
+ return false;
1438
+ }
1439
+ if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
1440
+ return false;
1441
+ }
1442
+ const lastActivityAt = Math.max(
1443
+ tracker.installedAt,
1444
+ tracker.lastMutationAt,
1445
+ tracker.lastNetworkActivityAt
1446
+ );
1447
+ return tracker.now - lastActivityAt >= quietWindowMs;
1448
+ }
1449
+
1450
+ // ../browser-core/src/action-boundary.ts
1451
+ var CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS = 3e4;
1452
+ var CROSS_DOCUMENT_DETECTION_WINDOW_MS = 500;
1453
+ async function waitForActionBoundary(input) {
1454
+ if (input.timeoutMs <= 0) {
1455
+ return {
1456
+ trigger: "dom-action",
1457
+ crossDocument: false,
1458
+ bootstrapSettled: false,
1459
+ timedOutPhase: "bootstrap"
1460
+ };
1461
+ }
1462
+ const deadline = Date.now() + input.timeoutMs;
1463
+ const crossDocumentDetectionDeadline = input.snapshot === void 0 ? void 0 : Math.min(deadline, Date.now() + CROSS_DOCUMENT_DETECTION_WINDOW_MS);
1464
+ const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
1465
+ let trigger = "dom-action";
1466
+ let crossDocument = false;
1467
+ let waitedForNavigationContentLoaded = false;
1468
+ while (Date.now() < deadline) {
1469
+ input.throwBackgroundError();
1470
+ if (input.isPageClosed()) {
1471
+ return {
1472
+ trigger,
1473
+ crossDocument,
1474
+ bootstrapSettled: true
1475
+ };
1476
+ }
1477
+ if (input.signal?.aborted) {
1478
+ if (isTimeoutAbort(input.signal.reason) && Date.now() >= deadline) {
1479
+ return {
1480
+ trigger,
1481
+ crossDocument,
1482
+ bootstrapSettled: false,
1483
+ timedOutPhase: "bootstrap"
1484
+ };
1485
+ }
1486
+ throw abortError(input.signal);
1487
+ }
1488
+ const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
1489
+ if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
1490
+ trigger = "navigation";
1491
+ crossDocument = true;
1492
+ if (!waitedForNavigationContentLoaded) {
1493
+ waitedForNavigationContentLoaded = true;
1494
+ const remaining = Math.max(0, deadline - Date.now());
1495
+ if (remaining > 0) {
1496
+ await input.waitForNavigationContentLoaded(remaining);
1497
+ }
1498
+ }
1499
+ }
1500
+ if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
1501
+ return {
1502
+ trigger,
1503
+ crossDocument,
1504
+ bootstrapSettled: true
1505
+ };
1506
+ }
1507
+ if (crossDocument && postLoadTrackerIsSettled(await input.readTrackerState())) {
1508
+ return {
1509
+ trigger,
1510
+ crossDocument,
1511
+ bootstrapSettled: true
1512
+ };
1513
+ }
1514
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
1515
+ }
1516
+ return {
1517
+ trigger,
1518
+ crossDocument,
1519
+ bootstrapSettled: false,
1520
+ timedOutPhase: "bootstrap"
1521
+ };
1522
+ }
1523
+ function abortError(signal) {
1524
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
1525
+ }
1526
+ async function delay(ms) {
1527
+ if (ms <= 0) {
1528
+ return;
1529
+ }
1530
+ await new Promise((resolve) => {
1531
+ setTimeout(resolve, ms);
1532
+ });
1533
+ }
1534
+ function isTimeoutAbort(reason) {
1535
+ return typeof reason === "object" && reason !== null && "code" in reason && reason.code === "timeout";
1536
+ }
1537
+
1262
1538
  // ../protocol/src/computer-use-bridge.ts
1263
1539
  var OPENSTEER_COMPUTER_USE_BRIDGE_SYMBOL = /* @__PURE__ */ Symbol.for("@opensteer/computer-use-bridge");
1264
1540
 
@@ -1893,7 +2169,7 @@ async function waitForReady(baseUrl) {
1893
2169
  }
1894
2170
  } catch {
1895
2171
  }
1896
- await delay(200);
2172
+ await delay2(200);
1897
2173
  }
1898
2174
  throw createBrowserCoreError("timeout", `ABP did not become ready within 30000ms at ${baseUrl}`);
1899
2175
  }
@@ -1910,19 +2186,19 @@ async function waitForDevToolsPort(userDataDir) {
1910
2186
  }
1911
2187
  } catch {
1912
2188
  }
1913
- await delay(200);
2189
+ await delay2(200);
1914
2190
  }
1915
2191
  throw createBrowserCoreError(
1916
2192
  "timeout",
1917
2193
  `CDP port file was not written to ${userDataDir} within 30000ms`
1918
2194
  );
1919
2195
  }
1920
- function delay(ms) {
2196
+ function delay2(ms) {
1921
2197
  return new Promise((resolve) => setTimeout(resolve, ms));
1922
2198
  }
1923
2199
 
1924
2200
  // src/action-events.ts
1925
- function isRecord(value) {
2201
+ function isRecord2(value) {
1926
2202
  return typeof value === "object" && value !== null;
1927
2203
  }
1928
2204
  function readBoolean(value) {
@@ -1935,7 +2211,7 @@ function readString(value) {
1935
2211
  return typeof value === "string" ? value : void 0;
1936
2212
  }
1937
2213
  function parseSelectPopupItem(value) {
1938
- if (!isRecord(value)) {
2214
+ if (!isRecord2(value)) {
1939
2215
  return void 0;
1940
2216
  }
1941
2217
  const index = readInteger(value.index);
@@ -1994,225 +2270,19 @@ function normalizeSelectChooserEventData(data) {
1994
2270
  }
1995
2271
 
1996
2272
  // src/action-settle.ts
1997
- var DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS = 5e3;
1998
- var POST_ACTION_SETTLE_QUIET_WINDOW_MS = 400;
1999
- var POST_ACTION_SETTLE_POLL_INTERVAL_MS = 100;
2273
+ var DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS = CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS;
2000
2274
  function clampAbpActionSettleTimeout(timeoutMs) {
2001
2275
  if (timeoutMs === void 0) {
2002
2276
  return DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS;
2003
2277
  }
2004
2278
  return Math.max(0, Math.min(DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS, timeoutMs));
2005
2279
  }
2006
- function isRecord2(value) {
2007
- return typeof value === "object" && value !== null;
2008
- }
2009
- function readFiniteNumber(value) {
2010
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
2011
- }
2012
- function readNonNegativeNumber(value) {
2013
- const parsed = readFiniteNumber(value);
2014
- return parsed === void 0 || parsed < 0 ? 0 : parsed;
2015
- }
2016
- function normalizeAbpSettleTrackerState(value) {
2017
- if (!isRecord2(value)) {
2018
- return void 0;
2019
- }
2020
- const installedAt = readFiniteNumber(value.installedAt);
2021
- const lastMutationAt = readFiniteNumber(value.lastMutationAt);
2022
- const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
2023
- const now = readFiniteNumber(value.now);
2024
- const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
2025
- if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
2026
- return void 0;
2027
- }
2028
- return {
2029
- installedAt,
2030
- lastMutationAt,
2031
- lastNetworkActivityAt,
2032
- now,
2033
- pendingFetches: readNonNegativeNumber(value.pendingFetches),
2034
- pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
2035
- pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
2036
- readyState
2037
- };
2038
- }
2039
- function buildAbpSettleTrackerInstallScript() {
2040
- return `(() => {
2041
- const globalObject = globalThis;
2042
- if (globalObject.__opensteerAbpSettleTrackerInstalled) {
2043
- return true;
2044
- }
2045
-
2046
- const tracker = {
2047
- installedAt: performance.now(),
2048
- lastMutationAt: performance.now(),
2049
- lastNetworkActivityAt: performance.now(),
2050
- pendingFetches: 0,
2051
- pendingTimeouts: 0,
2052
- pendingXhrs: 0,
2053
- readyState: document.readyState,
2054
- timeoutIds: new Set(),
2055
- };
2056
- globalObject.__opensteerAbpSettleTrackerInstalled = true;
2057
- globalObject.__opensteerAbpSettleTracker = tracker;
2058
-
2059
- const markMutation = () => {
2060
- tracker.lastMutationAt = performance.now();
2061
- tracker.readyState = document.readyState;
2062
- };
2063
- const markNetwork = () => {
2064
- tracker.lastNetworkActivityAt = performance.now();
2065
- tracker.readyState = document.readyState;
2066
- };
2067
-
2068
- const startObserver = () => {
2069
- const target = document.documentElement ?? document;
2070
- if (!(target instanceof Node)) {
2071
- return;
2072
- }
2073
- const observer = new MutationObserver(markMutation);
2074
- observer.observe(target, {
2075
- subtree: true,
2076
- childList: true,
2077
- characterData: true,
2078
- attributes: true,
2079
- });
2080
- markMutation();
2081
- };
2082
-
2083
- if (document.documentElement) {
2084
- startObserver();
2085
- } else {
2086
- document.addEventListener("DOMContentLoaded", startObserver, { once: true });
2087
- }
2088
-
2089
- document.addEventListener("readystatechange", markMutation);
2090
- addEventListener("load", markMutation, { once: true });
2091
-
2092
- const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
2093
- const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
2094
- globalObject.setTimeout = function(callback, delay, ...args) {
2095
- tracker.pendingTimeouts += 1;
2096
- markNetwork();
2097
- let handle;
2098
- const wrapped =
2099
- typeof callback === "function"
2100
- ? (...callbackArgs) => {
2101
- if (tracker.timeoutIds.delete(handle)) {
2102
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2103
- }
2104
- try {
2105
- return callback(...callbackArgs);
2106
- } finally {
2107
- markMutation();
2108
- }
2109
- }
2110
- : callback;
2111
- handle = nativeSetTimeout(wrapped, delay, ...args);
2112
- tracker.timeoutIds.add(handle);
2113
- return handle;
2114
- };
2115
- globalObject.clearTimeout = function(handle) {
2116
- if (tracker.timeoutIds.delete(handle)) {
2117
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2118
- }
2119
- return nativeClearTimeout(handle);
2120
- };
2121
-
2122
- if (typeof globalObject.fetch === "function") {
2123
- const nativeFetch = globalObject.fetch.bind(globalObject);
2124
- globalObject.fetch = (...args) => {
2125
- tracker.pendingFetches += 1;
2126
- markNetwork();
2127
- return nativeFetch(...args)
2128
- .finally(() => {
2129
- tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
2130
- markNetwork();
2131
- });
2132
- };
2133
- }
2134
-
2135
- if (typeof globalObject.XMLHttpRequest === "function") {
2136
- const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
2137
- const nativeSend = NativeXMLHttpRequest.prototype.send;
2138
- NativeXMLHttpRequest.prototype.send = function(...args) {
2139
- tracker.pendingXhrs += 1;
2140
- markNetwork();
2141
- const finalize = () => {
2142
- this.removeEventListener("loadend", finalize);
2143
- tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
2144
- markNetwork();
2145
- };
2146
- this.addEventListener("loadend", finalize, { once: true });
2147
- return nativeSend.apply(this, args);
2148
- };
2149
- }
2150
-
2151
- return true;
2152
- })()`;
2153
- }
2154
- function buildAbpSettleTrackerReadExpression() {
2155
- return `(() => {
2156
- const tracker = globalThis.__opensteerAbpSettleTracker;
2157
- if (!tracker) {
2158
- return null;
2159
- }
2160
-
2161
- return {
2162
- installedAt: Number(tracker.installedAt ?? 0),
2163
- lastMutationAt: Number(tracker.lastMutationAt ?? 0),
2164
- lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
2165
- now: Number(performance.now()),
2166
- pendingFetches: Number(tracker.pendingFetches ?? 0),
2167
- pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
2168
- pendingXhrs: Number(tracker.pendingXhrs ?? 0),
2169
- readyState: String(document.readyState),
2170
- };
2171
- })()`;
2172
- }
2173
- function trackerStateIsSettled(tracker) {
2174
- if (!tracker) {
2175
- return false;
2176
- }
2177
- if (tracker.readyState !== "complete") {
2178
- return false;
2179
- }
2180
- if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
2181
- return false;
2182
- }
2183
- const lastActivityAt = Math.max(
2184
- tracker.installedAt,
2185
- tracker.lastMutationAt,
2186
- tracker.lastNetworkActivityAt
2187
- );
2188
- return tracker.now - lastActivityAt >= POST_ACTION_SETTLE_QUIET_WINDOW_MS;
2189
- }
2190
- function abortError(signal) {
2280
+ function abortError2(signal) {
2191
2281
  return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
2192
2282
  }
2193
- async function delay2(ms, signal) {
2194
- if (ms <= 0) {
2195
- return;
2196
- }
2197
- if (signal?.aborted) {
2198
- throw abortError(signal);
2199
- }
2200
- await new Promise((resolve, reject) => {
2201
- const timeoutId = setTimeout(() => {
2202
- signal?.removeEventListener("abort", onAbort);
2203
- resolve();
2204
- }, ms);
2205
- const onAbort = () => {
2206
- clearTimeout(timeoutId);
2207
- signal?.removeEventListener("abort", onAbort);
2208
- reject(abortError(signal));
2209
- };
2210
- signal?.addEventListener("abort", onAbort, { once: true });
2211
- });
2212
- }
2213
2283
  function createAbpActionSettler(context) {
2214
- const installScript = buildAbpSettleTrackerInstallScript();
2215
- const readExpression = buildAbpSettleTrackerReadExpression();
2284
+ const installScript = buildPostLoadTrackerInstallScript();
2285
+ const readExpression = buildPostLoadTrackerReadExpression();
2216
2286
  async function installTracker(controller) {
2217
2287
  if (!controller.settleTrackerRegistered) {
2218
2288
  await controller.cdp.send("Page.addScriptToEvaluateOnNewDocument", {
@@ -2227,47 +2297,68 @@ function createAbpActionSettler(context) {
2227
2297
  });
2228
2298
  }
2229
2299
  async function readTrackerState(controller) {
2230
- const evaluated = await controller.cdp.send("Runtime.evaluate", {
2231
- expression: readExpression,
2232
- returnByValue: true,
2233
- awaitPromise: true
2234
- });
2235
- return normalizeAbpSettleTrackerState(evaluated.result?.value);
2300
+ try {
2301
+ const evaluated = await controller.cdp.send("Runtime.evaluate", {
2302
+ expression: readExpression,
2303
+ returnByValue: true,
2304
+ awaitPromise: true
2305
+ });
2306
+ return normalizePostLoadTrackerState(evaluated.result?.value);
2307
+ } catch (error) {
2308
+ if (context.isPageClosedError(error)) {
2309
+ return void 0;
2310
+ }
2311
+ throw error;
2312
+ }
2236
2313
  }
2237
2314
  async function settle(options) {
2238
- const { controller, timeoutMs, signal, policySettle } = options;
2315
+ const { controller, timeoutMs, signal, snapshot, policySettle } = options;
2239
2316
  if (timeoutMs <= 0) {
2240
- return;
2317
+ return {
2318
+ trigger: "dom-action",
2319
+ crossDocument: false,
2320
+ bootstrapSettled: false,
2321
+ timedOutPhase: "bootstrap"
2322
+ };
2241
2323
  }
2242
- const deadline = Date.now() + timeoutMs;
2243
2324
  const wasPaused = await context.syncExecutionPaused(controller);
2325
+ let boundary = {
2326
+ trigger: "dom-action",
2327
+ crossDocument: false,
2328
+ bootstrapSettled: false,
2329
+ timedOutPhase: "bootstrap"
2330
+ };
2244
2331
  if (wasPaused) {
2245
2332
  await context.setExecutionPaused(controller, false);
2246
2333
  }
2247
2334
  try {
2248
- await installTracker(controller);
2249
- if (policySettle) {
2250
- if (signal?.aborted) {
2251
- throw abortError(signal);
2252
- }
2253
- await policySettle(controller.pageRef, signal);
2254
- }
2255
- while (Date.now() < deadline) {
2256
- context.throwBackgroundError(controller);
2257
- if (controller.lifecycleState === "closed") {
2258
- return;
2259
- }
2260
- if (signal?.aborted) {
2261
- throw abortError(signal);
2335
+ if (snapshot === void 0) {
2336
+ if (policySettle) {
2337
+ if (signal?.aborted) {
2338
+ throw abortError2(signal);
2339
+ }
2340
+ await policySettle(controller.pageRef, "dom-action");
2262
2341
  }
2263
- const tracker = await readTrackerState(controller).catch(() => void 0);
2264
- if (trackerStateIsSettled(tracker)) {
2265
- break;
2342
+ boundary = {
2343
+ trigger: "dom-action",
2344
+ crossDocument: false,
2345
+ bootstrapSettled: true
2346
+ };
2347
+ } else {
2348
+ await installTracker(controller);
2349
+ boundary = await waitForActionBoundary({
2350
+ timeoutMs,
2351
+ ...signal === void 0 ? {} : { signal },
2352
+ snapshot,
2353
+ getCurrentMainFrameDocumentRef: () => context.getMainFrameDocumentRef(controller),
2354
+ waitForNavigationContentLoaded: (remainingMs) => context.waitForNavigationContentLoaded(controller, remainingMs),
2355
+ readTrackerState: () => readTrackerState(controller),
2356
+ throwBackgroundError: () => context.throwBackgroundError(controller),
2357
+ isPageClosed: () => controller.lifecycleState === "closed"
2358
+ });
2359
+ if (policySettle) {
2360
+ await policySettle(controller.pageRef, boundary.trigger);
2266
2361
  }
2267
- await delay2(
2268
- Math.min(POST_ACTION_SETTLE_POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())),
2269
- signal
2270
- );
2271
2362
  }
2272
2363
  } finally {
2273
2364
  if (wasPaused && controller.lifecycleState !== "closed") {
@@ -2277,7 +2368,6 @@ function createAbpActionSettler(context) {
2277
2368
  if (!context.isPageClosedError(error)) {
2278
2369
  throw error;
2279
2370
  }
2280
- return;
2281
2371
  }
2282
2372
  }
2283
2373
  if (controller.lifecycleState !== "closed") {
@@ -2290,6 +2380,7 @@ function createAbpActionSettler(context) {
2290
2380
  }
2291
2381
  }
2292
2382
  }
2383
+ return boundary;
2293
2384
  }
2294
2385
  return {
2295
2386
  installTracker,
@@ -2716,6 +2807,7 @@ function createAbpComputerUseBridge(context) {
2716
2807
  });
2717
2808
  let response;
2718
2809
  let dialogEvents = [];
2810
+ let boundary;
2719
2811
  switch (action.type) {
2720
2812
  case "click": {
2721
2813
  const executed = await context.executeInputAction(
@@ -2846,8 +2938,9 @@ function createAbpComputerUseBridge(context) {
2846
2938
  const resultController = context.resolveController(resultPageRef);
2847
2939
  let displayResponse = response;
2848
2940
  if (action.type !== "screenshot") {
2849
- await context.settleActionBoundary(resultController, {
2941
+ boundary = await context.settleActionBoundary(resultController, {
2850
2942
  timeoutMs: clampAbpActionSettleTimeout(remainingMs),
2943
+ ...resultController.pageRef === controller.pageRef && input.snapshot !== void 0 ? { snapshot: input.snapshot } : {},
2851
2944
  signal: input.signal,
2852
2945
  policySettle: input.policySettle
2853
2946
  });
@@ -2878,7 +2971,8 @@ function createAbpComputerUseBridge(context) {
2878
2971
  ...dialogEvents,
2879
2972
  ...popupQueuedEvents
2880
2973
  ],
2881
- timing: timingFromResponse(response, Date.now() - startedAt)
2974
+ timing: timingFromResponse(response, Date.now() - startedAt),
2975
+ ...boundary === void 0 ? {} : { boundary }
2882
2976
  };
2883
2977
  }
2884
2978
  };
@@ -3554,8 +3648,9 @@ function createAbpDomActionBridge(context) {
3554
3648
  },
3555
3649
  async finalizeDomAction(pageRef, options) {
3556
3650
  const controller = context.resolveController(pageRef);
3557
- await context.settleActionBoundary(controller, {
3651
+ const boundary = await context.settleActionBoundary(controller, {
3558
3652
  timeoutMs: clampAbpActionSettleTimeout(options.remainingMs()),
3653
+ ...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
3559
3654
  signal: options.signal,
3560
3655
  policySettle: options.policySettle
3561
3656
  });
@@ -3565,6 +3660,7 @@ function createAbpDomActionBridge(context) {
3565
3660
  details: { pageRef }
3566
3661
  });
3567
3662
  }
3663
+ return boundary;
3568
3664
  }
3569
3665
  };
3570
3666
  }
@@ -4204,6 +4300,8 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
4204
4300
  syncExecutionPaused: (controller) => this.syncControllerExecutionPaused(controller),
4205
4301
  setExecutionPaused: (controller, paused) => this.setControllerExecutionPaused(controller, paused),
4206
4302
  flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
4303
+ getMainFrameDocumentRef: (controller) => controller.mainFrameRef === void 0 ? void 0 : this.frames.get(controller.mainFrameRef)?.currentDocument.documentRef,
4304
+ waitForNavigationContentLoaded: async () => void 0,
4207
4305
  throwBackgroundError: (controller) => this.throwBackgroundError(controller),
4208
4306
  isPageClosedError: isAbpPageClosedError
4209
4307
  });