@grabbit-labs/dynafetch 0.2.5 → 0.2.7

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 CHANGED
@@ -119,7 +119,7 @@ const page = await dynafetch({
119
119
  |-|-|-|
120
120
  | `minWaitMs` | `75` | Minimum ms before checking idle state |
121
121
  | `idleWaitMs` | `100` | Ms of zero pending requests to consider settled |
122
- | `maxWaitMs` | `2000` | Hard cap on wait time |
122
+ | `maxWaitMs` | `3000` | Hard cap on wait time |
123
123
  | `moduleWaitMs` | `6000` | Max wait for ES module bundling |
124
124
  | `timeoutMs` | none | Overall operation timeout |
125
125
 
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/index.js CHANGED
@@ -829,9 +829,11 @@ function shouldSkipDynamicScriptUrl(url, pageUrl, policy) {
829
829
  // ../../src/phantom/execute.ts
830
830
  var esbuildModulePromise = null;
831
831
  var esbuildRefCount = 0;
832
+ var runtimeImport = new Function("specifier", "return import(specifier)");
833
+ var ESBUILD_MODULE_NAME = Buffer.from("ZXNidWlsZA==", "base64").toString("utf8");
832
834
  async function acquireEsbuildModule() {
833
835
  if (!esbuildModulePromise) {
834
- esbuildModulePromise = import("esbuild");
836
+ esbuildModulePromise = runtimeImport(ESBUILD_MODULE_NAME);
835
837
  }
836
838
  esbuildRefCount++;
837
839
  try {
@@ -890,6 +892,8 @@ var Executor = class {
890
892
  this.originalGlobalMessageChannel = void 0;
891
893
  this.originalGlobalMessagePort = void 0;
892
894
  this.activeTimerHandles = /* @__PURE__ */ new Set();
895
+ this.domMutationVersion = 0;
896
+ this.domMutationObserver = null;
893
897
  // Simple telemetry counters (useful for debugging).
894
898
  this.telemetry_stubbed = 0;
895
899
  this.telemetry_proxy = 0;
@@ -1008,6 +1012,29 @@ var Executor = class {
1008
1012
  }
1009
1013
  this.activeTimerHandles.clear();
1010
1014
  }
1015
+ noteDomMutation() {
1016
+ this.domMutationVersion++;
1017
+ }
1018
+ async waitForDomSettle(window) {
1019
+ const quietMs = this.clampMs(
1020
+ Number(process.env.PHANTOM_DOM_SETTLE_MS ?? Math.max(this.quiescenceOptions.idleWaitMs * 4, 400)),
1021
+ 50,
1022
+ 5e3
1023
+ );
1024
+ const maxMs = this.clampMs(
1025
+ Number(process.env.PHANTOM_DOM_SETTLE_MAX_MS ?? Math.max(quietMs * 4, 2e3)),
1026
+ quietMs,
1027
+ 1e4
1028
+ );
1029
+ const start = Date.now();
1030
+ let seenVersion = this.domMutationVersion;
1031
+ while (!this.windowClosed) {
1032
+ await new Promise((resolve) => setTimeout(resolve, quietMs));
1033
+ if (this.domMutationVersion === seenVersion) return;
1034
+ seenVersion = this.domMutationVersion;
1035
+ if (Date.now() - start >= maxMs) return;
1036
+ }
1037
+ }
1011
1038
  async performAutoScroll(window) {
1012
1039
  const steps = this.clampMs(Number(process.env.PHANTOM_AUTO_SCROLL_STEPS ?? 3), 0, 12);
1013
1040
  if (steps === 0) return false;
@@ -1065,7 +1092,7 @@ var Executor = class {
1065
1092
  const hardMaxCap = this.clampMs(Number(process.env.PHANTOM_QUIESCENCE_MAX_CAP_MS ?? 8e3), 500, 6e4);
1066
1093
  const minWaitMs = this.clampMs(quiescence?.minWaitMs ?? 75, 0, 1e4);
1067
1094
  const idleWaitMs = this.clampMs(quiescence?.idleWaitMs ?? 100, 0, 1e4);
1068
- const maxWaitMs = this.clampMs(quiescence?.maxWaitMs ?? 2e3, 0, hardMaxCap);
1095
+ const maxWaitMs = this.clampMs(quiescence?.maxWaitMs ?? 3e3, 0, hardMaxCap);
1069
1096
  const hardModuleCap = this.clampMs(Number(process.env.PHANTOM_MODULE_WAIT_MAX_CAP_MS ?? 3e4), 1e3, 12e4);
1070
1097
  this.moduleWaitMs = this.clampMs(Number(process.env.PHANTOM_MODULE_WAIT_MS ?? moduleWaitMsOverride ?? 6e3), 1e3, hardModuleCap);
1071
1098
  this.quiescenceOptions = { minWaitMs, idleWaitMs, maxWaitMs };
@@ -2272,6 +2299,23 @@ var Executor = class {
2272
2299
  }
2273
2300
  });
2274
2301
  const { window } = dom;
2302
+ this.domMutationVersion = 0;
2303
+ try {
2304
+ const MutationObserverCtor = window.MutationObserver;
2305
+ const targetNode = window.document?.documentElement || window.document?.body;
2306
+ if (MutationObserverCtor && targetNode) {
2307
+ this.domMutationObserver = new MutationObserverCtor(() => {
2308
+ this.noteDomMutation();
2309
+ });
2310
+ this.domMutationObserver.observe(targetNode, {
2311
+ subtree: true,
2312
+ childList: true,
2313
+ characterData: true,
2314
+ attributes: true
2315
+ });
2316
+ }
2317
+ } catch {
2318
+ }
2275
2319
  let readyStateValue = "loading";
2276
2320
  try {
2277
2321
  Object.defineProperty(window.document, "readyState", {
@@ -2414,6 +2458,11 @@ var Executor = class {
2414
2458
  this.timings.quiescence_ms += Date.now() - postScrollStart;
2415
2459
  }
2416
2460
  }
2461
+ try {
2462
+ await this.waitForDomSettle(window);
2463
+ } catch (e) {
2464
+ warn("[Executor] DOM settle wait failed:", e);
2465
+ }
2417
2466
  const renderedHtml = this.serializeDocument(window);
2418
2467
  this.windowClosed = true;
2419
2468
  const result = {
@@ -2430,6 +2479,11 @@ var Executor = class {
2430
2479
  this.unrefNewMessagePorts(initialActiveHandles);
2431
2480
  return result;
2432
2481
  } finally {
2482
+ try {
2483
+ this.domMutationObserver?.disconnect?.();
2484
+ } catch {
2485
+ }
2486
+ this.domMutationObserver = null;
2433
2487
  const g = globalThis;
2434
2488
  if (this.originalGlobalMessageChannel !== void 0) {
2435
2489
  g.MessageChannel = this.originalGlobalMessageChannel;