@xbrowser/cli 1.9.7 → 1.9.9
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/{anti-bot-MCVM6IFB.js → anti-bot-DR56Y63V.js} +1 -1
- package/dist/{browser-JXIJF4VL.js → browser-FFYPFTBV.js} +1 -1
- package/dist/{browser-ALPLJNH2.js → browser-RHWUAMTB.js} +2 -2
- package/dist/{browser-ZPQP6VW7.js → browser-YCO4GJMZ.js} +2 -2
- package/dist/{cdp-driver-MI7VCE44.js → cdp-driver-2T4P4ZE2.js} +103 -2
- package/dist/{cdp-driver-6EVYLHL2.js → cdp-driver-J3YQ4LJV.js} +1 -1
- package/dist/chunk-3OD76SUE.js +20 -0
- package/dist/chunk-43TEMG4U.js +9 -0
- package/dist/{chunk-CH5ZQV64.js → chunk-4452SPFI.js} +928 -18
- package/dist/{chunk-C4O73DQL.js → chunk-5UGR6MUK.js} +928 -18
- package/dist/{chunk-37SHZSUR.js → chunk-6OZWKXSW.js} +15 -16
- package/dist/{chunk-7ZDWM6T2.js → chunk-BNO7OKO4.js} +5 -6
- package/dist/{chunk-24SY6PE5.js → chunk-CG3D3CHY.js} +1 -8
- package/dist/{chunk-ZJHQPMCY.js → chunk-DWDXEGVK.js} +5 -6
- package/dist/{chunk-74S7UUI2.js → chunk-GUTBIYFW.js} +117 -17
- package/dist/{chunk-DPJNCMLC.js → chunk-INTQPBYF.js} +7 -0
- package/dist/{human-interaction-OU7LZ6OZ.js → chunk-MWFHZUIY.js} +6 -7
- package/dist/chunk-Q2DFJQGS.js +128 -0
- package/dist/{chunk-VJNMAWPZ.js → chunk-RRBXV7KE.js} +103 -2
- package/dist/{chunk-5JSOGINQ.js → chunk-RZM5CNIY.js} +15 -16
- package/dist/{human-interaction-HJTXFVQS.js → chunk-SQHSZENE.js} +2 -2
- package/dist/chunk-TZPKFUBT.js +20 -0
- package/dist/{chunk-YAUG3NSI.js → chunk-YMUSHPU4.js} +16 -128
- package/dist/cli.js +41 -28
- package/dist/{daemon-client-4HJENICO.js → daemon-client-GKEPT4NY.js} +15 -3
- package/dist/{daemon-client-CMRAWXTN.js → daemon-client-O6BYVRXV.js} +4 -1
- package/dist/daemon-main.js +661 -70
- package/dist/human-interaction-5AO42MBA.js +8 -0
- package/dist/{human-interaction-2DZK4MW7.js → human-interaction-C5OEGXGO.js} +1 -1
- package/dist/human-interaction-ISXZTAYY.js +8 -0
- package/dist/index.d.ts +172 -2
- package/dist/index.js +173 -63
- package/dist/recovery-EF33LKRJ.js +77 -0
- package/dist/recovery-J2ISVGUL.js +77 -0
- package/dist/recovery-ZJVVHP7N.js +76 -0
- package/dist/{session-recorder-7GXI42FO.js → session-recorder-H3KEYU26.js} +1 -1
- package/dist/{session-recorder-RFOPX4SF.js → session-recorder-QRZMKFVL.js} +1 -1
- package/dist/{session-replayer-3HEIJBJ2.js → session-replayer-LJUC4TI7.js} +25 -8
- package/package.json +1 -1
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-6OZWKXSW.js";
|
|
24
|
+
import "./chunk-RRBXV7KE.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-RZM5CNIY.js";
|
|
24
|
+
import "./chunk-RRBXV7KE.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-ABXMBNQ6.js";
|
|
@@ -289,6 +289,36 @@ function queryJS(selector) {
|
|
|
289
289
|
const xpath = JSON.stringify(selector.slice(6));
|
|
290
290
|
return `document.evaluate(${xpath}, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue`;
|
|
291
291
|
}
|
|
292
|
+
if (selector.startsWith("text=")) {
|
|
293
|
+
const raw = selector.slice(5);
|
|
294
|
+
const exact = raw.startsWith('"') && raw.endsWith('"');
|
|
295
|
+
const text = exact ? raw.slice(1, -1) : raw;
|
|
296
|
+
return `(() => {
|
|
297
|
+
const target = ${JSON.stringify(text)};
|
|
298
|
+
const exact = ${exact};
|
|
299
|
+
const els = [...document.querySelectorAll('*')].filter(e => {
|
|
300
|
+
if (e.children.length > 0) return false;
|
|
301
|
+
if (e.offsetParent === null) return false;
|
|
302
|
+
const t = (e.textContent || '').trim();
|
|
303
|
+
if (!t) return false;
|
|
304
|
+
return exact ? t === target : t.toLowerCase().includes(target.toLowerCase());
|
|
305
|
+
});
|
|
306
|
+
return els[0] || null;
|
|
307
|
+
})()`;
|
|
308
|
+
}
|
|
309
|
+
if (selector.startsWith("popup-text=")) {
|
|
310
|
+
const text = selector.slice("popup-text=".length);
|
|
311
|
+
return `(() => {
|
|
312
|
+
const target = ${JSON.stringify(text)};
|
|
313
|
+
const els = [...document.querySelectorAll('*')].filter(e => {
|
|
314
|
+
if (e.children.length > 0) return false;
|
|
315
|
+
if (e.offsetParent === null) return false;
|
|
316
|
+
if ((e.textContent || '').trim() !== target) return false;
|
|
317
|
+
return true;
|
|
318
|
+
});
|
|
319
|
+
return els[0] || null;
|
|
320
|
+
})()`;
|
|
321
|
+
}
|
|
292
322
|
return `document.querySelector(${JSON.stringify(selector)})`;
|
|
293
323
|
}
|
|
294
324
|
function queryAllJS(selector) {
|
|
@@ -296,6 +326,9 @@ function queryAllJS(selector) {
|
|
|
296
326
|
const xpath = JSON.stringify(selector.slice(6));
|
|
297
327
|
return `(() => { const it = document.evaluate(${xpath}, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); const r=[]; for(let i=0;i<it.snapshotLength;i++) r.push(it.snapshotItem(i)); return r; })()`;
|
|
298
328
|
}
|
|
329
|
+
if (selector.startsWith("text=") || selector.startsWith("popup-text=")) {
|
|
330
|
+
return `(() => { const el = ${queryJS(selector)}; return el ? [el] : []; })()`;
|
|
331
|
+
}
|
|
299
332
|
return `document.querySelectorAll(${JSON.stringify(selector)})`;
|
|
300
333
|
}
|
|
301
334
|
|
|
@@ -1333,7 +1366,22 @@ Last error: ${lastError.message}` : "";
|
|
|
1333
1366
|
return this._url;
|
|
1334
1367
|
}
|
|
1335
1368
|
async title() {
|
|
1336
|
-
|
|
1369
|
+
for (let i = 0; i < 20; i++) {
|
|
1370
|
+
try {
|
|
1371
|
+
this._title = await this.evaluate("document.title");
|
|
1372
|
+
if (this._title) return this._title;
|
|
1373
|
+
} catch {
|
|
1374
|
+
}
|
|
1375
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
1376
|
+
}
|
|
1377
|
+
try {
|
|
1378
|
+
const info = await this._cdpSend("Target.getTargetInfo", { targetId: this._targetId });
|
|
1379
|
+
if (info?.title) {
|
|
1380
|
+
this._title = info.title;
|
|
1381
|
+
return this._title;
|
|
1382
|
+
}
|
|
1383
|
+
} catch {
|
|
1384
|
+
}
|
|
1337
1385
|
return this._title;
|
|
1338
1386
|
}
|
|
1339
1387
|
async content() {
|
|
@@ -2743,11 +2791,52 @@ var CDPConnection = class extends EventEmitter4 {
|
|
|
2743
2791
|
this.setMaxListeners(0);
|
|
2744
2792
|
this.defaultSessionId = sessionId;
|
|
2745
2793
|
if (typeof wsOrUrl === "string") {
|
|
2746
|
-
|
|
2794
|
+
const wsOptions = /^wss:\/\/\d+\.\d+\.\d+\.\d+/.test(wsOrUrl) ? { rejectUnauthorized: false } : void 0;
|
|
2795
|
+
this.ws = new WebSocket(wsOrUrl, wsOptions);
|
|
2747
2796
|
} else {
|
|
2748
2797
|
this.ws = wsOrUrl;
|
|
2749
2798
|
}
|
|
2750
2799
|
this.bindWebSocket();
|
|
2800
|
+
this.startKeepalive();
|
|
2801
|
+
}
|
|
2802
|
+
/** Send periodic WS pings to prevent idle-timeout disconnects (e.g. CF's 100s).
|
|
2803
|
+
* Also detects dead connections: if a pong isn't received within 10s of a
|
|
2804
|
+
* ping, the connection is considered dead and forcibly closed. */
|
|
2805
|
+
keepaliveTimer = null;
|
|
2806
|
+
pongTimer = null;
|
|
2807
|
+
startKeepalive() {
|
|
2808
|
+
this.ws.on("pong", () => {
|
|
2809
|
+
if (this.pongTimer) {
|
|
2810
|
+
clearTimeout(this.pongTimer);
|
|
2811
|
+
this.pongTimer = null;
|
|
2812
|
+
}
|
|
2813
|
+
});
|
|
2814
|
+
this.keepaliveTimer = setInterval(() => {
|
|
2815
|
+
if (this.ws.readyState === WebSocket.OPEN) {
|
|
2816
|
+
if (!this.pongTimer) {
|
|
2817
|
+
this.pongTimer = setTimeout(() => {
|
|
2818
|
+
if (!this.closed) {
|
|
2819
|
+
this.closed = true;
|
|
2820
|
+
this.closeReason = "keepalive timeout (no pong in 10s)";
|
|
2821
|
+
try {
|
|
2822
|
+
this.ws.terminate();
|
|
2823
|
+
} catch {
|
|
2824
|
+
}
|
|
2825
|
+
for (const [, pending] of this.pending) {
|
|
2826
|
+
clearTimeout(pending.timeout);
|
|
2827
|
+
pending.reject(new Error("Connection dead: keepalive timeout"));
|
|
2828
|
+
}
|
|
2829
|
+
this.pending.clear();
|
|
2830
|
+
this.emit("disconnect");
|
|
2831
|
+
}
|
|
2832
|
+
}, 1e4);
|
|
2833
|
+
}
|
|
2834
|
+
this.ws.ping?.();
|
|
2835
|
+
} else if (this.closed) {
|
|
2836
|
+
if (this.keepaliveTimer) clearInterval(this.keepaliveTimer);
|
|
2837
|
+
this.keepaliveTimer = null;
|
|
2838
|
+
}
|
|
2839
|
+
}, 3e4);
|
|
2751
2840
|
}
|
|
2752
2841
|
/** Wait for the connection to be fully open */
|
|
2753
2842
|
async ready() {
|
|
@@ -2856,6 +2945,14 @@ var CDPConnection = class extends EventEmitter4 {
|
|
|
2856
2945
|
if (this.closed) return;
|
|
2857
2946
|
this.closed = true;
|
|
2858
2947
|
this.closeReason = "closed by caller";
|
|
2948
|
+
if (this.keepaliveTimer) {
|
|
2949
|
+
clearInterval(this.keepaliveTimer);
|
|
2950
|
+
this.keepaliveTimer = null;
|
|
2951
|
+
}
|
|
2952
|
+
if (this.pongTimer) {
|
|
2953
|
+
clearTimeout(this.pongTimer);
|
|
2954
|
+
this.pongTimer = null;
|
|
2955
|
+
}
|
|
2859
2956
|
for (const [id, pending] of this.pending) {
|
|
2860
2957
|
clearTimeout(pending.timeout);
|
|
2861
2958
|
pending.reject(new Error(`Connection closed: ${pending.method}`));
|
|
@@ -2897,6 +2994,10 @@ var CDPConnection = class extends EventEmitter4 {
|
|
|
2897
2994
|
if (this.closed) return;
|
|
2898
2995
|
this.closed = true;
|
|
2899
2996
|
this.closeReason = `WebSocket closed: ${code} ${reason?.toString() ?? ""}`.trim();
|
|
2997
|
+
if (this.keepaliveTimer) {
|
|
2998
|
+
clearInterval(this.keepaliveTimer);
|
|
2999
|
+
this.keepaliveTimer = null;
|
|
3000
|
+
}
|
|
2900
3001
|
for (const [id, pending] of this.pending) {
|
|
2901
3002
|
clearTimeout(pending.timeout);
|
|
2902
3003
|
pending.reject(new Error(`Connection closed: ${pending.method}`));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDaemonConfig,
|
|
3
|
+
getDaemonProcessStatus
|
|
4
|
+
} from "./chunk-Q2DFJQGS.js";
|
|
5
|
+
|
|
6
|
+
// src/utils/viewer-url.ts
|
|
7
|
+
function buildViewerUrl(sessionName = "default") {
|
|
8
|
+
try {
|
|
9
|
+
const status = getDaemonProcessStatus();
|
|
10
|
+
if (!status.running) return void 0;
|
|
11
|
+
const port = status.port || getDaemonConfig().basePort;
|
|
12
|
+
return `http://localhost:${port}/preview/${encodeURIComponent(sessionName)}`;
|
|
13
|
+
} catch {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
buildViewerUrl
|
|
20
|
+
};
|