@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.js CHANGED
@@ -1252,6 +1252,282 @@ function sleep(ms) {
1252
1252
  return new Promise((resolve) => setTimeout(resolve, ms));
1253
1253
  }
1254
1254
 
1255
+ // ../browser-core/src/post-load-tracker.ts
1256
+ var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
1257
+ var DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS = 100;
1258
+ function isRecord(value) {
1259
+ return typeof value === "object" && value !== null;
1260
+ }
1261
+ function readFiniteNumber(value) {
1262
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1263
+ }
1264
+ function readNonNegativeNumber(value) {
1265
+ const parsed = readFiniteNumber(value);
1266
+ return parsed === void 0 || parsed < 0 ? 0 : parsed;
1267
+ }
1268
+ function normalizePostLoadTrackerState(value) {
1269
+ if (!isRecord(value)) {
1270
+ return void 0;
1271
+ }
1272
+ const installedAt = readFiniteNumber(value.installedAt);
1273
+ const lastMutationAt = readFiniteNumber(value.lastMutationAt);
1274
+ const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
1275
+ const now = readFiniteNumber(value.now);
1276
+ const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
1277
+ if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
1278
+ return void 0;
1279
+ }
1280
+ return {
1281
+ installedAt,
1282
+ lastMutationAt,
1283
+ lastNetworkActivityAt,
1284
+ now,
1285
+ pendingFetches: readNonNegativeNumber(value.pendingFetches),
1286
+ pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
1287
+ pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
1288
+ readyState
1289
+ };
1290
+ }
1291
+ function buildPostLoadTrackerInstallScript() {
1292
+ return `(() => {
1293
+ const globalObject = globalThis;
1294
+ if (globalObject.__opensteerActionBoundaryTrackerInstalled) {
1295
+ return true;
1296
+ }
1297
+
1298
+ const tracker = {
1299
+ installedAt: performance.now(),
1300
+ lastMutationAt: performance.now(),
1301
+ lastNetworkActivityAt: performance.now(),
1302
+ pendingFetches: 0,
1303
+ pendingTimeouts: 0,
1304
+ pendingXhrs: 0,
1305
+ readyState: document.readyState,
1306
+ timeoutIds: new Set(),
1307
+ };
1308
+ globalObject.__opensteerActionBoundaryTrackerInstalled = true;
1309
+ globalObject.__opensteerActionBoundaryTracker = tracker;
1310
+
1311
+ const markMutation = () => {
1312
+ tracker.lastMutationAt = performance.now();
1313
+ tracker.readyState = document.readyState;
1314
+ };
1315
+ const markNetwork = () => {
1316
+ tracker.lastNetworkActivityAt = performance.now();
1317
+ tracker.readyState = document.readyState;
1318
+ };
1319
+
1320
+ const startObserver = () => {
1321
+ const target = document.documentElement ?? document;
1322
+ if (!(target instanceof Node)) {
1323
+ return;
1324
+ }
1325
+ const observer = new MutationObserver(markMutation);
1326
+ observer.observe(target, {
1327
+ subtree: true,
1328
+ childList: true,
1329
+ characterData: true,
1330
+ attributes: true,
1331
+ });
1332
+ markMutation();
1333
+ };
1334
+
1335
+ if (document.documentElement) {
1336
+ startObserver();
1337
+ } else {
1338
+ document.addEventListener("DOMContentLoaded", startObserver, { once: true });
1339
+ }
1340
+
1341
+ document.addEventListener("readystatechange", markMutation);
1342
+ addEventListener("load", markMutation, { once: true });
1343
+
1344
+ const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
1345
+ const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
1346
+ globalObject.setTimeout = function(callback, delay, ...args) {
1347
+ tracker.pendingTimeouts += 1;
1348
+ markNetwork();
1349
+ let handle;
1350
+ const wrapped =
1351
+ typeof callback === "function"
1352
+ ? (...callbackArgs) => {
1353
+ if (tracker.timeoutIds.delete(handle)) {
1354
+ tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1355
+ }
1356
+ try {
1357
+ return callback(...callbackArgs);
1358
+ } finally {
1359
+ markMutation();
1360
+ }
1361
+ }
1362
+ : callback;
1363
+ handle = nativeSetTimeout(wrapped, delay, ...args);
1364
+ tracker.timeoutIds.add(handle);
1365
+ return handle;
1366
+ };
1367
+ globalObject.clearTimeout = function(handle) {
1368
+ if (tracker.timeoutIds.delete(handle)) {
1369
+ tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1370
+ }
1371
+ return nativeClearTimeout(handle);
1372
+ };
1373
+
1374
+ if (typeof globalObject.fetch === "function") {
1375
+ const nativeFetch = globalObject.fetch.bind(globalObject);
1376
+ globalObject.fetch = (...args) => {
1377
+ tracker.pendingFetches += 1;
1378
+ markNetwork();
1379
+ return nativeFetch(...args)
1380
+ .finally(() => {
1381
+ tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
1382
+ markNetwork();
1383
+ });
1384
+ };
1385
+ }
1386
+
1387
+ if (typeof globalObject.XMLHttpRequest === "function") {
1388
+ const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
1389
+ const nativeSend = NativeXMLHttpRequest.prototype.send;
1390
+ NativeXMLHttpRequest.prototype.send = function(...args) {
1391
+ tracker.pendingXhrs += 1;
1392
+ markNetwork();
1393
+ const finalize = () => {
1394
+ this.removeEventListener("loadend", finalize);
1395
+ tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
1396
+ markNetwork();
1397
+ };
1398
+ this.addEventListener("loadend", finalize, { once: true });
1399
+ return nativeSend.apply(this, args);
1400
+ };
1401
+ }
1402
+
1403
+ return true;
1404
+ })()`;
1405
+ }
1406
+ function buildPostLoadTrackerReadExpression() {
1407
+ return `(() => {
1408
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
1409
+ if (!tracker) {
1410
+ return null;
1411
+ }
1412
+
1413
+ return {
1414
+ installedAt: Number(tracker.installedAt ?? 0),
1415
+ lastMutationAt: Number(tracker.lastMutationAt ?? 0),
1416
+ lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
1417
+ now: Number(performance.now()),
1418
+ pendingFetches: Number(tracker.pendingFetches ?? 0),
1419
+ pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
1420
+ pendingXhrs: Number(tracker.pendingXhrs ?? 0),
1421
+ readyState: String(document.readyState),
1422
+ };
1423
+ })()`;
1424
+ }
1425
+ function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
1426
+ if (!tracker) {
1427
+ return false;
1428
+ }
1429
+ if (tracker.readyState !== "complete") {
1430
+ return false;
1431
+ }
1432
+ if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
1433
+ return false;
1434
+ }
1435
+ const lastActivityAt = Math.max(
1436
+ tracker.installedAt,
1437
+ tracker.lastMutationAt,
1438
+ tracker.lastNetworkActivityAt
1439
+ );
1440
+ return tracker.now - lastActivityAt >= quietWindowMs;
1441
+ }
1442
+
1443
+ // ../browser-core/src/action-boundary.ts
1444
+ var CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS = 3e4;
1445
+ var CROSS_DOCUMENT_DETECTION_WINDOW_MS = 500;
1446
+ async function waitForActionBoundary(input) {
1447
+ if (input.timeoutMs <= 0) {
1448
+ return {
1449
+ trigger: "dom-action",
1450
+ crossDocument: false,
1451
+ bootstrapSettled: false,
1452
+ timedOutPhase: "bootstrap"
1453
+ };
1454
+ }
1455
+ const deadline = Date.now() + input.timeoutMs;
1456
+ const crossDocumentDetectionDeadline = input.snapshot === void 0 ? void 0 : Math.min(deadline, Date.now() + CROSS_DOCUMENT_DETECTION_WINDOW_MS);
1457
+ const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
1458
+ let trigger = "dom-action";
1459
+ let crossDocument = false;
1460
+ let waitedForNavigationContentLoaded = false;
1461
+ while (Date.now() < deadline) {
1462
+ input.throwBackgroundError();
1463
+ if (input.isPageClosed()) {
1464
+ return {
1465
+ trigger,
1466
+ crossDocument,
1467
+ bootstrapSettled: true
1468
+ };
1469
+ }
1470
+ if (input.signal?.aborted) {
1471
+ if (isTimeoutAbort(input.signal.reason) && Date.now() >= deadline) {
1472
+ return {
1473
+ trigger,
1474
+ crossDocument,
1475
+ bootstrapSettled: false,
1476
+ timedOutPhase: "bootstrap"
1477
+ };
1478
+ }
1479
+ throw abortError(input.signal);
1480
+ }
1481
+ const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
1482
+ if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
1483
+ trigger = "navigation";
1484
+ crossDocument = true;
1485
+ if (!waitedForNavigationContentLoaded) {
1486
+ waitedForNavigationContentLoaded = true;
1487
+ const remaining = Math.max(0, deadline - Date.now());
1488
+ if (remaining > 0) {
1489
+ await input.waitForNavigationContentLoaded(remaining);
1490
+ }
1491
+ }
1492
+ }
1493
+ if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
1494
+ return {
1495
+ trigger,
1496
+ crossDocument,
1497
+ bootstrapSettled: true
1498
+ };
1499
+ }
1500
+ if (crossDocument && postLoadTrackerIsSettled(await input.readTrackerState())) {
1501
+ return {
1502
+ trigger,
1503
+ crossDocument,
1504
+ bootstrapSettled: true
1505
+ };
1506
+ }
1507
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
1508
+ }
1509
+ return {
1510
+ trigger,
1511
+ crossDocument,
1512
+ bootstrapSettled: false,
1513
+ timedOutPhase: "bootstrap"
1514
+ };
1515
+ }
1516
+ function abortError(signal) {
1517
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
1518
+ }
1519
+ async function delay(ms) {
1520
+ if (ms <= 0) {
1521
+ return;
1522
+ }
1523
+ await new Promise((resolve) => {
1524
+ setTimeout(resolve, ms);
1525
+ });
1526
+ }
1527
+ function isTimeoutAbort(reason) {
1528
+ return typeof reason === "object" && reason !== null && "code" in reason && reason.code === "timeout";
1529
+ }
1530
+
1255
1531
  // ../protocol/src/computer-use-bridge.ts
