@skrillex1224/playwright-toolkit 2.1.198 → 2.1.199
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.cjs +155 -2
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +155 -2
- package/dist/index.js.map +2 -2
- package/dist/internals/proxy-meter.js +78 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -571,9 +571,31 @@ var logger2 = createInternalLogger("ProxyMeter");
|
|
|
571
571
|
var MAX_TOP_DOMAINS = 20;
|
|
572
572
|
var FLUSH_INTERVAL_MS = 2e3;
|
|
573
573
|
var DEFAULT_DEBUG_MAX_EVENTS = 400;
|
|
574
|
+
var PROXY_METER_READY_TIMEOUT_MS = 5e3;
|
|
575
|
+
var PROXY_METER_STABLE_WINDOW_MS = 2e3;
|
|
576
|
+
var PROXY_METER_POLL_INTERVAL_MS = 100;
|
|
577
|
+
var PROXY_METER_CONNECT_TIMEOUT_MS = 200;
|
|
574
578
|
var runtime = null;
|
|
575
579
|
var cleanupInstalled = false;
|
|
576
580
|
var observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
581
|
+
var sleepSignal = new Int32Array(new SharedArrayBuffer(4));
|
|
582
|
+
var portProbeScript = [
|
|
583
|
+
'const net = require("net");',
|
|
584
|
+
"const port = Number(process.argv[1] || 0);",
|
|
585
|
+
"const timeout = Number(process.argv[2] || 200);",
|
|
586
|
+
"if (!Number.isFinite(port) || port <= 0) process.exit(2);",
|
|
587
|
+
'const socket = net.connect({ host: "127.0.0.1", port });',
|
|
588
|
+
"let done = false;",
|
|
589
|
+
"const finish = (code) => {",
|
|
590
|
+
" if (done) return;",
|
|
591
|
+
" done = true;",
|
|
592
|
+
" try { socket.destroy(); } catch {}",
|
|
593
|
+
" process.exit(code);",
|
|
594
|
+
"};",
|
|
595
|
+
'socket.once("connect", () => finish(0));',
|
|
596
|
+
'socket.once("error", () => finish(1));',
|
|
597
|
+
"socket.setTimeout(timeout, () => finish(1));"
|
|
598
|
+
].join("");
|
|
577
599
|
var toSafeInt = (value) => {
|
|
578
600
|
const num = Number(value);
|
|
579
601
|
if (!Number.isFinite(num) || num <= 0) return 0;
|
|
@@ -672,6 +694,17 @@ var ensureLogPath = () => {
|
|
|
672
694
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
673
695
|
return path.join(baseDir, label);
|
|
674
696
|
};
|
|
697
|
+
var ensureStatePath = () => {
|
|
698
|
+
const baseDir = resolveLogDir();
|
|
699
|
+
if (!existsSync(baseDir)) {
|
|
700
|
+
try {
|
|
701
|
+
mkdirSync(baseDir, { recursive: true });
|
|
702
|
+
} catch {
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
const suffix = `${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
706
|
+
return path.join(baseDir, `proxy-meter-state-${process.pid}-${suffix}.json`);
|
|
707
|
+
};
|
|
675
708
|
var readSnapshot = (logPath) => {
|
|
676
709
|
if (!logPath || !existsSync(logPath)) return null;
|
|
677
710
|
try {
|
|
@@ -682,6 +715,86 @@ var readSnapshot = (logPath) => {
|
|
|
682
715
|
return null;
|
|
683
716
|
}
|
|
684
717
|
};
|
|
718
|
+
var readState = (statePath) => {
|
|
719
|
+
if (!statePath || !existsSync(statePath)) return null;
|
|
720
|
+
try {
|
|
721
|
+
const raw = readFileSync(statePath, "utf8");
|
|
722
|
+
if (!raw) return null;
|
|
723
|
+
return JSON.parse(raw);
|
|
724
|
+
} catch {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
var sleepSync = (durationMs) => {
|
|
729
|
+
const timeout = Math.max(0, Number(durationMs) || 0);
|
|
730
|
+
if (timeout <= 0) return;
|
|
731
|
+
Atomics.wait(sleepSignal, 0, 0, timeout);
|
|
732
|
+
};
|
|
733
|
+
var canConnectToPort = (port, timeoutMs = PROXY_METER_CONNECT_TIMEOUT_MS) => {
|
|
734
|
+
const result = spawnSync(process.execPath, ["-e", portProbeScript, String(port), String(timeoutMs)], {
|
|
735
|
+
stdio: "ignore",
|
|
736
|
+
timeout: timeoutMs + 100
|
|
737
|
+
});
|
|
738
|
+
return result.status === 0;
|
|
739
|
+
};
|
|
740
|
+
var waitForProxyMeterReady = ({ port, statePath }) => {
|
|
741
|
+
const startedAt = Date.now();
|
|
742
|
+
const listenDeadline = startedAt + PROXY_METER_READY_TIMEOUT_MS;
|
|
743
|
+
let firstConnectAt = 0;
|
|
744
|
+
let stableHealthy = true;
|
|
745
|
+
while (Date.now() < listenDeadline) {
|
|
746
|
+
const lifecycle = readState(statePath);
|
|
747
|
+
if (lifecycle?.status === "exited") {
|
|
748
|
+
return {
|
|
749
|
+
ok: false,
|
|
750
|
+
reason: "child_exit_before_ready",
|
|
751
|
+
childExitCode: lifecycle.exitCode,
|
|
752
|
+
latencyMs: Date.now() - startedAt
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
if (canConnectToPort(port)) {
|
|
756
|
+
firstConnectAt = Date.now();
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
sleepSync(PROXY_METER_POLL_INTERVAL_MS);
|
|
760
|
+
}
|
|
761
|
+
if (!firstConnectAt) {
|
|
762
|
+
return {
|
|
763
|
+
ok: false,
|
|
764
|
+
reason: "listen_timeout",
|
|
765
|
+
childExitCode: readState(statePath)?.exitCode ?? null,
|
|
766
|
+
latencyMs: Date.now() - startedAt
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
const stableDeadline = firstConnectAt + PROXY_METER_STABLE_WINDOW_MS;
|
|
770
|
+
while (Date.now() < stableDeadline) {
|
|
771
|
+
const lifecycle = readState(statePath);
|
|
772
|
+
if (lifecycle?.status === "exited") {
|
|
773
|
+
return {
|
|
774
|
+
ok: false,
|
|
775
|
+
reason: "stabilize_timeout",
|
|
776
|
+
childExitCode: lifecycle.exitCode,
|
|
777
|
+
latencyMs: Date.now() - startedAt
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
if (!canConnectToPort(port)) {
|
|
781
|
+
stableHealthy = false;
|
|
782
|
+
}
|
|
783
|
+
sleepSync(PROXY_METER_POLL_INTERVAL_MS);
|
|
784
|
+
}
|
|
785
|
+
if (!stableHealthy || !canConnectToPort(port)) {
|
|
786
|
+
return {
|
|
787
|
+
ok: false,
|
|
788
|
+
reason: "stabilize_timeout",
|
|
789
|
+
childExitCode: readState(statePath)?.exitCode ?? null,
|
|
790
|
+
latencyMs: Date.now() - startedAt
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
return {
|
|
794
|
+
ok: true,
|
|
795
|
+
latencyMs: Date.now() - startedAt
|
|
796
|
+
};
|
|
797
|
+
};
|
|
685
798
|
var normalizeDomainRows = (hosts) => {
|
|
686
799
|
const rows = [];
|
|
687
800
|
let requestCount = 0;
|
|
@@ -830,15 +943,23 @@ var startProxyMeter = (options = {}) => {
|
|
|
830
943
|
const upstreamUrl = String(options.proxyUrl || "").trim();
|
|
831
944
|
if (!upstreamUrl) return null;
|
|
832
945
|
if (runtime && runtime.proc) {
|
|
946
|
+
const previousStatePath = runtime.statePath;
|
|
833
947
|
try {
|
|
834
948
|
runtime.proc.kill("SIGTERM");
|
|
835
949
|
} catch {
|
|
836
950
|
}
|
|
837
951
|
runtime = null;
|
|
952
|
+
if (previousStatePath) {
|
|
953
|
+
try {
|
|
954
|
+
rmSync(previousStatePath, { force: true });
|
|
955
|
+
} catch {
|
|
956
|
+
}
|
|
957
|
+
}
|
|
838
958
|
}
|
|
839
959
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
840
960
|
const port = pickFreePort();
|
|
841
961
|
const logPath = ensureLogPath();
|
|
962
|
+
const statePath = ensureStatePath();
|
|
842
963
|
const scriptPath = resolveScriptPath();
|
|
843
964
|
const debugMode = Boolean(options.debugMode);
|
|
844
965
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -849,7 +970,8 @@ var startProxyMeter = (options = {}) => {
|
|
|
849
970
|
PROXY_METER_UPSTREAM: upstreamUrl,
|
|
850
971
|
PROXY_METER_FLUSH_MS: String(FLUSH_INTERVAL_MS),
|
|
851
972
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
852
|
-
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
973
|
+
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents),
|
|
974
|
+
PROXY_METER_STATE: statePath
|
|
853
975
|
};
|
|
854
976
|
const child = spawn(process.execPath, [scriptPath], {
|
|
855
977
|
env,
|
|
@@ -864,8 +986,27 @@ var startProxyMeter = (options = {}) => {
|
|
|
864
986
|
proc: child,
|
|
865
987
|
port,
|
|
866
988
|
logPath,
|
|
989
|
+
statePath,
|
|
867
990
|
startedAt: Date.now()
|
|
868
991
|
};
|
|
992
|
+
const readiness = waitForProxyMeterReady({ port, statePath });
|
|
993
|
+
if (!readiness.ok) {
|
|
994
|
+
logger2.warn(
|
|
995
|
+
`[proxy-meter] startup failed reason=${readiness.reason} latency_ms=${readiness.latencyMs} exit_code=${readiness.childExitCode ?? "unknown"}`
|
|
996
|
+
);
|
|
997
|
+
try {
|
|
998
|
+
child.kill("SIGTERM");
|
|
999
|
+
} catch {
|
|
1000
|
+
}
|
|
1001
|
+
runtime = null;
|
|
1002
|
+
try {
|
|
1003
|
+
rmSync(statePath, { force: true });
|
|
1004
|
+
} catch {
|
|
1005
|
+
}
|
|
1006
|
+
throw new Error(`proxy-meter startup failed: ${readiness.reason}`);
|
|
1007
|
+
}
|
|
1008
|
+
runtime.startedAt = Date.now() - readiness.latencyMs;
|
|
1009
|
+
logger2.info(`[proxy-meter] ready latency_ms=${readiness.latencyMs} stable_window_ms=${PROXY_METER_STABLE_WINDOW_MS}`);
|
|
869
1010
|
registerCleanup();
|
|
870
1011
|
return { server: `http://127.0.0.1:${port}` };
|
|
871
1012
|
};
|
|
@@ -877,9 +1018,15 @@ var recordProxyMeterResourceType = (requestUrl, resourceType) => {
|
|
|
877
1018
|
};
|
|
878
1019
|
var stopProxyMeter = async () => {
|
|
879
1020
|
if (!runtime) return null;
|
|
880
|
-
const { proc, logPath } = runtime;
|
|
1021
|
+
const { proc, logPath, statePath } = runtime;
|
|
881
1022
|
if (!proc || proc.killed) {
|
|
882
1023
|
runtime = null;
|
|
1024
|
+
if (statePath) {
|
|
1025
|
+
try {
|
|
1026
|
+
rmSync(statePath, { force: true });
|
|
1027
|
+
} catch {
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
883
1030
|
return logPath || null;
|
|
884
1031
|
}
|
|
885
1032
|
await new Promise((resolve) => {
|
|
@@ -901,6 +1048,12 @@ var stopProxyMeter = async () => {
|
|
|
901
1048
|
}
|
|
902
1049
|
});
|
|
903
1050
|
runtime = null;
|
|
1051
|
+
if (statePath) {
|
|
1052
|
+
try {
|
|
1053
|
+
rmSync(statePath, { force: true });
|
|
1054
|
+
} catch {
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
904
1057
|
return logPath || null;
|
|
905
1058
|
};
|
|
906
1059
|
var getProxyMeterSnapshot = async (options = {}) => {
|