@skrillex1224/playwright-toolkit 3.0.8 → 3.0.10

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/browser.js CHANGED
@@ -2853,6 +2853,7 @@ var createActorInfo = (info) => {
2853
2853
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path2 }) => {
2854
2854
  const safeProtocol = String(protocol2).trim();
2855
2855
  const safeDomain = normalizeDomain(domain2);
2856
+ if (!safeDomain) return "";
2856
2857
  const safePath = normalizePath(path2);
2857
2858
  return `${safeProtocol}://${safeDomain}${safePath}`;
2858
2859
  };
@@ -3060,6 +3061,17 @@ var ActorInfo = {
3060
3061
  prefix: "",
3061
3062
  xurl: []
3062
3063
  }
3064
+ }),
3065
+ webpage: createActorInfo({
3066
+ key: "webpage",
3067
+ name: "\u901A\u7528\u7F51\u9875",
3068
+ domain: "",
3069
+ path: "/",
3070
+ share: {
3071
+ mode: "dom",
3072
+ prefix: "",
3073
+ xurl: []
3074
+ }
3063
3075
  })
3064
3076
  };
3065
3077
 
package/dist/index.cjs CHANGED
@@ -149,6 +149,7 @@ var createActorInfo = (info) => {
149
149
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
150
150
  const safeProtocol = String(protocol2).trim();
151
151
  const safeDomain = normalizeDomain(domain2);
152
+ if (!safeDomain) return "";
152
153
  const safePath = normalizePath(path4);
153
154
  return `${safeProtocol}://${safeDomain}${safePath}`;
154
155
  };
@@ -356,6 +357,17 @@ var ActorInfo = {
356
357
  prefix: "",
357
358
  xurl: []
358
359
  }
360
+ }),
361
+ webpage: createActorInfo({
362
+ key: "webpage",
363
+ name: "\u901A\u7528\u7F51\u9875",
364
+ domain: "",
365
+ path: "/",
366
+ share: {
367
+ mode: "dom",
368
+ prefix: "",
369
+ xurl: []
370
+ }
359
371
  })
360
372
  };
361
373
 
@@ -1196,6 +1208,18 @@ var ensureLogPath = () => {
1196
1208
  const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
1197
1209
  return import_path.default.join(baseDir, label);
1198
1210
  };