1256
1532
  var OPENSTEER_COMPUTER_USE_BRIDGE_SYMBOL = /* @__PURE__ */ Symbol.for("@opensteer/computer-use-bridge");
1257
1533
 
@@ -1886,7 +2162,7 @@ async function waitForReady(baseUrl) {
1886
2162
  }
1887
2163
  } catch {
1888
2164
  }
1889
- await delay(200);
2165
+ await delay2(200);
1890
2166
  }
1891
2167
  throw createBrowserCoreError("timeout", `ABP did not become ready within 30000ms at ${baseUrl}`);
1892
2168
  }
@@ -1903,19 +2179,19 @@ async function waitForDevToolsPort(userDataDir) {
1903
2179
  }
1904
2180
  } catch {
1905
2181
  }
1906
- await delay(200);
2182
+ await delay2(200);
1907
2183
  }
1908
2184
  throw createBrowserCoreError(
1909
2185
  "timeout",
1910
2186
  `CDP port file was not written to ${userDataDir} within 30000ms`
1911
2187
  );
1912
2188
  }
1913
- function delay(ms) {
2189
+ function delay2(ms) {
1914
2190
  return new Promise((resolve) => setTimeout(resolve, ms));
1915
2191
  }
1916
2192
 
1917
2193
  // src/action-events.ts
1918
- function isRecord(value) {
2194
+ function isRecord2(value) {
1919
2195
  return typeof value === "object" && value !== null;
1920
2196
  }
1921
2197
  function readBoolean(value) {
@@ -1928,7 +2204,7 @@ function readString(value) {
1928
2204
  return typeof value === "string" ? value : void 0;
1929
2205
  }
1930
2206
  function parseSelectPopupItem(value) {
1931
- if (!isRecord(value)) {
2207
+ if (!isRecord2(value)) {
1932
2208
  return void 0;
1933
2209
  }
1934
2210
  const index = readInteger(value.index);
@@ -1987,225 +2263,19 @@ function normalizeSelectChooserEventData(data) {
1987
2263
  }
1988
2264
 
1989
2265
  // src/action-settle.ts
1990
- var DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS = 5e3;
1991
- var POST_ACTION_SETTLE_QUIET_WINDOW_MS = 400;
1992
- var POST_ACTION_SETTLE_POLL_INTERVAL_MS = 100;
2266
+ var DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS = CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS;
1993
2267
  function clampAbpActionSettleTimeout(timeoutMs) {
1994
2268
  if (timeoutMs === void 0) {
1995
2269
  return DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS;
1996
2270
  }
1997
2271
  return Math.max(0, Math.min(DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS, timeoutMs));
1998
2272
  }
1999
- function isRecord2(value) {
2000
- return typeof value === "object" && value !== null;
2001
- }
2002
- function readFiniteNumber(value) {
2003
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
2004
- }
2005
- function readNonNegativeNumber(value) {
2006
- const parsed = readFiniteNumber(value);
2007
- return parsed === void 0 || parsed < 0 ? 0 : parsed;
2008
- }
2009
- function normalizeAbpSettleTrackerState(value) {
2010
- if (!isRecord2(value)) {
2011
- return void 0;
2012
- }
2013
- const installedAt = readFiniteNumber(value.installedAt);
2014
- const lastMutationAt = readFiniteNumber(value.lastMutationAt);
2015
- const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
2016
- const now = readFiniteNumber(value.now);
2017
- const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
2018
- if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
2019
- return void 0;
2020
- }
2021
- return {
2022
- installedAt,
2023
- lastMutationAt,
2024
- lastNetworkActivityAt,
2025
- now,
2026
- pendingFetches: readNonNegativeNumber(value.pendingFetches),
2027
- pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
2028
- pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
2029
- readyState
2030
- };
2031
- }
2032
- function buildAbpSettleTrackerInstallScript() {
2033
- return `(() => {
2034
- const globalObject = globalThis;
2035
- if (globalObject.__opensteerAbpSettleTrackerInstalled) {
2036
- return true;
2037
- }
2038
-
2039
- const tracker = {
2040
- installedAt: performance.now(),
2041
- lastMutationAt: performance.now(),
2042
- lastNetworkActivityAt: performance.now(),
2043
- pendingFetches: 0,
2044
- pendingTimeouts: 0,
2045
- pendingXhrs: 0,
2046
- readyState: document.readyState,
2047
- timeoutIds: new Set(),
2048
- };
2049
- globalObject.__opensteerAbpSettleTrackerInstalled = true;
2050
- globalObject.__opensteerAbpSettleTracker = tracker;
2051
-
2052
- const markMutation = () => {
2053
- tracker.lastMutationAt = performance.now();
2054
- tracker.readyState = document.readyState;
2055
- };
2056
- const markNetwork = () => {
2057
- tracker.lastNetworkActivityAt = performance.now();
2058
- tracker.readyState = document.readyState;
2059
- };
2060
-
2061
- const startObserver = () => {
2062
- const target = document.documentElement ?? document;
2063
- if (!(target instanceof Node)) {
2064
- return;
2065
- }
2066
- const observer = new MutationObserver(markMutation);
2067
- observer.observe(target, {
2068
- subtree: true,
2069
- childList: true,
2070
- characterData: true,
2071
- attributes: true,
2072
- });
2073
- markMutation();
2074
- };
2075
-
2076
- if (document.documentElement) {
2077
- startObserver();
2078
- } else {
2079
- document.addEventListener("DOMContentLoaded", startObserver, { once: true });
2080
- }
2081
-
2082
- document.addEventListener("readystatechange", markMutation);
2083
- addEventListener("load", markMutation, { once: true });
2084
-
2085
- const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
2086
- const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
2087
- globalObject.setTimeout = function(callback, delay, ...args) {
2088
- tracker.pendingTimeouts += 1;
2089
- markNetwork();
2090
- let handle;
2091
- const wrapped =
2092
- typeof callback === "function"
2093
- ? (...callbackArgs) => {
2094
- if (tracker.timeoutIds.delete(handle)) {
2095
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2096
- }
2097
- try {
2098
- return callback(...callbackArgs);
2099
- } finally {
2100
- markMutation();
2101
- }
2102
- }
2103
- : callback;
2104
- handle = nativeSetTimeout(wrapped, delay, ...args);
2105
- tracker.timeoutIds.add(handle);
2106
- return handle;
2107
- };
2108
- globalObject.clearTimeout = function(handle) {
2109
- if (tracker.timeoutIds.delete(handle)) {
2110
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2111
- }
2112
- return nativeClearTimeout(handle);
2113
- };
2114
-
2115
- if (typeof globalObject.fetch === "function") {
2116
- const nativeFetch = globalObject.fetch.bind(globalObject);
2117
- globalObject.fetch = (...args) => {
2118
- tracker.pendingFetches += 1;
2119
- markNetwork();
2120
- return nativeFetch(...args)
2121
- .finally(() => {
2122
- tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
2123
- markNetwork();
2124
- });
2125
- };
2126
- }
2127
-
2128
- if (typeof globalObject.XMLHttpRequest === "function") {
2129
- const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
2130
- const nativeSend = NativeXMLHttpRequest.prototype.send;
2131
- NativeXMLHttpRequest.prototype.send = function(...args) {
2132
- tracker.pendingXhrs += 1;
2133
- markNetwork();
2134
- const finalize = () => {
2135
- this.removeEventListener("loadend", finalize);
2136
- tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
2137
- markNetwork();
2138
- };
2139
- this.addEventListener("loadend", finalize, { once: true });
2140
- return nativeSend.apply(this, args);
2141
- };
2142
- }
2143
-
2144
- return true;
2145
- })()`;
2146
- }
2147
- function buildAbpSettleTrackerReadExpression() {
2148
- return `(() => {
2149
- const tracker = globalThis.__opensteerAbpSettleTracker;
2150
- if (!tracker) {
2151
- return null;
2152
- }
2153
-
2154
- return {
2155
- installedAt: Number(tracker.installedAt ?? 0),
2156
- lastMutationAt: Number(tracker.lastMutationAt ?? 0),
2157
- lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
2158
- now: Number(performance.now()),
2159
- pendingFetches: Number(tracker.pendingFetches ?? 0),
2160
- pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
2161
- pendingXhrs: Number(tracker.pendingXhrs ?? 0),
2162
- readyState: String(document.readyState),
2163
- };
2164
- })()`;
2165
- }
2166
- function trackerStateIsSettled(tracker) {
2167
- if (!tracker) {
2168
- return false;
2169
- }
2170
- if (tracker.readyState !== "complete") {
2171
- return false;
2172
- }
2173
- if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
2174
- return false;
2175
- }
2176
- const lastActivityAt = Math.max(
2177
- tracker.installedAt,
2178
- tracker.lastMutationAt,
2179
- tracker.lastNetworkActivityAt
2180
- );
2181
- return tracker.now - lastActivityAt >= POST_ACTION_SETTLE_QUIET_WINDOW_MS;
2182
- }
2183
- function abortError(signal) {
2273
+ function abortError2(signal) {
2184
2274
  return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
2185
2275
  }
2186
- async function delay2(ms, signal) {
2187
- if (ms <= 0) {
2188
- return;
2189
- }
2190
- if (signal?.aborted) {
2191
- throw abortError(signal);
2192
- }
2193
- await new Promise((resolve, reject) => {
2194
- const timeoutId = setTimeout(() => {
2195
- signal?.removeEventListener("abort", onAbort);
2196
- resolve();
2197
- }, ms);
2198
- const onAbort = () => {
2199
- clearTimeout(timeoutId);
2200
- signal?.removeEventListener("abort", onAbort);
2201
- reject(abortError(signal));
2202
- };
2203
- signal?.addEventListener("abort", onAbort, { once: true });
2204
- });
2205
- }
2206
2276
  function createAbpActionSettler(context) {
2207
- const installScript = buildAbpSettleTrackerInstallScript();
2208
- const readExpression = buildAbpSettleTrackerReadExpression();
2277
+ const installScript = buildPostLoadTrackerInstallScript();
2278
+ const readExpression = buildPostLoadTrackerReadExpression();
2209
2279
  async function installTracker(controller) {
2210
2280
  if (!controller.settleTrackerRegistered) {
2211
2281
  await controller.cdp.send("Page.addScriptToEvaluateOnNewDocument", {
@@ -2220,47 +2290,68 @@ function createAbpActionSettler(context) {
2220
2290
  });
2221
2291
  }
2222
2292
  async function readTrackerState(controller) {
2223
- const evaluated = await controller.cdp.send("Runtime.evaluate", {
2224
- expression: readExpression,
2225
- returnByValue: true,
2226
- awaitPromise: true
2227
- });
2228
- return normalizeAbpSettleTrackerState(evaluated.result?.value);
2293
+ try {
2294
+ const evaluated = await controller.cdp.send("Runtime.evaluate", {
2295
+ expression: readExpression,
2296
+ returnByValue: true,
2297
+ awaitPromise: true
2298
+ });
2299
+ return normalizePostLoadTrackerState(evaluated.result?.value);
2300
+ } catch (error) {
2301
+ if (context.isPageClosedError(error)) {
2302
+ return void 0;
2303
+ }
2304
+ throw error;
2305
+ }
2229
2306
  }
2230
2307
  async function settle(options) {
2231
- const { controller, timeoutMs, signal, policySettle } = options;
2308
+ const { controller, timeoutMs, signal, snapshot, policySettle } = options;
2232
2309
  if (timeoutMs <= 0) {
2233
- return;
2310
+ return {
2311
+ trigger: "dom-action",
2312
+ crossDocument: false,
2313
+ bootstrapSettled: false,
2314
+ timedOutPhase: "bootstrap"
2315
+ };
2234
2316
  }
2235
- const deadline = Date.now() + timeoutMs;
2236
2317
  const wasPaused = await context.syncExecutionPaused(controller);
2318
+ let boundary = {
2319
+ trigger: "dom-action",
2320
+ crossDocument: false,
2321
+ bootstrapSettled: false,
2322
+ timedOutPhase: "bootstrap"
2323
+ };
2237
2324
  if (wasPaused) {
2238
2325
  await context.setExecutionPaused(controller, false);
2239
2326
  }
2240
2327
  try {
2241
- await installTracker(controller);
2242
- if (policySettle) {
2243
- if (signal?.aborted) {
2244
- throw abortError(signal);
2245
- }
2246
- await policySettle(controller.pageRef, signal);
2247
- }
2248
- while (Date.now() < deadline) {
2249
- context.throwBackgroundError(controller);
2250
- if (controller.lifecycleState === "closed") {
2251
- return;
2252
- }
2253
- if (signal?.aborted) {
2254
- throw abortError(signal);
2328
+ if (snapshot === void 0) {
2329
+ if (policySettle) {
2330
+ if (signal?.aborted) {
2331
+ throw abortError2(signal);
2332
+ }
2333
+ await policySettle(controller.pageRef, "dom-action");
2255
2334
  }
2256
- const tracker = await readTrackerState(controller).catch(() => void 0);
2257
- if (trackerStateIsSettled(tracker)) {
2258
- break;
2335
+ boundary = {
2336
+ trigger: "dom-action",
2337
+ crossDocument: false,
2338
+ bootstrapSettled: true
2339
+ };
2340
+ } else {
2341
+ await installTracker(controller);
2342
+ boundary = await waitForActionBoundary({
2343
+ timeoutMs,
2344
+ ...signal === void 0 ? {} : { signal },
2345
+ snapshot,
2346
+ getCurrentMainFrameDocumentRef: () => context.getMainFrameDocumentRef(controller),
2347
+ waitForNavigationContentLoaded: (remainingMs) => context.waitForNavigationContentLoaded(controller, remainingMs),
2348
+ readTrackerState: () => readTrackerState(controller),
2349
+ throwBackgroundError: () => context.throwBackgroundError(controller),
2350
+ isPageClosed: () => controller.lifecycleState === "closed"
2351
+ });
2352
+ if (policySettle) {
2353
+ await policySettle(controller.pageRef, boundary.trigger);
2259
2354
  }
2260
- await delay2(
2261
- Math.min(POST_ACTION_SETTLE_POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())),
2262
- signal
2263
- );
2264
2355
  }
2265
2356
  } finally {
2266
2357
  if (wasPaused && controller.lifecycleState !== "closed") {
@@ -2270,7 +2361,6 @@ function createAbpActionSettler(context) {
2270
2361
  if (!context.isPageClosedError(error)) {
2271
2362
  throw error;
2272
2363
  }
2273
- return;
2274
2364
  }
2275
2365
  }
2276
2366
  if (controller.lifecycleState !== "closed") {
@@ -2283,6 +2373,7 @@ function createAbpActionSettler(context) {
2283
2373
  }
2284
2374
  }
2285
2375
  }
2376
+ return boundary;
2286
2377
  }
2287
2378
  return {
2288
2379
  installTracker,
@@ -2709,6 +2800,7 @@ function createAbpComputerUseBridge(context) {
2709
2800
  });
2710
2801
  let response;
2711
2802
  let dialogEvents = [];
2803
+ let boundary;
2712
2804
  switch (action.type) {
2713
2805
  case "click": {
2714
2806
  const executed = await context.executeInputAction(
@@ -2839,8 +2931,9 @@ function createAbpComputerUseBridge(context) {
2839
2931
  const resultController = context.resolveController(resultPageRef);
2840
2932
  let displayResponse = response;
2841
2933
  if (action.type !== "screenshot") {
2842
- await context.settleActionBoundary(resultController, {
2934
+ boundary = await context.settleActionBoundary(resultController, {
2843
2935
  timeoutMs: clampAbpActionSettleTimeout(remainingMs),
2936
+ ...resultController.pageRef === controller.pageRef && input.snapshot !== void 0 ? { snapshot: input.snapshot } : {},
2844
2937
  signal: input.signal,
2845
2938
  policySettle: input.policySettle
2846
2939
  });
@@ -2871,7 +2964,8 @@ function createAbpComputerUseBridge(context) {
2871
2964
  ...dialogEvents,
2872
2965
  ...popupQueuedEvents
2873
2966
  ],
2874
- timing: timingFromResponse(response, Date.now() - startedAt)
2967
+ timing: timingFromResponse(response, Date.now() - startedAt),
2968
+ ...boundary === void 0 ? {} : { boundary }
2875
2969
  };
2876
2970
  }
2877
2971
  };
@@ -3547,8 +3641,9 @@ function createAbpDomActionBridge(context) {
3547
3641
  },
3548
3642
  async finalizeDomAction(pageRef, options) {
3549
3643
  const controller = context.resolveController(pageRef);
3550
- await context.settleActionBoundary(controller, {
3644
+ const boundary = await context.settleActionBoundary(controller, {
3551
3645
  timeoutMs: clampAbpActionSettleTimeout(options.remainingMs()),
3646
+ ...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
3552
3647
  signal: options.signal,
3553
3648
  policySettle: options.policySettle
3554
3649
  });
@@ -3558,6 +3653,7 @@ function createAbpDomActionBridge(context) {
3558
3653
  details: { pageRef }
3559
3654
  });
3560
3655
  }
3656
+ return boundary;
3561
3657
  }
3562
3658
  };
3563
3659
  }
@@ -4197,6 +4293,8 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
4197
4293
  syncExecutionPaused: (controller) => this.syncControllerExecutionPaused(controller),
4198
4294
  setExecutionPaused: (controller, paused) => this.setControllerExecutionPaused(controller, paused),
4199
4295
  flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
4296
+ getMainFrameDocumentRef: (controller) => controller.mainFrameRef === void 0 ? void 0 : this.frames.get(controller.mainFrameRef)?.currentDocument.documentRef,
4297
+ waitForNavigationContentLoaded: async () => void 0,
4200
4298
  throwBackgroundError: (controller) => this.throwBackgroundError(controller),
4201
4299
  isPageClosedError: isAbpPageClosedError
4202
4300
  });