browserclaw 0.3.9 → 0.3.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/index.cjs +59 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +59 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -382,6 +382,51 @@ async function getChromeWebSocketUrl(cdpUrl, timeoutMs = 500, authToken) {
|
|
|
382
382
|
clearTimeout(t);
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
|
+
async function isChromeCdpReady(cdpUrl, timeoutMs = 500, handshakeTimeoutMs = 800) {
|
|
386
|
+
const wsUrl = await getChromeWebSocketUrl(cdpUrl, timeoutMs);
|
|
387
|
+
if (!wsUrl) return false;
|
|
388
|
+
return await canRunCdpHealthCommand(wsUrl, handshakeTimeoutMs);
|
|
389
|
+
}
|
|
390
|
+
async function canRunCdpHealthCommand(wsUrl, timeoutMs = 800) {
|
|
391
|
+
return new Promise((resolve2) => {
|
|
392
|
+
let settled = false;
|
|
393
|
+
const finish = (value) => {
|
|
394
|
+
if (settled) return;
|
|
395
|
+
settled = true;
|
|
396
|
+
clearTimeout(timer);
|
|
397
|
+
try {
|
|
398
|
+
ws.close();
|
|
399
|
+
} catch {
|
|
400
|
+
}
|
|
401
|
+
resolve2(value);
|
|
402
|
+
};
|
|
403
|
+
const timer = setTimeout(() => finish(false), Math.max(50, timeoutMs + 25));
|
|
404
|
+
let ws;
|
|
405
|
+
try {
|
|
406
|
+
ws = new WebSocket(wsUrl);
|
|
407
|
+
} catch {
|
|
408
|
+
finish(false);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
ws.onopen = () => {
|
|
412
|
+
try {
|
|
413
|
+
ws.send(JSON.stringify({ id: 1, method: "Browser.getVersion" }));
|
|
414
|
+
} catch {
|
|
415
|
+
finish(false);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
ws.onmessage = (event) => {
|
|
419
|
+
try {
|
|
420
|
+
const parsed = JSON.parse(String(event.data));
|
|
421
|
+
if (parsed?.id !== 1) return;
|
|
422
|
+
finish(Boolean(parsed.result && typeof parsed.result === "object"));
|
|
423
|
+
} catch {
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
ws.onerror = () => finish(false);
|
|
427
|
+
ws.onclose = () => finish(false);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
385
430
|
async function launchChrome(opts = {}) {
|
|
386
431
|
const cdpPort = opts.cdpPort ?? DEFAULT_CDP_PORT;
|
|
387
432
|
await ensurePortAvailable(cdpPort);
|
|
@@ -456,18 +501,30 @@ async function launchChrome(opts = {}) {
|
|
|
456
501
|
}
|
|
457
502
|
const proc = spawnChrome();
|
|
458
503
|
const cdpUrl = `http://127.0.0.1:${cdpPort}`;
|
|
504
|
+
const stderrChunks = [];
|
|
505
|
+
const onStderr = (chunk) => {
|
|
506
|
+
stderrChunks.push(chunk);
|
|
507
|
+
};
|
|
508
|
+
proc.stderr?.on("data", onStderr);
|
|
459
509
|
const readyDeadline = Date.now() + 15e3;
|
|
460
510
|
while (Date.now() < readyDeadline) {
|
|
461
511
|
if (await isChromeReachable(cdpUrl, 500)) break;
|
|
462
512
|
await new Promise((r) => setTimeout(r, 200));
|
|
463
513
|
}
|
|
464
514
|
if (!await isChromeReachable(cdpUrl, 500)) {
|
|
515
|
+
const stderrOutput = Buffer.concat(stderrChunks).toString("utf8").trim();
|
|
516
|
+
const stderrHint = stderrOutput ? `
|
|
517
|
+
Chrome stderr:
|
|
518
|
+
${stderrOutput.slice(0, 2e3)}` : "";
|
|
519
|
+
const sandboxHint = process.platform === "linux" && !opts.noSandbox ? "\nHint: If running in a container or as root, try setting noSandbox: true." : "";
|
|
465
520
|
try {
|
|
466
521
|
proc.kill("SIGKILL");
|
|
467
522
|
} catch {
|
|
468
523
|
}
|
|
469
|
-
throw new Error(`Failed to start Chrome CDP on port ${cdpPort}
|
|
524
|
+
throw new Error(`Failed to start Chrome CDP on port ${cdpPort}.${sandboxHint}${stderrHint}`);
|
|
470
525
|
}
|
|
526
|
+
proc.stderr?.off("data", onStderr);
|
|
527
|
+
stderrChunks.length = 0;
|
|
471
528
|
return {
|
|
472
529
|
pid: proc.pid ?? -1,
|
|
473
530
|
exe,
|
|
@@ -3195,6 +3252,7 @@ exports.BrowserClaw = BrowserClaw;
|
|
|
3195
3252
|
exports.CrawlPage = CrawlPage;
|
|
3196
3253
|
exports.InvalidBrowserNavigationUrlError = InvalidBrowserNavigationUrlError;
|
|
3197
3254
|
exports.assertBrowserNavigationAllowed = assertBrowserNavigationAllowed;
|
|
3255
|
+
exports.isChromeCdpReady = isChromeCdpReady;
|
|
3198
3256
|
exports.withBrowserNavigationPolicy = withBrowserNavigationPolicy;
|
|
3199
3257
|
//# sourceMappingURL=index.cjs.map
|
|
3200
3258
|
//# sourceMappingURL=index.cjs.map
|