1211
+ var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
1212
+ var writeChildOutput = (stream, output, prefix) => {
1213
+ if (!stream || !output) return;
1214
+ output.on("data", (chunk) => {
1215
+ const text = chunk?.toString?.() || String(chunk || "");
1216
+ if (!text) return;
1217
+ for (const line of text.split(/\r?\n/)) {
1218
+ if (!line) continue;
1219
+ stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
1220
+ }
1221
+ });
1222
+ };
1199
1223
  var readSnapshot = (logPath) => {
1200
1224
  if (!logPath || !(0, import_fs.existsSync)(logPath)) return null;
1201
1225
  try {
@@ -1363,6 +1387,7 @@ var startProxyMeter = (options = {}) => {
1363
1387
  observedDomainResourceTypes = /* @__PURE__ */ new Map();
1364
1388
  const port = pickFreePort();
1365
1389
  const logPath = ensureLogPath();
1390
+ const stdioLogPath = ensureStdioLogPath(logPath);
1366
1391
  const scriptPath = resolveScriptPath();
1367
1392
  const debugMode = Boolean(options.debugMode);
1368
1393
  const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
@@ -1375,19 +1400,26 @@ var startProxyMeter = (options = {}) => {
1375
1400
  PROXY_METER_DEBUG: debugMode ? "1" : "0",
1376
1401
  PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
1377
1402
  };
1403
+ const stdioLog = (0, import_fs.createWriteStream)(stdioLogPath, { flags: "a" });
1404
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
1378
1405
  const child = (0, import_child_process.spawn)(process.execPath, [scriptPath], {
1379
1406
  env,
1380
- stdio: ["ignore", "ignore", "ignore"]
1407
+ stdio: ["ignore", "pipe", "pipe"]
1381
1408
  });
1382
- child.once("exit", (code) => {
1409
+ writeChildOutput(stdioLog, child.stdout, "stdout");
1410
+ writeChildOutput(stdioLog, child.stderr, "stderr");
1411
+ child.once("exit", (code, signal) => {
1412
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
1413
+ stdioLog.end();
1383
1414
  if (code && code !== 0) {
1384
- logger2.warn(`[proxy-meter] exited with code ${code}`);
1415
+ logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
1385
1416
  }
1386
1417
  });
1387
1418
  runtime = {
1388
1419
  proc: child,
1389
1420
  port,
1390
1421
  logPath,
1422
+ stdioLogPath,
1391
1423
  startedAt: Date.now()
1392
1424
  };
1393
1425
  registerCleanup();
package/dist/index.js CHANGED
@@ -122,6 +122,7 @@ var createActorInfo = (info) => {
122
122
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
123
123
  const safeProtocol = String(protocol2).trim();
124
124
  const safeDomain = normalizeDomain(domain2);
125
+ if (!safeDomain) return "";
125
126
  const safePath = normalizePath(path4);
126
127
  return `${safeProtocol}://${safeDomain}${safePath}`;
127
128
  };
@@ -329,6 +330,17 @@ var ActorInfo = {
329
330
  prefix: "",
330
331
  xurl: []
331
332
  }
333
+ }),
334
+ webpage: createActorInfo({
335
+ key: "webpage",
336
+ name: "\u901A\u7528\u7F51\u9875",
337
+ domain: "",
338
+ path: "/",
339
+ share: {
340
+ mode: "dom",
341
+ prefix: "",
342
+ xurl: []
343
+ }
332
344
  })
333
345
  };
334
346
 
@@ -1059,7 +1071,7 @@ import { serializeError as serializeError2 } from "serialize-error";
1059
1071
 
1060
1072
  // src/internals/proxy-meter-runtime.js
1061
1073
  import { spawn, spawnSync } from "child_process";
1062
- import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
1074
+ import { createWriteStream, existsSync, mkdirSync, readFileSync, rmSync } from "fs";
1063
1075
  import { tmpdir } from "os";
1064
1076
  import path from "path";
1065
1077
  import { fileURLToPath } from "url";
@@ -1168,6 +1180,18 @@ var ensureLogPath = () => {
1168
1180
  const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
1169
1181
  return path.join(baseDir, label);
1170
1182
  };
1183
+ var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
1184
+ var writeChildOutput = (stream, output, prefix) => {
1185
+ if (!stream || !output) return;
1186
+ output.on("data", (chunk) => {
1187
+ const text = chunk?.toString?.() || String(chunk || "");
1188
+ if (!text) return;
1189
+ for (const line of text.split(/\r?\n/)) {
1190
+ if (!line) continue;
1191
+ stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
1192
+ }
1193
+ });
1194
+ };
1171
1195
  var readSnapshot = (logPath) => {
1172
1196
  if (!logPath || !existsSync(logPath)) return null;
1173
1197
  try {
@@ -1335,6 +1359,7 @@ var startProxyMeter = (options = {}) => {
1335
1359
  observedDomainResourceTypes = /* @__PURE__ */ new Map();
1336
1360
  const port = pickFreePort();
1337
1361
  const logPath = ensureLogPath();
1362
+ const stdioLogPath = ensureStdioLogPath(logPath);
1338
1363
  const scriptPath = resolveScriptPath();
1339
1364
  const debugMode = Boolean(options.debugMode);
1340
1365
  const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
@@ -1347,19 +1372,26 @@ var startProxyMeter = (options = {}) => {
1347
1372
  PROXY_METER_DEBUG: debugMode ? "1" : "0",
1348
1373
  PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
1349
1374
  };
1375
+ const stdioLog = createWriteStream(stdioLogPath, { flags: "a" });
1376
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
1350
1377
  const child = spawn(process.execPath, [scriptPath], {
1351
1378
  env,
1352
- stdio: ["ignore", "ignore", "ignore"]
1379
+ stdio: ["ignore", "pipe", "pipe"]
1353
1380
  });
1354
- child.once("exit", (code) => {
1381
+ writeChildOutput(stdioLog, child.stdout, "stdout");
1382
+ writeChildOutput(stdioLog, child.stderr, "stderr");
1383
+ child.once("exit", (code, signal) => {
1384
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
1385
+ stdioLog.end();
1355
1386
  if (code && code !== 0) {
1356
- logger2.warn(`[proxy-meter] exited with code ${code}`);
1387
+ logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
1357
1388
  }
1358
1389
  });
1359
1390
  runtime = {
1360
1391
  proc: child,
1361
1392
  port,
1362
1393
  logPath,
1394
+ stdioLogPath,
1363
1395
  startedAt: Date.now()
1364
1396
  };
1365
1397
  registerCleanup();
@@ -32,6 +32,25 @@ const state = {
32
32
  : null,
33
33
  };
34
34
 
35
+ const formatFatalError = (error) => {
36
+ if (error instanceof Error) {
37
+ return error.stack || error.message || String(error);
38
+ }
39
+ try {
40
+ return JSON.stringify(error);
41
+ } catch {
42
+ return String(error);
43
+ }
44
+ };
45
+
46
+ const exitAfterFatal = (kind, error) => {
47
+ try {
48
+ console.error(`[proxy-meter] fatal ${kind}: ${formatFatalError(error)}`);
49
+ } catch {}
50
+ flushSnapshot();
51
+ process.exit(1);
52
+ };
53
+
35
54
  const getHostBucket = (host) => {
36
55
  if (!host) return null;
37
56
  if (!state.hosts[host]) {
@@ -60,6 +79,21 @@ const safeError = (error) => {
60
79
  return message.length > 240 ? message.slice(0, 240) : message;
61
80
  };
62
81
 
82
+ const sendBadGateway = (res, error = null) => {
83
+ if (!res || res.destroyed || res.writableEnded) return;
84
+
85
+ try {
86
+ if (!res.headersSent) {
87
+ res.writeHead(502);
88
+ res.end('Bad Gateway');
89
+ return;
90
+ }
91
+
92
+ // Headers are already committed; the only truthful error signal left is closing the stream.
93
+ res.destroy(error instanceof Error ? error : undefined);
94
+ } catch {}
95
+ };
96
+
63
97
  const statusLabel = (statusCode, error) => {
64
98
  const code = Number(statusCode) || 0;
65
99
  if (error || code <= 0) return 'ERR';
@@ -349,8 +383,7 @@ const forwardHttp = (req, res) => {
349
383
 
350
384
  if (!target) {
351
385
  tracker.close({ statusCode: 0, error: 'invalid_target_url' });
352
- res.writeHead(502);
353
- res.end('Bad Gateway');
386
+ sendBadGateway(res);
354
387
  return;
355
388
  }
356
389
 
@@ -381,7 +414,19 @@ const forwardHttp = (req, res) => {
381
414
  let responseStatus = 0;
382
415
  const proxyReq = http.request(requestOptions, (proxyRes) => {
383
416
  responseStatus = Number(proxyRes.statusCode) || 0;
384
- res.writeHead(responseStatus || 502, proxyRes.headers);
417
+ if (res.destroyed || res.writableEnded) {
418
+ tracker.close({ statusCode: responseStatus || 499, error: 'client_response_closed' });
419
+ proxyRes.resume();
420
+ return;
421
+ }
422
+ try {
423
+ res.writeHead(responseStatus || 502, proxyRes.headers);
424
+ } catch (error) {
425
+ tracker.close({ statusCode: responseStatus, error: safeError(error) });
426
+ proxyRes.resume();
427
+ sendBadGateway(res, error);
428
+ return;
429
+ }
385
430
  proxyRes.on('data', (chunk) => {
386
431
  const size = chunk?.length || 0;
387
432
  addTraffic(hostname, 'in', size);
@@ -412,8 +457,7 @@ const forwardHttp = (req, res) => {
412
457
 
413
458
  proxyReq.on('error', (error) => {
414
459
  tracker.close({ statusCode: responseStatus, error: safeError(error) });
415
- res.writeHead(502);
416
- res.end('Bad Gateway');
460
+ sendBadGateway(res, error);
417
461
  });
418
462
  };
419
463
 
@@ -545,5 +589,7 @@ const shutdown = () => {
545
589
  process.exit(0);
546
590
  };
547
591
 
592
+ process.on('uncaughtException', (error) => exitAfterFatal('uncaughtException', error));
593
+ process.on('unhandledRejection', (error) => exitAfterFatal('unhandledRejection', error));
548
594
  process.on('SIGINT', shutdown);
549
595
  process.on('SIGTERM', shutdown);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skrillex1224/playwright-toolkit",
3
- "version": "3.0.8",
3
+ "version": "3.0.10",
4
4
  "description": "一个在 Apify/Crawlee Actor 中启用实时截图视图的实用工具库。",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",