@opensteer/browser-core 0.7.1 → 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.js CHANGED
@@ -1043,6 +1043,9 @@ var FakeBrowserCoreEngine = class {
1043
1043
  (pageRef) => clone(this.pageInfoFromState(this.requirePage(pageRef)))
1044
1044
  );
1045
1045
  }
1046
+ async drainEvents(input) {
1047
+ return this.drainQueuedEvents(input.pageRef);
1048
+ }
1046
1049
  async listFrames(input) {
1047
1050
  this.requireCapability("inspector.frameEnumeration");
1048
1051
  const page = this.requirePage(input.pageRef);
@@ -1066,9 +1069,30 @@ var FakeBrowserCoreEngine = class {
1066
1069
  const document = this.resolveDocumentInput(input);
1067
1070
  return clone(document.domSnapshot);
1068
1071
  }
1072
+ async getActionBoundarySnapshot(input) {
1073
+ this.requireCapability("inspector.frameEnumeration");
1074
+ const page = this.requirePage(input.pageRef);
1075
+ const mainFrameRef = Array.from(page.frameRefs).find(
1076
+ (frameRef) => this.requireFrame(frameRef).frameInfo.isMainFrame
1077
+ );
1078
+ if (mainFrameRef === void 0) {
1079
+ throw createBrowserCoreError(
1080
+ "operation-failed",
1081
+ `page ${input.pageRef} does not expose a main frame`
1082
+ );
1083
+ }
1084
+ const frame = this.requireFrame(mainFrameRef);
1085
+ return {
1086
+ pageRef: input.pageRef,
1087
+ documentRef: frame.frameInfo.documentRef,
1088
+ url: frame.frameInfo.url
1089
+ };
1090
+ }
1069
1091
  async waitForVisualStability(_input) {
1070
1092
  this.requireCapability("inspector.visualStability");
1071
1093
  }
1094
+ async waitForPostLoadQuiet(_input) {
1095
+ }
1072
1096
  async readText(input) {
1073
1097
  this.requireCapability("inspector.text");
1074
1098
  const document = this.requireLiveNode(input);
@@ -2841,6 +2865,355 @@ function sleep(ms) {
2841
2865
  return new Promise((resolve) => setTimeout(resolve, ms));
2842
2866
  }
2843
2867
 
2844
- export { BrowserCoreError, DEFAULT_VISUAL_STABILITY_SETTLE_MS, DEFAULT_VISUAL_STABILITY_TIMEOUT_MS, DOM_SNAPSHOT_COMPUTED_STYLE_NAMES, FakeBrowserCoreEngine, allBrowserCapabilities, bodyPayloadFromUtf8, brand, buildCdpShadowBoundaryIndex, buildDomSnapshotFromCdpCapture, closedPageError, closedSessionError, createBodyPayload, createBrowserCoreError, createChooserRef, createDevicePixelRatio, createDialogRef, createDocumentEpoch, createDocumentRef, createDownloadRef, createFakeBrowserCoreEngine, createFrameRef, createHeaderEntry, createNetworkRequestId, createNodeLocator, createNodeRef, createPageRef, createPageScaleFactor, createPageZoomFactor, createPoint, createQuad, createRect, createScrollOffset, createSessionRef, createSize, createWorkerRef, filterCookieRecords, findDomSnapshotNode, findDomSnapshotNodeByRef, hasCapability, isBrowserCoreError, isChooserRef, isDialogRef, isDocumentRef, isDownloadRef, isFrameRef, isNetworkRequestId, isNodeRef, isPageRef, isSessionRef, isWorkerRef, matchesNetworkRecordFilters, mergeBrowserCapabilities, nextDocumentEpoch, noBrowserCapabilities, normalizeCdpShadowRootType, parseCdpStringTable, quadBounds, rareCdpIntegerValue, rareCdpStringValue, rectContainsPoint, rectToQuad, serializeDocumentEpoch, serializeRef, staleNodeRefError, unsupportedCapabilityError, waitForCdpVisualStability };
2868
+ // src/post-load-tracker.ts
2869
+ var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
2870
+ var DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS = 100;
2871
+ function isRecord(value) {
2872
+ return typeof value === "object" && value !== null;
2873
+ }
2874
+ function readFiniteNumber(value) {
2875
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
2876
+ }
2877
+ function readNonNegativeNumber(value) {
2878
+ const parsed = readFiniteNumber(value);
2879
+ return parsed === void 0 || parsed < 0 ? 0 : parsed;
2880
+ }
2881
+ function normalizePostLoadTrackerState(value) {
2882
+ if (!isRecord(value)) {
2883
+ return void 0;
2884
+ }
2885
+ const installedAt = readFiniteNumber(value.installedAt);
2886
+ const lastMutationAt = readFiniteNumber(value.lastMutationAt);
2887
+ const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
2888
+ const lastTrackedNetworkActivityAt = readFiniteNumber(value.lastTrackedNetworkActivityAt);
2889
+ const now = readFiniteNumber(value.now);
2890
+ const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
2891
+ if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || lastTrackedNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
2892
+ return void 0;
2893
+ }
2894
+ return {
2895
+ installedAt,
2896
+ lastMutationAt,
2897
+ lastNetworkActivityAt,
2898
+ lastTrackedNetworkActivityAt,
2899
+ now,
2900
+ pendingFetches: readNonNegativeNumber(value.pendingFetches),
2901
+ pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
2902
+ pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
2903
+ trackedPendingFetches: readNonNegativeNumber(value.trackedPendingFetches),
2904
+ trackedPendingXhrs: readNonNegativeNumber(value.trackedPendingXhrs),
2905
+ collecting: value.collecting === true,
2906
+ readyState
2907
+ };
2908
+ }
2909
+ function buildPostLoadTrackerInstallScript() {
2910
+ return `(() => {
2911
+ const globalObject = globalThis;
2912
+ if (globalObject.__opensteerActionBoundaryTrackerInstalled) {
2913
+ return true;
2914
+ }
2915
+
2916
+ const tracker = {
2917
+ installedAt: performance.now(),
2918
+ lastMutationAt: performance.now(),
2919
+ lastNetworkActivityAt: performance.now(),
2920
+ lastTrackedNetworkActivityAt: performance.now(),
2921
+ pendingFetches: 0,
2922
+ pendingTimeouts: 0,
2923
+ pendingXhrs: 0,
2924
+ trackedPendingFetches: 0,
2925
+ trackedPendingXhrs: 0,
2926
+ collecting: true,
2927
+ readyState: document.readyState,
2928
+ };
2929
+ globalObject.__opensteerActionBoundaryTrackerInstalled = true;
2930
+ globalObject.__opensteerActionBoundaryTracker = tracker;
2931
+
2932
+ const markMutation = () => {
2933
+ tracker.lastMutationAt = performance.now();
2934
+ tracker.readyState = document.readyState;
2935
+ };
2936
+ const markNetwork = () => {
2937
+ tracker.lastNetworkActivityAt = performance.now();
2938
+ tracker.readyState = document.readyState;
2939
+ };
2940
+ const markTrackedNetwork = () => {
2941
+ tracker.lastTrackedNetworkActivityAt = performance.now();
2942
+ markNetwork();
2943
+ };
2944
+ const resetTracking = () => {
2945
+ const now = performance.now();
2946
+ tracker.lastTrackedNetworkActivityAt = now;
2947
+ tracker.trackedPendingFetches = 0;
2948
+ tracker.trackedPendingXhrs = 0;
2949
+ tracker.collecting = true;
2950
+ tracker.readyState = document.readyState;
2951
+ };
2952
+
2953
+ const startObserver = () => {
2954
+ const target = document.documentElement ?? document;
2955
+ if (!(target instanceof Node)) {
2956
+ return;
2957
+ }
2958
+ const observer = new MutationObserver(markMutation);
2959
+ observer.observe(target, {
2960
+ subtree: true,
2961
+ childList: true,
2962
+ characterData: true,
2963
+ attributes: true,
2964
+ });
2965
+ markMutation();
2966
+ };
2967
+
2968
+ if (document.documentElement) {
2969
+ startObserver();
2970
+ } else {
2971
+ document.addEventListener("DOMContentLoaded", startObserver, { once: true });
2972
+ }
2973
+
2974
+ document.addEventListener("readystatechange", markMutation);
2975
+ addEventListener("load", markMutation, { once: true });
2976
+
2977
+ if (typeof globalObject.fetch === "function") {
2978
+ const nativeFetch = globalObject.fetch.bind(globalObject);
2979
+ globalObject.fetch = (...args) => {
2980
+ const tracked = tracker.collecting === true;
2981
+ tracker.pendingFetches += 1;
2982
+ if (tracked) {
2983
+ tracker.trackedPendingFetches += 1;
2984
+ markTrackedNetwork();
2985
+ } else {
2986
+ markNetwork();
2987
+ }
2988
+ return nativeFetch(...args)
2989
+ .finally(() => {
2990
+ tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
2991
+ if (tracked) {
2992
+ tracker.trackedPendingFetches = Math.max(0, tracker.trackedPendingFetches - 1);
2993
+ markTrackedNetwork();
2994
+ } else {
2995
+ markNetwork();
2996
+ }
2997
+ });
2998
+ };
2999
+ }
3000
+
3001
+ if (typeof globalObject.XMLHttpRequest === "function") {
3002
+ const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
3003
+ const nativeSend = NativeXMLHttpRequest.prototype.send;
3004
+ NativeXMLHttpRequest.prototype.send = function(...args) {
3005
+ const tracked = tracker.collecting === true;
3006
+ tracker.pendingXhrs += 1;
3007
+ if (tracked) {
3008
+ tracker.trackedPendingXhrs += 1;
3009
+ markTrackedNetwork();
3010
+ } else {
3011
+ markNetwork();
3012
+ }
3013
+ const finalize = () => {
3014
+ this.removeEventListener("loadend", finalize);
3015
+ tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
3016
+ if (tracked) {
3017
+ tracker.trackedPendingXhrs = Math.max(0, tracker.trackedPendingXhrs - 1);
3018
+ markTrackedNetwork();
3019
+ } else {
3020
+ markNetwork();
3021
+ }
3022
+ };
3023
+ this.addEventListener("loadend", finalize, { once: true });
3024
+ return nativeSend.apply(this, args);
3025
+ };
3026
+ }
3027
+
3028
+ tracker.beginObservation = () => {
3029
+ resetTracking();
3030
+ return true;
3031
+ };
3032
+ tracker.freezeObservation = () => {
3033
+ tracker.collecting = false;
3034
+ tracker.readyState = document.readyState;
3035
+ return true;
3036
+ };
3037
+
3038
+ return true;
3039
+ })()`;
3040
+ }
3041
+ function buildPostLoadTrackerBeginExpression() {
3042
+ return `(() => {
3043
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
3044
+ if (!tracker || typeof tracker.beginObservation !== "function") {
3045
+ return false;
3046
+ }
3047
+ return tracker.beginObservation();
3048
+ })()`;
3049
+ }
3050
+ function buildPostLoadTrackerFreezeExpression() {
3051
+ return `(() => {
3052
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
3053
+ if (!tracker || typeof tracker.freezeObservation !== "function") {
3054
+ return false;
3055
+ }
3056
+ return tracker.freezeObservation();
3057
+ })()`;
3058
+ }
3059
+ function buildPostLoadTrackerReadExpression() {
3060
+ return `(() => {
3061
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
3062
+ if (!tracker) {
3063
+ return null;
3064
+ }
3065
+
3066
+ return {
3067
+ installedAt: Number(tracker.installedAt ?? 0),
3068
+ lastMutationAt: Number(tracker.lastMutationAt ?? 0),
3069
+ lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
3070
+ lastTrackedNetworkActivityAt: Number(tracker.lastTrackedNetworkActivityAt ?? 0),
3071
+ now: Number(performance.now()),
3072
+ pendingFetches: Number(tracker.pendingFetches ?? 0),
3073
+ pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
3074
+ pendingXhrs: Number(tracker.pendingXhrs ?? 0),
3075
+ trackedPendingFetches: Number(tracker.trackedPendingFetches ?? 0),
3076
+ trackedPendingXhrs: Number(tracker.trackedPendingXhrs ?? 0),
3077
+ collecting: tracker.collecting === true,
3078
+ readyState: String(document.readyState),
3079
+ };
3080
+ })()`;
3081
+ }
3082
+ function capturePostLoadTrackerSnapshot(tracker) {
3083
+ return {
3084
+ lastTrackedNetworkActivityAt: tracker.lastTrackedNetworkActivityAt,
3085
+ trackedPendingFetches: tracker.trackedPendingFetches,
3086
+ trackedPendingXhrs: tracker.trackedPendingXhrs
3087
+ };
3088
+ }
3089
+ function postLoadTrackerHasTrackedNetworkActivitySince(snapshot, tracker) {
3090
+ if (!tracker) {
3091
+ return false;
3092
+ }
3093
+ return tracker.trackedPendingFetches > snapshot.trackedPendingFetches || tracker.trackedPendingXhrs > snapshot.trackedPendingXhrs || tracker.lastTrackedNetworkActivityAt > snapshot.lastTrackedNetworkActivityAt;
3094
+ }
3095
+ function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
3096
+ if (!tracker) {
3097
+ return false;
3098
+ }
3099
+ if (tracker.readyState !== "complete") {
3100
+ return false;
3101
+ }
3102
+ if (tracker.trackedPendingFetches > 0 || tracker.trackedPendingXhrs > 0) {
3103
+ return false;
3104
+ }
3105
+ const lastActivityAt = Math.max(
3106
+ tracker.installedAt,
3107
+ tracker.lastMutationAt,
3108
+ tracker.lastTrackedNetworkActivityAt
3109
+ );
3110
+ return tracker.now - lastActivityAt >= quietWindowMs;
3111
+ }
3112
+
3113
+ // src/action-boundary.ts
3114
+ var CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS = 3e4;
3115
+ var CROSS_DOCUMENT_DETECTION_WINDOW_MS = 500;
3116
+ async function waitForActionBoundary(input) {
3117
+ if (input.timeoutMs <= 0) {
3118
+ return {
3119
+ trigger: "dom-action",
3120
+ crossDocument: false,
3121
+ bootstrapSettled: false,
3122
+ timedOutPhase: "bootstrap"
3123
+ };
3124
+ }
3125
+ const deadline = Date.now() + input.timeoutMs;
3126
+ const crossDocumentDetectionDeadline = input.snapshot === void 0 ? void 0 : Math.min(deadline, Date.now() + CROSS_DOCUMENT_DETECTION_WINDOW_MS);
3127
+ const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
3128
+ let trigger = "dom-action";
3129
+ let crossDocument = false;
3130
+ let sameDocumentAsyncActivity = false;
3131
+ while (Date.now() < deadline) {
3132
+ input.throwBackgroundError();
3133
+ if (input.isPageClosed()) {
3134
+ return {
3135
+ trigger,
3136
+ crossDocument,
3137
+ bootstrapSettled: true
3138
+ };
3139
+ }
3140
+ if (input.signal?.aborted) {
3141
+ if (isTimeoutAbort(input.signal.reason) && Date.now() >= deadline) {
3142
+ return {
3143
+ trigger,
3144
+ crossDocument,
3145
+ bootstrapSettled: false,
3146
+ timedOutPhase: "bootstrap"
3147
+ };
3148
+ }
3149
+ throw abortError(input.signal);
3150
+ }
3151
+ const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
3152
+ const currentPageUrl = input.getCurrentPageUrl?.();
3153
+ if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
3154
+ trigger = "navigation";
3155
+ crossDocument = true;
3156
+ }
3157
+ if (!crossDocument && !sameDocumentAsyncActivity && input.snapshot?.tracker !== void 0 && postLoadTrackerHasTrackedNetworkActivitySince(
3158
+ input.snapshot.tracker,
3159
+ await input.readTrackerState()
3160
+ )) {
3161
+ trigger = "navigation";
3162
+ sameDocumentAsyncActivity = true;
3163
+ }
3164
+ if (!crossDocument && input.snapshot?.url !== void 0 && currentPageUrl !== void 0 && currentPageUrl !== input.snapshot.url && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
3165
+ trigger = "navigation";
3166
+ crossDocument = true;
3167
+ }
3168
+ if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
3169
+ return {
3170
+ trigger,
3171
+ crossDocument,
3172
+ bootstrapSettled: true
3173
+ };
3174
+ }
3175
+ if (sameDocumentAsyncActivity) {
3176
+ return {
3177
+ trigger,
3178
+ crossDocument,
3179
+ bootstrapSettled: true
3180
+ };
3181
+ }
3182
+ if (crossDocument && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
3183
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
3184
+ continue;
3185
+ }
3186
+ if (crossDocument) {
3187
+ return {
3188
+ trigger,
3189
+ crossDocument,
3190
+ bootstrapSettled: true
3191
+ };
3192
+ }
3193
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
3194
+ }
3195
+ return {
3196
+ trigger,
3197
+ crossDocument,
3198
+ bootstrapSettled: false,
3199
+ timedOutPhase: "bootstrap"
3200
+ };
3201
+ }
3202
+ function abortError(signal) {
3203
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
3204
+ }
3205
+ async function delay(ms) {
3206
+ if (ms <= 0) {
3207
+ return;
3208
+ }
3209
+ await new Promise((resolve) => {
3210
+ setTimeout(resolve, ms);
3211
+ });
3212
+ }
3213
+ function isTimeoutAbort(reason) {
3214
+ return typeof reason === "object" && reason !== null && "code" in reason && reason.code === "timeout";
3215
+ }
3216
+
3217
+ export { BrowserCoreError, CROSS_DOCUMENT_DETECTION_WINDOW_MS, CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS, DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS, DEFAULT_VISUAL_STABILITY_SETTLE_MS, DEFAULT_VISUAL_STABILITY_TIMEOUT_MS, DOM_SNAPSHOT_COMPUTED_STYLE_NAMES, FakeBrowserCoreEngine, allBrowserCapabilities, bodyPayloadFromUtf8, brand, buildCdpShadowBoundaryIndex, buildDomSnapshotFromCdpCapture, buildPostLoadTrackerBeginExpression, buildPostLoadTrackerFreezeExpression, buildPostLoadTrackerInstallScript, buildPostLoadTrackerReadExpression, capturePostLoadTrackerSnapshot, closedPageError, closedSessionError, createBodyPayload, createBrowserCoreError, createChooserRef, createDevicePixelRatio, createDialogRef, createDocumentEpoch, createDocumentRef, createDownloadRef, createFakeBrowserCoreEngine, createFrameRef, createHeaderEntry, createNetworkRequestId, createNodeLocator, createNodeRef, createPageRef, createPageScaleFactor, createPageZoomFactor, createPoint, createQuad, createRect, createScrollOffset, createSessionRef, createSize, createWorkerRef, filterCookieRecords, findDomSnapshotNode, findDomSnapshotNodeByRef, hasCapability, isBrowserCoreError, isChooserRef, isDialogRef, isDocumentRef, isDownloadRef, isFrameRef, isNetworkRequestId, isNodeRef, isPageRef, isSessionRef, isWorkerRef, matchesNetworkRecordFilters, mergeBrowserCapabilities, nextDocumentEpoch, noBrowserCapabilities, normalizeCdpShadowRootType, normalizePostLoadTrackerState, parseCdpStringTable, postLoadTrackerHasTrackedNetworkActivitySince, postLoadTrackerIsSettled, quadBounds, rareCdpIntegerValue, rareCdpStringValue, rectContainsPoint, rectToQuad, serializeDocumentEpoch, serializeRef, staleNodeRefError, unsupportedCapabilityError, waitForActionBoundary, waitForCdpVisualStability };
2845
3218
  //# sourceMappingURL=index.js.map
2846
3219
  //# sourceMappingURL=index.js.map