@opensteer/browser-core 0.7.2 → 0.7.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
@@ -1045,6 +1045,9 @@ var FakeBrowserCoreEngine = class {
1045
1045
  (pageRef) => clone(this.pageInfoFromState(this.requirePage(pageRef)))
1046
1046
  );
1047
1047
  }
1048
+ async drainEvents(input) {
1049
+ return this.drainQueuedEvents(input.pageRef);
1050
+ }
1048
1051
  async listFrames(input) {
1049
1052
  this.requireCapability("inspector.frameEnumeration");
1050
1053
  const page = this.requirePage(input.pageRef);
@@ -1068,9 +1071,30 @@ var FakeBrowserCoreEngine = class {
1068
1071
  const document = this.resolveDocumentInput(input);
1069
1072
  return clone(document.domSnapshot);
1070
1073
  }
1074
+ async getActionBoundarySnapshot(input) {
1075
+ this.requireCapability("inspector.frameEnumeration");
1076
+ const page = this.requirePage(input.pageRef);
1077
+ const mainFrameRef = Array.from(page.frameRefs).find(
1078
+ (frameRef) => this.requireFrame(frameRef).frameInfo.isMainFrame
1079
+ );
1080
+ if (mainFrameRef === void 0) {
1081
+ throw createBrowserCoreError(
1082
+ "operation-failed",
1083
+ `page ${input.pageRef} does not expose a main frame`
1084
+ );
1085
+ }
1086
+ const frame = this.requireFrame(mainFrameRef);
1087
+ return {
1088
+ pageRef: input.pageRef,
1089
+ documentRef: frame.frameInfo.documentRef,
1090
+ url: frame.frameInfo.url
1091
+ };
1092
+ }
1071
1093
  async waitForVisualStability(_input) {
1072
1094
  this.requireCapability("inspector.visualStability");
1073
1095
  }
1096
+ async waitForPostLoadQuiet(_input) {
1097
+ }
1074
1098
  async readText(input) {
1075
1099
  this.requireCapability("inspector.text");
1076
1100
  const document = this.requireLiveNode(input);
@@ -2863,19 +2887,24 @@ function normalizePostLoadTrackerState(value) {
2863
2887
  const installedAt = readFiniteNumber(value.installedAt);
2864
2888
  const lastMutationAt = readFiniteNumber(value.lastMutationAt);
2865
2889
  const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
2890
+ const lastTrackedNetworkActivityAt = readFiniteNumber(value.lastTrackedNetworkActivityAt);
2866
2891
  const now = readFiniteNumber(value.now);
2867
2892
  const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
2868
- if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
2893
+ if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || lastTrackedNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
2869
2894
  return void 0;
2870
2895
  }
2871
2896
  return {
2872
2897
  installedAt,
2873
2898
  lastMutationAt,
2874
2899
  lastNetworkActivityAt,
2900
+ lastTrackedNetworkActivityAt,
2875
2901
  now,
2876
2902
  pendingFetches: readNonNegativeNumber(value.pendingFetches),
2877
2903
  pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
2878
2904
  pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
2905
+ trackedPendingFetches: readNonNegativeNumber(value.trackedPendingFetches),
2906
+ trackedPendingXhrs: readNonNegativeNumber(value.trackedPendingXhrs),
2907
+ collecting: value.collecting === true,
2879
2908
  readyState
2880
2909
  };
2881
2910
  }
@@ -2890,11 +2919,14 @@ function buildPostLoadTrackerInstallScript() {
2890
2919
  installedAt: performance.now(),
2891
2920
  lastMutationAt: performance.now(),
2892
2921
  lastNetworkActivityAt: performance.now(),
2922
+ lastTrackedNetworkActivityAt: performance.now(),
2893
2923
  pendingFetches: 0,
2894
2924
  pendingTimeouts: 0,
2895
2925
  pendingXhrs: 0,
2926
+ trackedPendingFetches: 0,
2927
+ trackedPendingXhrs: 0,
2928
+ collecting: true,
2896
2929
  readyState: document.readyState,
2897
- timeoutIds: new Set(),
2898
2930
  };
2899
2931
  globalObject.__opensteerActionBoundaryTrackerInstalled = true;
2900
2932
  globalObject.__opensteerActionBoundaryTracker = tracker;
@@ -2907,6 +2939,18 @@ function buildPostLoadTrackerInstallScript() {
2907
2939
  tracker.lastNetworkActivityAt = performance.now();
2908
2940
  tracker.readyState = document.readyState;
2909
2941
  };
2942
+ const markTrackedNetwork = () => {
2943
+ tracker.lastTrackedNetworkActivityAt = performance.now();
2944
+ markNetwork();
2945
+ };
2946
+ const resetTracking = () => {
2947
+ const now = performance.now();
2948
+ tracker.lastTrackedNetworkActivityAt = now;
2949
+ tracker.trackedPendingFetches = 0;
2950
+ tracker.trackedPendingXhrs = 0;
2951
+ tracker.collecting = true;
2952
+ tracker.readyState = document.readyState;
2953
+ };
2910
2954
 
2911
2955
  const startObserver = () => {
2912
2956
  const target = document.documentElement ?? document;
@@ -2932,45 +2976,26 @@ function buildPostLoadTrackerInstallScript() {
2932
2976
  document.addEventListener("readystatechange", markMutation);
2933
2977
  addEventListener("load", markMutation, { once: true });
2934
2978
 
2935
- const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
2936
- const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
2937
- globalObject.setTimeout = function(callback, delay, ...args) {
2938
- tracker.pendingTimeouts += 1;
2939
- markNetwork();
2940
- let handle;
2941
- const wrapped =
2942
- typeof callback === "function"
2943
- ? (...callbackArgs) => {
2944
- if (tracker.timeoutIds.delete(handle)) {
2945
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2946
- }
2947
- try {
2948
- return callback(...callbackArgs);
2949
- } finally {
2950
- markMutation();
2951
- }
2952
- }
2953
- : callback;
2954
- handle = nativeSetTimeout(wrapped, delay, ...args);
2955
- tracker.timeoutIds.add(handle);
2956
- return handle;
2957
- };
2958
- globalObject.clearTimeout = function(handle) {
2959
- if (tracker.timeoutIds.delete(handle)) {
2960
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
2961
- }
2962
- return nativeClearTimeout(handle);
2963
- };
2964
-
2965
2979
  if (typeof globalObject.fetch === "function") {
2966
2980
  const nativeFetch = globalObject.fetch.bind(globalObject);
2967
2981
  globalObject.fetch = (...args) => {
2982
+ const tracked = tracker.collecting === true;
2968
2983
  tracker.pendingFetches += 1;
2969
- markNetwork();
2984
+ if (tracked) {
2985
+ tracker.trackedPendingFetches += 1;
2986
+ markTrackedNetwork();
2987
+ } else {
2988
+ markNetwork();
2989
+ }
2970
2990
  return nativeFetch(...args)
2971
2991
  .finally(() => {
2972
2992
  tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
2973
- markNetwork();
2993
+ if (tracked) {
2994
+ tracker.trackedPendingFetches = Math.max(0, tracker.trackedPendingFetches - 1);
2995
+ markTrackedNetwork();
2996
+ } else {
2997
+ markNetwork();
2998
+ }
2974
2999
  });
2975
3000
  };
2976
3001
  }
@@ -2979,21 +3004,60 @@ function buildPostLoadTrackerInstallScript() {
2979
3004
  const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
2980
3005
  const nativeSend = NativeXMLHttpRequest.prototype.send;
2981
3006
  NativeXMLHttpRequest.prototype.send = function(...args) {
3007
+ const tracked = tracker.collecting === true;
2982
3008
  tracker.pendingXhrs += 1;
2983
- markNetwork();
3009
+ if (tracked) {
3010
+ tracker.trackedPendingXhrs += 1;
3011
+ markTrackedNetwork();
3012
+ } else {
3013
+ markNetwork();
3014
+ }
2984
3015
  const finalize = () => {
2985
3016
  this.removeEventListener("loadend", finalize);
2986
3017
  tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
2987
- markNetwork();
3018
+ if (tracked) {
3019
+ tracker.trackedPendingXhrs = Math.max(0, tracker.trackedPendingXhrs - 1);
3020
+ markTrackedNetwork();
3021
+ } else {
3022
+ markNetwork();
3023
+ }
2988
3024
  };
2989
3025
  this.addEventListener("loadend", finalize, { once: true });
2990
3026
  return nativeSend.apply(this, args);
2991
3027
  };
2992
3028
  }
2993
3029
 
3030
+ tracker.beginObservation = () => {
3031
+ resetTracking();
3032
+ return true;
3033
+ };
3034
+ tracker.freezeObservation = () => {
3035
+ tracker.collecting = false;
3036
+ tracker.readyState = document.readyState;
3037
+ return true;
3038
+ };
3039
+
2994
3040
  return true;
2995
3041
  })()`;
2996
3042
  }
3043
+ function buildPostLoadTrackerBeginExpression() {
3044
+ return `(() => {
3045
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
3046
+ if (!tracker || typeof tracker.beginObservation !== "function") {
3047
+ return false;
3048
+ }
3049
+ return tracker.beginObservation();
3050
+ })()`;
3051
+ }
3052
+ function buildPostLoadTrackerFreezeExpression() {
3053
+ return `(() => {
3054
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
3055
+ if (!tracker || typeof tracker.freezeObservation !== "function") {
3056
+ return false;
3057
+ }
3058
+ return tracker.freezeObservation();
3059
+ })()`;
3060
+ }
2997
3061
  function buildPostLoadTrackerReadExpression() {
2998
3062
  return `(() => {
2999
3063
  const tracker = globalThis.__opensteerActionBoundaryTracker;
@@ -3005,14 +3069,31 @@ function buildPostLoadTrackerReadExpression() {
3005
3069
  installedAt: Number(tracker.installedAt ?? 0),
3006
3070
  lastMutationAt: Number(tracker.lastMutationAt ?? 0),
3007
3071
  lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
3072
+ lastTrackedNetworkActivityAt: Number(tracker.lastTrackedNetworkActivityAt ?? 0),
3008
3073
  now: Number(performance.now()),
3009
3074
  pendingFetches: Number(tracker.pendingFetches ?? 0),
3010
3075
  pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
3011
3076
  pendingXhrs: Number(tracker.pendingXhrs ?? 0),
3077
+ trackedPendingFetches: Number(tracker.trackedPendingFetches ?? 0),
3078
+ trackedPendingXhrs: Number(tracker.trackedPendingXhrs ?? 0),
3079
+ collecting: tracker.collecting === true,
3012
3080
  readyState: String(document.readyState),
3013
3081
  };
3014
3082
  })()`;
3015
3083
  }
3084
+ function capturePostLoadTrackerSnapshot(tracker) {
3085
+ return {
3086
+ lastTrackedNetworkActivityAt: tracker.lastTrackedNetworkActivityAt,
3087
+ trackedPendingFetches: tracker.trackedPendingFetches,
3088
+ trackedPendingXhrs: tracker.trackedPendingXhrs
3089
+ };
3090
+ }
3091
+ function postLoadTrackerHasTrackedNetworkActivitySince(snapshot, tracker) {
3092
+ if (!tracker) {
3093
+ return false;
3094
+ }
3095
+ return tracker.trackedPendingFetches > snapshot.trackedPendingFetches || tracker.trackedPendingXhrs > snapshot.trackedPendingXhrs || tracker.lastTrackedNetworkActivityAt > snapshot.lastTrackedNetworkActivityAt;
3096
+ }
3016
3097
  function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
3017
3098
  if (!tracker) {
3018
3099
  return false;
@@ -3020,13 +3101,13 @@ function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRA
3020
3101
  if (tracker.readyState !== "complete") {
3021
3102
  return false;
3022
3103
  }
3023
- if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
3104
+ if (tracker.trackedPendingFetches > 0 || tracker.trackedPendingXhrs > 0) {
3024
3105
  return false;
3025
3106
  }
3026
3107
  const lastActivityAt = Math.max(
3027
3108
  tracker.installedAt,
3028
3109
  tracker.lastMutationAt,
3029
- tracker.lastNetworkActivityAt
3110
+ tracker.lastTrackedNetworkActivityAt
3030
3111
  );
3031
3112
  return tracker.now - lastActivityAt >= quietWindowMs;
3032
3113
  }
@@ -3048,7 +3129,7 @@ async function waitForActionBoundary(input) {
3048
3129
  const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
3049
3130
  let trigger = "dom-action";
3050
3131
  let crossDocument = false;
3051
- let waitedForNavigationContentLoaded = false;
3132
+ let sameDocumentAsyncActivity = false;
3052
3133
  while (Date.now() < deadline) {
3053
3134
  input.throwBackgroundError();
3054
3135
  if (input.isPageClosed()) {
@@ -3070,16 +3151,21 @@ async function waitForActionBoundary(input) {
3070
3151
  throw abortError(input.signal);
3071
3152
  }
3072
3153
  const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
3154
+ const currentPageUrl = input.getCurrentPageUrl?.();
3073
3155
  if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
3074
3156
  trigger = "navigation";
3075
3157
  crossDocument = true;
3076
- if (!waitedForNavigationContentLoaded) {
3077
- waitedForNavigationContentLoaded = true;
3078
- const remaining = Math.max(0, deadline - Date.now());
3079
- if (remaining > 0) {
3080
- await input.waitForNavigationContentLoaded(remaining);
3081
- }
3082
- }
3158
+ }
3159
+ if (!crossDocument && !sameDocumentAsyncActivity && input.snapshot?.tracker !== void 0 && postLoadTrackerHasTrackedNetworkActivitySince(
3160
+ input.snapshot.tracker,
3161
+ await input.readTrackerState()
3162
+ )) {
3163
+ trigger = "navigation";
3164
+ sameDocumentAsyncActivity = true;
3165
+ }
3166
+ if (!crossDocument && input.snapshot?.url !== void 0 && currentPageUrl !== void 0 && currentPageUrl !== input.snapshot.url && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
3167
+ trigger = "navigation";
3168
+ crossDocument = true;
3083
3169
  }
3084
3170
  if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
3085
3171
  return {
@@ -3088,7 +3174,18 @@ async function waitForActionBoundary(input) {
3088
3174
  bootstrapSettled: true
3089
3175
  };
3090
3176
  }
3091
- if (crossDocument && postLoadTrackerIsSettled(await input.readTrackerState())) {
3177
+ if (sameDocumentAsyncActivity) {
3178
+ return {
3179
+ trigger,
3180
+ crossDocument,
3181
+ bootstrapSettled: true
3182
+ };
3183
+ }
3184
+ if (crossDocument && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
3185
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
3186
+ continue;
3187
+ }
3188
+ if (crossDocument) {
3092
3189
  return {
3093
3190
  trigger,
3094
3191
  crossDocument,
@@ -3133,8 +3230,11 @@ exports.bodyPayloadFromUtf8 = bodyPayloadFromUtf8;
3133
3230
  exports.brand = brand;
3134
3231
  exports.buildCdpShadowBoundaryIndex = buildCdpShadowBoundaryIndex;
3135
3232
  exports.buildDomSnapshotFromCdpCapture = buildDomSnapshotFromCdpCapture;
3233
+ exports.buildPostLoadTrackerBeginExpression = buildPostLoadTrackerBeginExpression;
3234
+ exports.buildPostLoadTrackerFreezeExpression = buildPostLoadTrackerFreezeExpression;
3136
3235
  exports.buildPostLoadTrackerInstallScript = buildPostLoadTrackerInstallScript;
3137
3236
  exports.buildPostLoadTrackerReadExpression = buildPostLoadTrackerReadExpression;
3237
+ exports.capturePostLoadTrackerSnapshot = capturePostLoadTrackerSnapshot;
3138
3238
  exports.closedPageError = closedPageError;
3139
3239
  exports.closedSessionError = closedSessionError;
3140
3240
  exports.createBodyPayload = createBodyPayload;
@@ -3183,6 +3283,7 @@ exports.noBrowserCapabilities = noBrowserCapabilities;
3183
3283
  exports.normalizeCdpShadowRootType = normalizeCdpShadowRootType;
3184
3284
  exports.normalizePostLoadTrackerState = normalizePostLoadTrackerState;
3185
3285
  exports.parseCdpStringTable = parseCdpStringTable;
3286
+ exports.postLoadTrackerHasTrackedNetworkActivitySince = postLoadTrackerHasTrackedNetworkActivitySince;
3186
3287
  exports.postLoadTrackerIsSettled = postLoadTrackerIsSettled;
3187
3288
  exports.quadBounds = quadBounds;
3188
3289
  exports.rareCdpIntegerValue = rareCdpIntegerValue;