@skrillex1224/playwright-toolkit 2.1.222 → 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/README.md CHANGED
@@ -210,6 +210,7 @@ const cookies = Utils.parseCookies('key=value; key2=value2', '.example.com');
210
210
  await page.context().addCookies(cookies);
211
211
 
212
212
  // 全页面滚动截图 (自动检测所有滚动元素,强制展开后截图,默认会执行 watermarkify)
213
+ // 默认会将返回的 base64 压缩到 8MiB 以内,避免 Apify/Crawlee dataset 单条 item 超限
213
214
  const base64Image = await Share.captureScreen(page);
214
215
 
215
216
  // 移动端宽度截图(moblie 拼写保持兼容)
@@ -249,7 +250,14 @@ const image4 = await Share.captureScreen(page, {
249
250
  const image5 = await Share.captureScreen(page, {
250
251
  watermarkify: false,
251
252
  });
252
- // 返回 base64 编码的 PNG 图片
253
+ // 指定更小的返回体积。内部使用 Jimp 重编码:优先降 JPEG 质量,仍超限时再等比缩放。
254
+ const image6 = await Share.captureScreen(page, {
255
+ maxBytes: 4 * 1024 * 1024,
256
+ quality: 60,
257
+ minQuality: 35,
258
+ outputType: 'jpeg',
259
+ });
260
+ // 返回 base64 编码图片,默认输出会在超限时转为 JPEG 压缩
253
261
  ```
254
262
 
255
263
  ---
package/dist/index.cjs CHANGED
@@ -361,18 +361,18 @@ var fallbackLog = {
361
361
  error: (...args) => console.error(...args),
362
362
  debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
363
363
  };
364
- var resolveLogMethod = (logger14, name) => {
365
- if (logger14 && typeof logger14[name] === "function") {
366
- return logger14[name].bind(logger14);
364
+ var resolveLogMethod = (logger15, name) => {
365
+ if (logger15 && typeof logger15[name] === "function") {
366
+ return logger15[name].bind(logger15);
367
367
  }
368
- if (name === "warning" && logger14 && typeof logger14.warn === "function") {
369
- return logger14.warn.bind(logger14);
368
+ if (name === "warning" && logger15 && typeof logger15.warn === "function") {
369
+ return logger15.warn.bind(logger15);
370
370
  }
371
371
  return fallbackLog[name];
372
372
  };
373
373
  var defaultLogger = null;
374
- var setDefaultLogger = (logger14) => {
375
- defaultLogger = logger14;
374
+ var setDefaultLogger = (logger15) => {
375
+ defaultLogger = logger15;
376
376
  };
377
377
  var resolveLogger = (explicitLogger) => {
378
378
  if (explicitLogger && typeof explicitLogger.info === "function") {
@@ -399,8 +399,8 @@ var colorize = (text, color) => {
399
399
  var createBaseLogger = (prefix = "", explicitLogger) => {
400
400
  const name = prefix ? String(prefix) : "";
401
401
  const dispatch = (methodName, icon, message, color) => {
402
- const logger14 = resolveLogger(explicitLogger);
403
- const logFn = resolveLogMethod(logger14, methodName);
402
+ const logger15 = resolveLogger(explicitLogger);
403
+ const logFn = resolveLogMethod(logger15, methodName);
404
404
  const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
405
405
  const line = formatLine(name, icon, message);
406
406
  const coloredLine = colorize(line, color);
@@ -4934,7 +4934,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
4934
4934
  };
4935
4935
  var getDefaultBaseLogger = () => createBaseLogger("");
4936
4936
  var Logger = {
4937
- setLogger: (logger14) => setDefaultLogger(logger14),
4937
+ setLogger: (logger15) => setDefaultLogger(logger15),
4938
4938
  info: (message) => getDefaultBaseLogger().info(message),
4939
4939
  success: (message) => getDefaultBaseLogger().success(message),
4940
4940
  warning: (message) => getDefaultBaseLogger().warning(message),
@@ -4942,8 +4942,8 @@ var Logger = {
4942
4942
  error: (message) => getDefaultBaseLogger().error(message),
4943
4943
  debug: (message) => getDefaultBaseLogger().debug(message),
4944
4944
  start: (message) => getDefaultBaseLogger().start(message),
4945
- useTemplate: (logger14) => {
4946
- if (logger14) return createTemplateLogger(createBaseLogger("", logger14));
4945
+ useTemplate: (logger15) => {
4946
+ if (logger15) return createTemplateLogger(createBaseLogger("", logger15));
4947
4947
  return createTemplateLogger();
4948
4948
  }
4949
4949
  };
@@ -6272,8 +6272,147 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
6272
6272
  return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
6273
6273
  };
6274
6274
 
6275
+ // src/internals/screenshot-compression.js
6276
+ var import_jimp = require("jimp");
6277
+ var logger13 = createInternalLogger("ScreenshotCompression");
6278
+ var DEFAULT_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
6279
+ var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
6280
+ var DEFAULT_SCREENSHOT_QUALITY = 0.72;
6281
+ var DEFAULT_SCREENSHOT_MIN_QUALITY = 0.38;
6282
+ var DEFAULT_SCREENSHOT_MIN_SCALE = 0.25;
6283
+ var SUPPORTED_SCREENSHOT_OUTPUT_TYPES = /* @__PURE__ */ new Set(["jpeg"]);
6284
+ var toPositiveInteger = (value, fallback = 0) => {
6285
+ const number = Math.floor(Number(value) || 0);
6286
+ return number > 0 ? number : fallback;
6287
+ };
6288
+ var normalizeQuality2 = (value, fallback) => {
6289
+ const number = Number(value);
6290
+ if (!Number.isFinite(number) || number <= 0) return fallback;
6291
+ const normalized = number > 1 ? number / 100 : number;
6292
+ return Math.min(1, Math.max(0.01, normalized));
6293
+ };
6294
+ var normalizeScale = (value, fallback) => {
6295
+ const number = Number(value);
6296
+ if (!Number.isFinite(number) || number <= 0) return fallback;
6297
+ return Math.min(1, Math.max(0.05, number));
6298
+ };
6299
+ var normalizeScreenshotOutputType = (value) => {
6300
+ const raw = String(value || DEFAULT_SCREENSHOT_OUTPUT_TYPE).trim().toLowerCase();
6301
+ const normalized = raw === "jpg" ? "jpeg" : raw;
6302
+ return SUPPORTED_SCREENSHOT_OUTPUT_TYPES.has(normalized) ? normalized : DEFAULT_SCREENSHOT_OUTPUT_TYPE;
6303
+ };
6304
+ var getBase64BytesFromBuffer = (buffer) => Math.ceil(buffer.length / 3) * 4;
6305
+ var toJpegQuality = (value) => Math.round(normalizeQuality2(value, DEFAULT_SCREENSHOT_QUALITY) * 100);
6306
+ var resolveCaptureScreenCompression = (options = {}) => {
6307
+ const explicit = options.compression;
6308
+ const source = explicit && typeof explicit === "object" && !Array.isArray(explicit) ? explicit : {};
6309
+ const enabled = explicit !== false && source.enabled !== false && options.compress !== false;
6310
+ const quality = normalizeQuality2(
6311
+ source.quality ?? options.quality,
6312
+ DEFAULT_SCREENSHOT_QUALITY
6313
+ );
6314
+ const minQuality = Math.min(
6315
+ quality,
6316
+ normalizeQuality2(source.minQuality ?? options.minQuality, DEFAULT_SCREENSHOT_MIN_QUALITY)
6317
+ );
6318
+ return {
6319
+ enabled,
6320
+ maxBytes: toPositiveInteger(
6321
+ source.maxBytes ?? source.maxBase64Bytes ?? options.maxBytes ?? options.maxBase64Bytes,
6322
+ DEFAULT_SCREENSHOT_MAX_BYTES
6323
+ ),
6324
+ outputType: normalizeScreenshotOutputType(
6325
+ source.type ?? source.outputType ?? options.type ?? options.outputType
6326
+ ),
6327
+ quality,
6328
+ minQuality,
6329
+ minScale: normalizeScale(
6330
+ source.minScale ?? options.minScale,
6331
+ DEFAULT_SCREENSHOT_MIN_SCALE
6332
+ )
6333
+ };
6334
+ };
6335
+ var encodeJpeg = async (sourceImage, compression, scale, quality) => {
6336
+ const width = Math.max(1, Math.round(sourceImage.bitmap.width * scale));
6337
+ const height = Math.max(1, Math.round(sourceImage.bitmap.height * scale));
6338
+ const image = sourceImage.clone();
6339
+ if (scale < 0.999) {
6340
+ image.resize({
6341
+ w: width,
6342
+ h: height,
6343
+ mode: import_jimp.ResizeStrategy.BILINEAR
6344
+ });
6345
+ }
6346
+ const buffer = await image.getBuffer(import_jimp.JimpMime.jpeg, { quality });
6347
+ return {
6348
+ buffer,
6349
+ bytes: getBase64BytesFromBuffer(buffer),
6350
+ width,
6351
+ height,
6352
+ quality,
6353
+ scale: Number(scale.toFixed(3)),
6354
+ format: compression.outputType
6355
+ };
6356
+ };
6357
+ var compressScreenshotBuffer = async (buffer, compression) => {
6358
+ const sourceImage = await import_jimp.Jimp.read(buffer);
6359
+ const maxQuality = toJpegQuality(compression.quality);
6360
+ const minQuality = Math.min(maxQuality, toJpegQuality(compression.minQuality));
6361
+ let quality = maxQuality;
6362
+ let scale = 1;
6363
+ let smallest = null;
6364
+ for (let attempt = 0; attempt < 12; attempt += 1) {
6365
+ const candidate = await encodeJpeg(sourceImage, compression, scale, quality);
6366
+ if (!smallest || candidate.bytes < smallest.bytes) {
6367
+ smallest = candidate;
6368
+ }
6369
+ if (candidate.bytes <= compression.maxBytes) {
6370
+ return { ...candidate, withinLimit: true };
6371
+ }
6372
+ if (quality > minQuality) {
6373
+ quality = Math.max(minQuality, Math.floor(quality * 0.75));
6374
+ continue;
6375
+ }
6376
+ const ratio = Math.sqrt(compression.maxBytes / Math.max(1, candidate.bytes));
6377
+ const nextScale = Math.max(
6378
+ compression.minScale,
6379
+ Math.min(scale * 0.85, scale * ratio * 0.94)
6380
+ );
6381
+ if (nextScale >= scale * 0.99 || scale <= compression.minScale) {
6382
+ break;
6383
+ }
6384
+ scale = nextScale;
6385
+ }
6386
+ const finalCandidate = await encodeJpeg(sourceImage, compression, compression.minScale, minQuality);
6387
+ const fallback = !smallest || finalCandidate.bytes < smallest.bytes ? finalCandidate : smallest;
6388
+ return { ...fallback, withinLimit: fallback.bytes <= compression.maxBytes };
6389
+ };
6390
+ var compressScreenshotBufferToBase64 = async (buffer, compression) => {
6391
+ const originalBytes = getBase64BytesFromBuffer(buffer);
6392
+ if (!compression.enabled || originalBytes <= compression.maxBytes) {
6393
+ return buffer.toString("base64");
6394
+ }
6395
+ const result = await compressScreenshotBuffer(buffer, compression).catch((error) => {
6396
+ logger13.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
6397
+ return null;
6398
+ });
6399
+ if (!result?.buffer) {
6400
+ return buffer.toString("base64");
6401
+ }
6402
+ if (result.withinLimit) {
6403
+ logger13.info(
6404
+ `captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
6405
+ );
6406
+ } else {
6407
+ logger13.warning(
6408
+ `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}`
6409
+ );
6410
+ }
6411
+ return result.buffer.toString("base64");
6412
+ };
6413
+
6275
6414
  // src/share.js
