@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/README.md +9 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +196 -54
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +196 -54
- package/dist/index.js.map +4 -4
- package/index.d.ts +37 -0
- package/package.json +2 -1
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 = (
|
|
338
|
-
if (
|
|
339
|
-
return
|
|
337
|
+
var resolveLogMethod = (logger15, name) => {
|
|
338
|
+
if (logger15 && typeof logger15[name] === "function") {
|
|
339
|
+
return logger15[name].bind(logger15);
|
|
340
340
|
}
|
|
341
|
-
if (name === "warning" &&
|
|
342
|
-
return
|
|
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 = (
|
|
348
|
-
defaultLogger =
|
|
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
|
|
376
|
-
const logFn = resolveLogMethod(
|
|
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((
|
|
662
|
-
if (Number(b[1]) !== Number(
|
|
663
|
-
return String(
|
|
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((
|
|
754
|
-
if (b.totalBytes !==
|
|
755
|
-
if (b.requests !==
|
|
756
|
-
return String(
|
|
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: (
|
|
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: (
|
|
4919
|
-
if (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6466
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6735
|
+
logger14.fail("captureLink.performActions", actionError);
|
|
6598
6736
|
throw actionError;
|
|
6599
6737
|
}
|
|
6600
6738
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
6601
6739
|
stats.actionTimedOut = true;
|
|
6602
|
-
|
|
6740
|
+
logger14.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
6603
6741
|
} else {
|
|
6604
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
* @
|
|
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
|
-
|
|
6703
|
-
|
|
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
|
-
|
|
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(() => {
|