@skrillex1224/playwright-toolkit 2.1.222 → 2.1.224
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 +9 -1
- package/dist/index.cjs +189 -46
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +189 -46
- package/dist/index.js.map +4 -4
- package/index.d.ts +37 -0
- package/package.json +2 -1
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 压缩到 5MiB 以内,避免 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
|
-
//
|
|
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 = (
|
|
365
|
-
if (
|
|
366
|
-
return
|
|
364
|
+
var resolveLogMethod = (logger15, name) => {
|
|
365
|
+
if (logger15 && typeof logger15[name] === "function") {
|
|
366
|
+
return logger15[name].bind(logger15);
|
|
367
367
|
}
|
|
368
|
-
if (name === "warning" &&
|
|
369
|
-
return
|
|
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 = (
|
|
375
|
-
defaultLogger =
|
|
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
|
|
403
|
-
const logFn = resolveLogMethod(
|
|
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: (
|
|
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: (
|
|
4946
|
-
if (
|
|
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 = 5 * 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6493
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6763
|
+
logger14.fail("captureLink.performActions", actionError);
|
|
6625
6764
|
throw actionError;
|
|
6626
6765
|
}
|
|
6627
6766
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
6628
6767
|
stats.actionTimedOut = true;
|
|
6629
|
-
|
|
6768
|
+
logger14.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
6630
6769
|
} else {
|
|
6631
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
* @
|
|
6826
|
+
* @param {number} [options.maxBytes] 默认 5MiB,返回 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
|
-
|
|
6730
|
-
|
|
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
|
-
|
|
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(() => {
|