6276
- var logger13 = createInternalLogger("Share");
6415
+ var logger14 = createInternalLogger("Share");
6277
6416
  var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
6278
6417
  var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
6279
6418
  var DEFAULT_POLL_INTERVAL_MS = 120;
@@ -6410,7 +6549,7 @@ var createDomShareMonitor = async (page, options = {}) => {
6410
6549
  const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
6411
6550
  const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
6412
6551
  let matched = false;
6413
- logger13.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
6552
+ logger14.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
6414
6553
  const monitor = await Mutation.useMonitor(page, selectors, {
6415
6554
  mode,
6416
6555
  onMutation: (context = {}) => {
@@ -6428,12 +6567,12 @@ ${text}`;
6428
6567
  });
6429
6568
  }
6430
6569
  if (mutationCount <= 5 || mutationCount % 50 === 0) {
6431
- logger13.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
6570
+ logger14.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
6432
6571
  }
6433
6572
  const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
6434
6573
  if (!candidate) return;
6435
6574
  matched = true;
6436
- logger13.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
6575
+ logger14.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
6437
6576
  if (onMatch) {
6438
6577
  onMatch({
6439
6578
  link: candidate,
@@ -6449,7 +6588,7 @@ ${text}`;
6449
6588
  return {
6450
6589
  stop: async () => {
6451
6590
  const result = await monitor.stop();
6452
- logger13.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
6591
+ logger14.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
6453
6592
  return result;
6454
6593
  }
6455
6594
  };
@@ -6489,8 +6628,8 @@ var Share = {
6489
6628
  if (share.mode === "response" && apiMatchers.length === 0) {
6490
6629
  throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
6491
6630
  }
6492
- logger13.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
6493
- logger13.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
6631
+ logger14.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
6632
+ logger14.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
6494
6633
  const stats = {
6495
6634
  actionTimedOut: false,
6496
6635
  domMutationCount: 0,
@@ -6515,7 +6654,7 @@ var Share = {
6515
6654
  link: validated,
6516
6655
  payloadText: String(payloadText || "")
6517
6656
  };
6518
- logger13.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
6657
+ logger14.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
6519
6658
  return true;
6520
6659
  };
6521
6660
  const resolveResponseCandidate = (responseText) => {
@@ -6550,7 +6689,7 @@ var Share = {
6550
6689
  try {
6551
6690
  await monitor.stop();
6552
6691
  } catch (error) {
6553
- logger13.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
6692
+ logger14.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
6554
6693
  }
6555
6694
  };
6556
6695
  const onResponse = async (response) => {
@@ -6563,29 +6702,29 @@ var Share = {
6563
6702
  stats.responseSampleUrls.push(url);
6564
6703
  }
6565
6704
  if (stats.responseObserved <= 5) {
6566
- logger13.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
6705
+ logger14.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
6567
6706
  }
6568
6707
  if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
6569
6708
  stats.responseMatched += 1;
6570
6709
  stats.lastMatchedUrl = url;
6571
- logger13.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
6710
+ logger14.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
6572
6711
  const text = await response.text();
6573
6712
  const hit = resolveResponseCandidate(text);
6574
6713
  if (!hit?.link) {
6575
6714
  if (stats.responseMatched <= 3) {
6576
- logger13.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
6715
+ logger14.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
6577
6716
  }
6578
6717
  return;
6579
6718
  }
6580
6719
  stats.responseResolved += 1;
6581
- logger13.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
6720
+ logger14.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
6582
6721
  setCandidate("response", hit.link, hit.payloadText);
6583
6722
  } catch (error) {
6584
- logger13.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
6723
+ logger14.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
6585
6724
  }
6586
6725
  };
6587
6726
  if (share.mode === "dom") {
6588
- logger13.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
6727
+ logger14.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
6589
6728
  domMonitor = await createDomShareMonitor(page, {
6590
6729
  prefix: share.prefix,
6591
6730
  selectors: domSelectors,
@@ -6600,14 +6739,14 @@ var Share = {
6600
6739
  });
6601
6740
  }
6602
6741
  if (share.mode === "response") {
6603
- logger13.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
6742
+ logger14.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
6604
6743
  page.on("response", onResponse);
6605
6744
  }
6606
6745
  const deadline = Date.now() + timeoutMs;
6607
6746
  const getRemainingMs = () => Math.max(0, deadline - Date.now());
6608
6747
  try {
6609
6748
  const actionTimeout = getRemainingMs();
6610
- logger13.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
6749
+ logger14.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
6611
6750
  if (actionTimeout > 0) {
6612
6751
  let timer = null;
6613
6752
  let actionError = null;
@@ -6621,21 +6760,21 @@ var Share = {
6621
6760
  const actionResult = await Promise.race([actionPromise, timeoutPromise]);
6622
6761
  if (timer) clearTimeout(timer);
6623
6762
  if (actionResult === "__ACTION_ERROR__") {
6624
- logger13.fail("captureLink.performActions", actionError);
6763
+ logger14.fail("captureLink.performActions", actionError);
6625
6764
  throw actionError;
6626
6765
  }
6627
6766
  if (actionResult === "__ACTION_TIMEOUT__") {
6628
6767
  stats.actionTimedOut = true;
6629
- logger13.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
6768
+ logger14.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
6630
6769
  } else {
6631
- logger13.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
6770
+ logger14.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
6632
6771
  }
6633
6772
  }
6634
6773
  let nextProgressLogTs = Date.now() + 3e3;
6635
6774
  while (true) {
6636
6775
  const selected = share.mode === "dom" ? candidates.dom : candidates.response;
6637
6776
  if (selected?.link) {
6638
- logger13.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
6777
+ logger14.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
6639
6778
  return {
6640
6779
  link: selected.link,
6641
6780
  payloadText: selected.payloadText,
@@ -6647,7 +6786,7 @@ var Share = {
6647
6786
  if (remaining <= 0) break;
6648
6787
  const now = Date.now();
6649
6788
  if (now >= nextProgressLogTs) {
6650
- logger13.info(
6789
+ logger14.info(
6651
6790
  `captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
6652
6791
  );
6653
6792
  nextProgressLogTs = now + 5e3;
@@ -6655,11 +6794,11 @@ var Share = {
6655
6794
  await (0, import_delay2.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
6656
6795
  }
6657
6796
  if (share.mode === "response" && stats.responseMatched === 0) {
6658
- logger13.warning(
6797
+ logger14.warning(
6659
6798
  `\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
6660
6799
  );
6661
6800
  }
6662
- logger13.warning(
6801
+ logger14.warning(
6663
6802
  `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"}`
6664
6803
  );
6665
6804
  return {
@@ -6671,7 +6810,7 @@ var Share = {
6671
6810
  } finally {
6672
6811
  if (share.mode === "response") {
6673
6812
  page.off("response", onResponse);
6674
- logger13.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
6813
+ logger14.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
6675
6814
  }
6676
6815
  await stopDomMonitor();
6677
6816
  }
@@ -6684,7 +6823,10 @@ var Share = {
6684
6823
  * @param {number} [options.buffer]
6685
6824
  * @param {boolean} [options.restore]
6686
6825
  * @param {number} [options.maxHeight]
6687
- * @returns {Promise<string>} base64 png
6826
+ * @param {number} [options.maxBytes] 默认 8MiB,返回 base64 超过后会压缩
6827
+ * @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
6828
+ * @param {boolean|Object} [options.compression] 传 false 可关闭压缩
6829
+ * @returns {Promise<string>} base64 image
6688
6830
  */
6689
6831
  async captureScreen(page, options = {}) {
6690
6832
  const originalViewport = await resolveCurrentViewportSize(page);
@@ -6693,6 +6835,7 @@ var Share = {
6693
6835
  const restore = options.restore ?? false;
6694
6836
  const maxHeight = options.maxHeight ?? 8e3;
6695
6837
  const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
6838
+ const compression = resolveCaptureScreenCompression(options);
6696
6839
  try {
6697
6840
  const maxScrollHeight = await page.evaluate(() => {
6698
6841
  let maxHeight2 = document.body.scrollHeight;
@@ -6726,15 +6869,15 @@ var Share = {
6726
6869
  type: "png",
6727
6870
  maxClipHeight: targetHeight
6728
6871
  });
6729
- if (!screenshotWatermarkify.enabled) {
6730
- return rawBuffer.toString("base64");
6872
+ let outputBuffer = rawBuffer;
6873
+ if (screenshotWatermarkify.enabled) {
6874
+ const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
6875
+ ...screenshotWatermarkify,
6876
+ capturedAt
6877
+ });
6878
+ outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
6731
6879
  }
6732
- const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
6733
- ...screenshotWatermarkify,
6734
- capturedAt
6735
- });
6736
- const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
6737
- return buffer_.toString("base64");
6880
+ return await compressScreenshotBufferToBase64(outputBuffer, compression);
6738
6881
  } finally {
6739
6882
  if (restore) {
6740
6883
  await page.evaluate(() => {