@skrillex1224/playwright-toolkit 2.1.221 → 2.1.223

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
@@ -334,18 +334,18 @@ var fallbackLog = {
334
334
  error: (...args) => console.error(...args),
335
335
  debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
336
336
  };
337
- var resolveLogMethod = (logger14, name) => {
338
- if (logger14 && typeof logger14[name] === "function") {
339
- return logger14[name].bind(logger14);
337
+ var resolveLogMethod = (logger15, name) => {
338
+ if (logger15 && typeof logger15[name] === "function") {
339
+ return logger15[name].bind(logger15);
340
340
  }
341
- if (name === "warning" && logger14 && typeof logger14.warn === "function") {
342
- return logger14.warn.bind(logger14);
341
+ if (name === "warning" && logger15 && typeof logger15.warn === "function") {
342
+ return logger15.warn.bind(logger15);
343
343
  }
344
344
  return fallbackLog[name];
345
345
  };
346
346
  var defaultLogger = null;
347
- var setDefaultLogger = (logger14) => {
348
- defaultLogger = logger14;
347
+ var setDefaultLogger = (logger15) => {
348
+ defaultLogger = logger15;
349
349
  };
350
350
  var resolveLogger = (explicitLogger) => {
351
351
  if (explicitLogger && typeof explicitLogger.info === "function") {
@@ -372,8 +372,8 @@ var colorize = (text, color) => {
372
372
  var createBaseLogger = (prefix = "", explicitLogger) => {
373
373
  const name = prefix ? String(prefix) : "";
374
374
  const dispatch = (methodName, icon, message, color) => {
375
- const logger14 = resolveLogger(explicitLogger);
376
- const logFn = resolveLogMethod(logger14, methodName);
375
+ const logger15 = resolveLogger(explicitLogger);
376
+ const logFn = resolveLogMethod(logger15, methodName);
377
377
  const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
378
378
  const line = formatLine(name, icon, message);
379
379
  const coloredLine = colorize(line, color);
@@ -412,7 +412,6 @@ function createInternalLogger(moduleName, explicitLogger) {
412
412
  },
413
413
  warning(message) {
414
414
  baseLogger.warning(message);
415
- a;
416
415
  },
417
416
  info(message) {
418
417
  baseLogger.info(message);
@@ -658,9 +657,9 @@ var resolveResourceTypeMeta = (domain) => {
658
657
  if (!byType || byType.size === 0) {
659
658
  return { resourceType: "", resourceTypeCounts: void 0 };
660
659
  }
661
- const entries = Array.from(byType.entries()).filter(([type, count]) => type && Number(count) > 0).sort((a2, b) => {
662
- if (Number(b[1]) !== Number(a2[1])) return Number(b[1]) - Number(a2[1]);
663
- return String(a2[0]).localeCompare(String(b[0]));
660
+ const entries = Array.from(byType.entries()).filter(([type, count]) => type && Number(count) > 0).sort((a, b) => {
661
+ if (Number(b[1]) !== Number(a[1])) return Number(b[1]) - Number(a[1]);
662
+ return String(a[0]).localeCompare(String(b[0]));
664
663
  });
665
664
  if (entries.length === 0) {
666
665
  return { resourceType: "", resourceTypeCounts: void 0 };
@@ -750,10 +749,10 @@ var normalizeDomainRows = (hosts) => {
750
749
  resourceTypeCounts: resourceTypeMeta.resourceTypeCounts || void 0
751
750
  });
752
751
  }
753
- rows.sort((a2, b) => {
754
- if (b.totalBytes !== a2.totalBytes) return b.totalBytes - a2.totalBytes;
755
- if (b.requests !== a2.requests) return b.requests - a2.requests;
756
- return String(a2.domain).localeCompare(String(b.domain));
752
+ rows.sort((a, b) => {
753
+ if (b.totalBytes !== a.totalBytes) return b.totalBytes - a.totalBytes;
754
+ if (b.requests !== a.requests) return b.requests - a.requests;
755
+ return String(a.domain).localeCompare(String(b.domain));
757
756
  });
758
757
  return {
759
758
  topDomains: rows.slice(0, MAX_TOP_DOMAINS),
@@ -4907,7 +4906,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
4907
4906
  };
4908
4907
  var getDefaultBaseLogger = () => createBaseLogger("");
4909
4908
  var Logger = {
4910
- setLogger: (logger14) => setDefaultLogger(logger14),
4909
+ setLogger: (logger15) => setDefaultLogger(logger15),
4911
4910
  info: (message) => getDefaultBaseLogger().info(message),
4912
4911
  success: (message) => getDefaultBaseLogger().success(message),
4913
4912
  warning: (message) => getDefaultBaseLogger().warning(message),
@@ -4915,8 +4914,8 @@ var Logger = {
4915
4914
  error: (message) => getDefaultBaseLogger().error(message),
4916
4915
  debug: (message) => getDefaultBaseLogger().debug(message),
4917
4916
  start: (message) => getDefaultBaseLogger().start(message),
4918
- useTemplate: (logger14) => {
4919
- if (logger14) return createTemplateLogger(createBaseLogger("", logger14));
4917
+ useTemplate: (logger15) => {
4918
+ if (logger15) return createTemplateLogger(createBaseLogger("", logger15));
4920
4919
  return createTemplateLogger();
4921
4920
  }
4922
4921
  };
@@ -6245,8 +6244,147 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
6245
6244
  return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
6246
6245
  };
6247
6246
 
6247
+ // src/internals/screenshot-compression.js
6248
+ import { Jimp, JimpMime, ResizeStrategy } from "jimp";
6249
+ var logger13 = createInternalLogger("ScreenshotCompression");
6250
+ var DEFAULT_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
6251
+ var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
6252
+ var DEFAULT_SCREENSHOT_QUALITY = 0.72;
6253
+ var DEFAULT_SCREENSHOT_MIN_QUALITY = 0.38;
6254
+ var DEFAULT_SCREENSHOT_MIN_SCALE = 0.25;
6255
+ var SUPPORTED_SCREENSHOT_OUTPUT_TYPES = /* @__PURE__ */ new Set(["jpeg"]);
6256
+ var toPositiveInteger = (value, fallback = 0) => {
6257
+ const number = Math.floor(Number(value) || 0);
6258
+ return number > 0 ? number : fallback;
6259
+ };
6260
+ var normalizeQuality2 = (value, fallback) => {
6261
+ const number = Number(value);
6262
+ if (!Number.isFinite(number) || number <= 0) return fallback;
6263
+ const normalized = number > 1 ? number / 100 : number;
6264
+ return Math.min(1, Math.max(0.01, normalized));
6265
+ };
6266
+ var normalizeScale = (value, fallback) => {
6267
+ const number = Number(value);
6268
+ if (!Number.isFinite(number) || number <= 0) return fallback;
6269
+ return Math.min(1, Math.max(0.05, number));
6270
+ };
6271
+ var normalizeScreenshotOutputType = (value) => {
6272
+ const raw = String(value || DEFAULT_SCREENSHOT_OUTPUT_TYPE).trim().toLowerCase();
6273
+ const normalized = raw === "jpg" ? "jpeg" : raw;
6274
+ return SUPPORTED_SCREENSHOT_OUTPUT_TYPES.has(normalized) ? normalized : DEFAULT_SCREENSHOT_OUTPUT_TYPE;
6275
+ };
6276
+ var getBase64BytesFromBuffer = (buffer) => Math.ceil(buffer.length / 3) * 4;
6277
+ var toJpegQuality = (value) => Math.round(normalizeQuality2(value, DEFAULT_SCREENSHOT_QUALITY) * 100);
6278
+ var resolveCaptureScreenCompression = (options = {}) => {
6279
+ const explicit = options.compression;
6280
+ const source = explicit && typeof explicit === "object" && !Array.isArray(explicit) ? explicit : {};
6281
+ const enabled = explicit !== false && source.enabled !== false && options.compress !== false;
6282
+ const quality = normalizeQuality2(
6283
+ source.quality ?? options.quality,
6284
+ DEFAULT_SCREENSHOT_QUALITY
6285
+ );
6286
+ const minQuality = Math.min(
6287
+ quality,
6288
+ normalizeQuality2(source.minQuality ?? options.minQuality, DEFAULT_SCREENSHOT_MIN_QUALITY)
6289
+ );
6290
+ return {
6291
+ enabled,
6292
+ maxBytes: toPositiveInteger(
6293
+ source.maxBytes ?? source.maxBase64Bytes ?? options.maxBytes ?? options.maxBase64Bytes,
6294
+ DEFAULT_SCREENSHOT_MAX_BYTES
6295
+ ),
6296
+ outputType: normalizeScreenshotOutputType(
6297
+ source.type ?? source.outputType ?? options.type ?? options.outputType
6298
+ ),
6299
+ quality,
6300
+ minQuality,
6301
+ minScale: normalizeScale(
6302
+ source.minScale ?? options.minScale,
6303
+ DEFAULT_SCREENSHOT_MIN_SCALE
6304
+ )
6305
+ };
6306
+ };
6307
+ var encodeJpeg = async (sourceImage, compression, scale, quality) => {
6308
+ const width = Math.max(1, Math.round(sourceImage.bitmap.width * scale));
6309
+ const height = Math.max(1, Math.round(sourceImage.bitmap.height * scale));
6310
+ const image = sourceImage.clone();
6311
+ if (scale < 0.999) {
6312
+ image.resize({
6313
+ w: width,
6314
+ h: height,
6315
+ mode: ResizeStrategy.BILINEAR
6316
+ });
6317
+ }
6318
+ const buffer = await image.getBuffer(JimpMime.jpeg, { quality });
6319
+ return {
6320
+ buffer,
6321
+ bytes: getBase64BytesFromBuffer(buffer),
6322
+ width,
6323
+ height,
6324
+ quality,
6325
+ scale: Number(scale.toFixed(3)),
6326
+ format: compression.outputType
6327
+ };
6328
+ };
6329
+ var compressScreenshotBuffer = async (buffer, compression) => {
6330
+ const sourceImage = await Jimp.read(buffer);
6331
+ const maxQuality = toJpegQuality(compression.quality);
6332
+ const minQuality = Math.min(maxQuality, toJpegQuality(compression.minQuality));
6333
+ let quality = maxQuality;
6334
+ let scale = 1;
6335
+ let smallest = null;
6336
+ for (let attempt = 0; attempt < 12; attempt += 1) {
6337
+ const candidate = await encodeJpeg(sourceImage, compression, scale, quality);
6338
+ if (!smallest || candidate.bytes < smallest.bytes) {
6339
+ smallest = candidate;
6340
+ }
6341
+ if (candidate.bytes <= compression.maxBytes) {
6342
+ return { ...candidate, withinLimit: true };
6343
+ }
6344
+ if (quality > minQuality) {
6345
+ quality = Math.max(minQuality, Math.floor(quality * 0.75));
6346
+ continue;
6347
+ }
6348
+ const ratio = Math.sqrt(compression.maxBytes / Math.max(1, candidate.bytes));
6349
+ const nextScale = Math.max(
6350
+ compression.minScale,
6351
+ Math.min(scale * 0.85, scale * ratio * 0.94)
6352
+ );
6353
+ if (nextScale >= scale * 0.99 || scale <= compression.minScale) {
6354
+ break;
6355
+ }
6356
+ scale = nextScale;
6357
+ }
6358
+ const finalCandidate = await encodeJpeg(sourceImage, compression, compression.minScale, minQuality);
6359
+ const fallback = !smallest || finalCandidate.bytes < smallest.bytes ? finalCandidate : smallest;
6360
+ return { ...fallback, withinLimit: fallback.bytes <= compression.maxBytes };
6361
+ };
6362
+ var compressScreenshotBufferToBase64 = async (buffer, compression) => {
6363
+ const originalBytes = getBase64BytesFromBuffer(buffer);
6364
+ if (!compression.enabled || originalBytes <= compression.maxBytes) {
6365
+ return buffer.toString("base64");
6366
+ }
6367
+ const result = await compressScreenshotBuffer(buffer, compression).catch((error) => {
6368
+ logger13.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
6369
+ return null;
6370
+ });
6371
+ if (!result?.buffer) {
6372
+ return buffer.toString("base64");
6373
+ }
6374
+ if (result.withinLimit) {
6375
+ logger13.info(
6376
+ `captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
6377
+ );
6378
+ } else {
6379
+ logger13.warning(
6380
+ `captureScreen \u538B\u7F29\u540E\u4ECD\u8D85\u8FC7\u76EE\u6807: ${originalBytes} -> ${result.bytes} bytes, maxBytes=${compression.maxBytes}, format=${result.format}, quality=${result.quality}, scale=${result.scale}`
6381
+ );
6382
+ }
6383
+ return result.buffer.toString("base64");
6384
+ };
6385
+
6248
6386
  // src/share.js
6249
- var logger13 = createInternalLogger("Share");
6387
+ var logger14 = createInternalLogger("Share");
6250
6388
  var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
6251
6389
  var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
6252
6390
  var DEFAULT_POLL_INTERVAL_MS = 120;
@@ -6383,7 +6521,7 @@ var createDomShareMonitor = async (page, options = {}) => {
6383
6521
  const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
6384
6522
  const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
6385
6523
  let matched = false;
6386
- logger13.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
6524
+ logger14.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
6387
6525
  const monitor = await Mutation.useMonitor(page, selectors, {
6388
6526
  mode,
6389
6527
  onMutation: (context = {}) => {
@@ -6401,12 +6539,12 @@ ${text}`;
6401
6539
  });
6402
6540
  }
6403
6541
  if (mutationCount <= 5 || mutationCount % 50 === 0) {
6404
- logger13.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
6542
+ logger14.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
6405
6543
  }
6406
6544
  const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
6407
6545
  if (!candidate) return;
6408
6546
  matched = true;
6409
- logger13.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
6547
+ logger14.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
6410
6548
  if (onMatch) {
6411
6549
  onMatch({
6412
6550
  link: candidate,
@@ -6422,7 +6560,7 @@ ${text}`;
6422
6560
  return {
6423
6561
  stop: async () => {
6424
6562
  const result = await monitor.stop();
6425
- logger13.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
6563
+ logger14.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
6426
6564
  return result;
6427
6565
  }
6428
6566
  };
@@ -6462,8 +6600,8 @@ var Share = {
6462
6600
  if (share.mode === "response" && apiMatchers.length === 0) {
6463
6601
  throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
6464
6602
  }
6465
- logger13.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
6466
- logger13.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
6603
+ logger14.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
6604
+ logger14.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
6467
6605
  const stats = {
6468
6606
  actionTimedOut: false,
6469
6607
  domMutationCount: 0,
@@ -6488,7 +6626,7 @@ var Share = {
6488
6626
  link: validated,
6489
6627
  payloadText: String(payloadText || "")
6490
6628
  };
6491
- logger13.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
6629
+ logger14.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
6492
6630
  return true;
6493
6631
  };
6494
6632
  const resolveResponseCandidate = (responseText) => {
@@ -6523,7 +6661,7 @@ var Share = {
6523
6661
  try {
6524
6662
  await monitor.stop();
6525
6663
  } catch (error) {
6526
- logger13.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
6664
+ logger14.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
6527
6665
  }
6528
6666
  };
6529
6667
  const onResponse = async (response) => {
@@ -6536,29 +6674,29 @@ var Share = {
6536
6674
  stats.responseSampleUrls.push(url);
6537
6675
  }
6538
6676
  if (stats.responseObserved <= 5) {
6539
- logger13.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
6677
+ logger14.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
6540
6678
  }
6541
6679
  if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
6542
6680
  stats.responseMatched += 1;
6543
6681
  stats.lastMatchedUrl = url;
6544
- logger13.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
6682
+ logger14.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
6545
6683
  const text = await response.text();
6546
6684
  const hit = resolveResponseCandidate(text);
6547
6685
  if (!hit?.link) {
6548
6686
  if (stats.responseMatched <= 3) {
6549
- logger13.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
6687
+ logger14.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
6550
6688
  }
6551
6689
  return;
6552
6690
  }
6553
6691
  stats.responseResolved += 1;
6554
- logger13.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
6692
+ logger14.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
6555
6693
  setCandidate("response", hit.link, hit.payloadText);
6556
6694
  } catch (error) {
6557
- logger13.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
6695
+ logger14.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
6558
6696
  }
6559
6697
  };
6560
6698
  if (share.mode === "dom") {
6561
- logger13.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
6699
+ logger14.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
6562
6700
  domMonitor = await createDomShareMonitor(page, {
6563
6701
  prefix: share.prefix,
6564
6702
  selectors: domSelectors,
@@ -6573,14 +6711,14 @@ var Share = {
6573
6711
  });
6574
6712
  }
6575
6713
  if (share.mode === "response") {
6576
- logger13.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
6714
+ logger14.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
6577
6715
  page.on("response", onResponse);
6578
6716
  }
6579
6717
  const deadline = Date.now() + timeoutMs;
6580
6718
  const getRemainingMs = () => Math.max(0, deadline - Date.now());
6581
6719
  try {
6582
6720
  const actionTimeout = getRemainingMs();
6583
- logger13.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
6721
+ logger14.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
6584
6722
  if (actionTimeout > 0) {
6585
6723
  let timer = null;
6586
6724
  let actionError = null;
@@ -6594,21 +6732,21 @@ var Share = {
6594
6732
  const actionResult = await Promise.race([actionPromise, timeoutPromise]);
6595
6733
  if (timer) clearTimeout(timer);
6596
6734
  if (actionResult === "__ACTION_ERROR__") {
6597
- logger13.fail("captureLink.performActions", actionError);
6735
+ logger14.fail("captureLink.performActions", actionError);
6598
6736
  throw actionError;
6599
6737
  }
6600
6738
  if (actionResult === "__ACTION_TIMEOUT__") {
6601
6739
  stats.actionTimedOut = true;
6602
- logger13.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
6740
+ logger14.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
6603
6741
  } else {
6604
- logger13.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
6742
+ logger14.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
6605
6743
  }
6606
6744
  }
6607
6745
  let nextProgressLogTs = Date.now() + 3e3;
6608
6746
  while (true) {
6609
6747
  const selected = share.mode === "dom" ? candidates.dom : candidates.response;
6610
6748
  if (selected?.link) {
6611
- logger13.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
6749
+ logger14.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
6612
6750
  return {
6613
6751
  link: selected.link,
6614
6752
  payloadText: selected.payloadText,
@@ -6620,7 +6758,7 @@ var Share = {
6620
6758
  if (remaining <= 0) break;
6621
6759
  const now = Date.now();
6622
6760
  if (now >= nextProgressLogTs) {
6623
- logger13.info(
6761
+ logger14.info(
6624
6762
  `captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
6625
6763
  );
6626
6764
  nextProgressLogTs = now + 5e3;
@@ -6628,11 +6766,11 @@ var Share = {
6628
6766
  await delay2(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
6629
6767
  }
6630
6768
  if (share.mode === "response" && stats.responseMatched === 0) {
6631
- logger13.warning(
6769
+ logger14.warning(
6632
6770
  `\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
6633
6771
  );
6634
6772
  }
6635
- logger13.warning(
6773
+ logger14.warning(
6636
6774
  `captureLink \u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
6637
6775
  );
6638
6776
  return {
@@ -6644,7 +6782,7 @@ var Share = {
6644
6782
  } finally {
6645
6783
  if (share.mode === "response") {
6646
6784
  page.off("response", onResponse);
6647
- logger13.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
6785
+ logger14.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
6648
6786
  }
6649
6787
  await stopDomMonitor();
6650
6788
  }
@@ -6657,7 +6795,10 @@ var Share = {
6657
6795
  * @param {number} [options.buffer]
6658
6796
  * @param {boolean} [options.restore]
6659
6797
  * @param {number} [options.maxHeight]
6660
- * @returns {Promise<string>} base64 png
6798
+ * @param {number} [options.maxBytes] 默认 8MiB,返回 base64 超过后会压缩
6799
+ * @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
6800
+ * @param {boolean|Object} [options.compression] 传 false 可关闭压缩
6801
+ * @returns {Promise<string>} base64 image
6661
6802
  */
6662
6803
  async captureScreen(page, options = {}) {
6663
6804
  const originalViewport = await resolveCurrentViewportSize(page);
@@ -6666,6 +6807,7 @@ var Share = {
6666
6807
  const restore = options.restore ?? false;
6667
6808
  const maxHeight = options.maxHeight ?? 8e3;
6668
6809
  const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
6810
+ const compression = resolveCaptureScreenCompression(options);
6669
6811
  try {
6670
6812
  const maxScrollHeight = await page.evaluate(() => {
6671
6813
  let maxHeight2 = document.body.scrollHeight;
@@ -6699,15 +6841,15 @@ var Share = {
6699
6841
  type: "png",
6700
6842
  maxClipHeight: targetHeight
6701
6843
  });
6702
- if (!screenshotWatermarkify.enabled) {
6703
- return rawBuffer.toString("base64");
6844
+ let outputBuffer = rawBuffer;
6845
+ if (screenshotWatermarkify.enabled) {
6846
+ const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
6847
+ ...screenshotWatermarkify,
6848
+ capturedAt
6849
+ });
6850
+ outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
6704
6851
  }
6705
- const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
6706
- ...screenshotWatermarkify,
6707
- capturedAt
6708
- });
6709
- const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
6710
- return buffer_.toString("base64");
6852
+ return await compressScreenshotBufferToBase64(outputBuffer, compression);
6711
6853
  } finally {
6712
6854
  if (restore) {
6713
6855
  await page.evaluate(() => {