@rynx-ai/daemon 0.1.11-beta.50 → 0.1.11-beta.51
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.
|
@@ -17,7 +17,6 @@ const DEVTOOLS_ACTIVE_PORT_FILE = "DevToolsActivePort";
|
|
|
17
17
|
const MAX_PROFILE_METADATA_BYTES = 4 * 1_024;
|
|
18
18
|
const MAX_PROCESS_COMMAND_BYTES = 64 * 1_024;
|
|
19
19
|
const MAX_ACTIVE_PORT_BYTES = 1_024;
|
|
20
|
-
const MAX_CDP_MESSAGE_BYTES = 4 * 1_024 * 1_024;
|
|
21
20
|
const DEFAULT_STARTUP_TIMEOUT_MS = 15_000;
|
|
22
21
|
const DEFAULT_CDP_COMMAND_TIMEOUT_MS = 10_000;
|
|
23
22
|
const DEFAULT_TERMINATION_GRACE_MS = 2_500;
|
|
@@ -771,7 +770,18 @@ class HeadlessBrowserHandle {
|
|
|
771
770
|
this.dropAttachedSession(event.sessionId);
|
|
772
771
|
return;
|
|
773
772
|
}
|
|
774
|
-
this.
|
|
773
|
+
if (!this.host.connection.connected) {
|
|
774
|
+
this.markUnavailable("The native CDP observer disconnected");
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
this.diagnostic("request.continue_failed", { ...identity, error: String(error) });
|
|
778
|
+
// A failed request must not strand the Page or invalidate unrelated Pages.
|
|
779
|
+
void this.host.connection.command("Fetch.failRequest", {
|
|
780
|
+
requestId: event.params.requestId,
|
|
781
|
+
errorReason: "Failed",
|
|
782
|
+
}, event.sessionId).catch((failure) => {
|
|
783
|
+
this.diagnostic("request.fail_failed", { ...identity, error: String(failure) });
|
|
784
|
+
});
|
|
775
785
|
});
|
|
776
786
|
return;
|
|
777
787
|
}
|
|
@@ -1044,13 +1054,14 @@ class HeadlessBrowserHandle {
|
|
|
1044
1054
|
}
|
|
1045
1055
|
catch (error) {
|
|
1046
1056
|
if (!isMissingTargetError(error) && !isTransientPageTransitionError(error)) {
|
|
1047
|
-
this.
|
|
1048
|
-
|
|
1057
|
+
if (!this.host.connection.connected)
|
|
1058
|
+
this.markUnavailable("The native CDP observer disconnected");
|
|
1059
|
+
this.diagnostic("session.detach_failed", { cdpSessionId: sessionId, error: String(error) });
|
|
1060
|
+
// Keep the live session tracked so its paused requests can still be handled.
|
|
1061
|
+
return;
|
|
1049
1062
|
}
|
|
1050
1063
|
}
|
|
1051
|
-
|
|
1052
|
-
this.dropAttachedSession(sessionId);
|
|
1053
|
-
}
|
|
1064
|
+
this.dropAttachedSession(sessionId);
|
|
1054
1065
|
}
|
|
1055
1066
|
async dismissJavaScriptDialog(sessionId, targetId) {
|
|
1056
1067
|
try {
|
|
@@ -1225,7 +1236,13 @@ class HeadlessBrowserSurfaceSource {
|
|
|
1225
1236
|
return result;
|
|
1226
1237
|
}
|
|
1227
1238
|
acceptScreencastFrame(params) {
|
|
1228
|
-
|
|
1239
|
+
let screencastSessionId;
|
|
1240
|
+
try {
|
|
1241
|
+
screencastSessionId = surfaceFrameSessionId(params.sessionId);
|
|
1242
|
+
}
|
|
1243
|
+
catch {
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1229
1246
|
const acknowledge = onceAsync(async () => {
|
|
1230
1247
|
await this.source.connection.command("Page.screencastFrameAck", { sessionId: screencastSessionId }, this.source.pageSessionId);
|
|
1231
1248
|
});
|
|
@@ -1236,7 +1253,6 @@ class HeadlessBrowserSurfaceSource {
|
|
|
1236
1253
|
void acknowledge().catch(() => undefined);
|
|
1237
1254
|
return;
|
|
1238
1255
|
}
|
|
1239
|
-
this.ensureCurrent();
|
|
1240
1256
|
const receivedAt = Date.now();
|
|
1241
1257
|
this.lastScreencastFrameAt = receivedAt;
|
|
1242
1258
|
// Throttle immediate deliveries, not replacements behind a slow viewer.
|
|
@@ -1247,6 +1263,7 @@ class HeadlessBrowserSurfaceSource {
|
|
|
1247
1263
|
return;
|
|
1248
1264
|
}
|
|
1249
1265
|
try {
|
|
1266
|
+
this.ensureCurrent();
|
|
1250
1267
|
this.updateViewportFromScreencastMetadata(params.metadata);
|
|
1251
1268
|
const timestampMilliseconds = surfaceFrameTimestamp(params.metadata, receivedAt);
|
|
1252
1269
|
this.lastAcceptedFrameAt = receivedAt;
|
|
@@ -1255,6 +1272,9 @@ class HeadlessBrowserSurfaceSource {
|
|
|
1255
1272
|
// never extend across network RTT back into Chrome capture.
|
|
1256
1273
|
this.pushFrameIfChanged(decodeSurfaceImage(params.data, this.format), timestampMilliseconds, async () => undefined);
|
|
1257
1274
|
}
|
|
1275
|
+
catch {
|
|
1276
|
+
// Discard a bad frame without disconnecting the shared Browser observer.
|
|
1277
|
+
}
|
|
1258
1278
|
finally {
|
|
1259
1279
|
void acknowledge().catch(() => undefined);
|
|
1260
1280
|
}
|
|
@@ -1837,7 +1857,6 @@ class CdpConnection {
|
|
|
1837
1857
|
static async connect(endpoint, commandTimeoutMs) {
|
|
1838
1858
|
validateCdpEndpoint(endpoint);
|
|
1839
1859
|
const socket = new WebSocket(endpoint, {
|
|
1840
|
-
maxPayload: MAX_CDP_MESSAGE_BYTES,
|
|
1841
1860
|
perMessageDeflate: false,
|
|
1842
1861
|
});
|
|
1843
1862
|
await new Promise((resolveOpen, rejectOpen) => {
|
|
@@ -1901,7 +1920,7 @@ class CdpConnection {
|
|
|
1901
1920
|
}
|
|
1902
1921
|
onMessage(data, isBinary) {
|
|
1903
1922
|
const bytes = rawDataBytes(data);
|
|
1904
|
-
if (isBinary
|
|
1923
|
+
if (isBinary) {
|
|
1905
1924
|
this.socket.terminate();
|
|
1906
1925
|
this.disconnect("Native CDP sent an invalid message");
|
|
1907
1926
|
return;
|
|
@@ -9,7 +9,7 @@ export async function createPageAgentBrowserConnection(endpoint, isCurrent) {
|
|
|
9
9
|
let used = false, closed = false, authority = "";
|
|
10
10
|
let client, upstream;
|
|
11
11
|
const server = createServer((_request, response) => { response.writeHead(404).end(); });
|
|
12
|
-
const sockets = new WebSocketServer({ noServer: true
|
|
12
|
+
const sockets = new WebSocketServer({ noServer: true });
|
|
13
13
|
const disconnect = () => { client?.terminate(); upstream?.terminate(); };
|
|
14
14
|
server.on("upgrade", (request, socket, head) => {
|
|
15
15
|
if (closed || used || !isCurrent() || request.url !== noncePath || request.headers.origin !== undefined || request.headers.host !== authority) {
|
|
@@ -19,7 +19,7 @@ export async function createPageAgentBrowserConnection(endpoint, isCurrent) {
|
|
|
19
19
|
used = true;
|
|
20
20
|
sockets.handleUpgrade(request, socket, head, (downstream) => {
|
|
21
21
|
client = downstream;
|
|
22
|
-
const native = new WebSocket(endpoint, {
|
|
22
|
+
const native = new WebSocket(endpoint, { handshakeTimeout: 5_000 });
|
|
23
23
|
upstream = native;
|
|
24
24
|
const early = [];
|
|
25
25
|
let buffered = 0;
|
|
@@ -28,7 +28,7 @@ export async function createPageAgentBrowserConnection(endpoint, isCurrent) {
|
|
|
28
28
|
native.on("close", disconnect);
|
|
29
29
|
native.on("error", disconnect);
|
|
30
30
|
downstream.on("message", (bytes, binary) => {
|
|
31
|
-
if (binary || !isCurrent()
|
|
31
|
+
if (binary || !isCurrent()) {
|
|
32
32
|
disconnect();
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
@@ -45,7 +45,7 @@ export async function createPageAgentBrowserConnection(endpoint, isCurrent) {
|
|
|
45
45
|
native.on("open", () => { for (const bytes of early)
|
|
46
46
|
native.send(bytes, { binary: false }); early.length = 0; buffered = 0; });
|
|
47
47
|
native.on("message", (bytes, binary) => {
|
|
48
|
-
if (binary || !isCurrent() || downstream.readyState !== WebSocket.OPEN
|
|
48
|
+
if (binary || !isCurrent() || downstream.readyState !== WebSocket.OPEN) {
|
|
49
49
|
disconnect();
|
|
50
50
|
return;
|
|
51
51
|
}
|
package/dist/page-cdp-gateway.js
CHANGED
|
@@ -2,7 +2,6 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { createServer } from "node:http";
|
|
3
3
|
import WebSocket, { WebSocketServer } from "ws";
|
|
4
4
|
const CHILD_TYPES = new Set(["iframe", "worker", "service_worker", "shared_worker"]);
|
|
5
|
-
const MAX_BYTES = 8 * 1024 * 1024;
|
|
6
5
|
const TARGET_METHODS = new Set(["Target.getTargets", "Target.getTargetInfo", "Target.setDiscoverTargets", "Target.setAutoAttach", "Target.attachToTarget", "Target.detachFromTarget", "Target.activateTarget"]);
|
|
7
6
|
const BROWSER_METHODS = new Set(["Browser.getVersion", "Browser.getWindowForTarget"]);
|
|
8
7
|
/** A capability for one existing native target, never the whole Chrome process. */
|
|
@@ -15,7 +14,7 @@ export async function createPageCdpGateway(upstreamEndpoint, targetId, isCurrent
|
|
|
15
14
|
// The daemon hands the nonce URL directly to its helper. Never publish that
|
|
16
15
|
// capability on an unauthenticated discovery endpoint.
|
|
17
16
|
const server = createServer((_request, response) => { response.writeHead(404).end(); });
|
|
18
|
-
const sockets = new WebSocketServer({ noServer: true
|
|
17
|
+
const sockets = new WebSocketServer({ noServer: true });
|
|
19
18
|
server.on("upgrade", (request, socket, head) => {
|
|
20
19
|
if (stopped || !isCurrent() || request.url !== path || downstream ||
|
|
21
20
|
request.headers.origin !== undefined || request.headers.host !== new URL(endpoint).host) {
|
|
@@ -26,7 +25,7 @@ export async function createPageCdpGateway(upstreamEndpoint, targetId, isCurrent
|
|
|
26
25
|
});
|
|
27
26
|
sockets.on("connection", (client) => {
|
|
28
27
|
downstream = client;
|
|
29
|
-
const native = new WebSocket(upstreamEndpoint, {
|
|
28
|
+
const native = new WebSocket(upstreamEndpoint, { handshakeTimeout: 5_000 });
|
|
30
29
|
upstream = native;
|
|
31
30
|
const sessions = new Set();
|
|
32
31
|
const children = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rynx-ai/daemon",
|
|
3
|
-
"version": "0.1.11-beta.
|
|
3
|
+
"version": "0.1.11-beta.51",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/rynx-ai/rynx.git",
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
"tar": "^7.5.19",
|
|
53
53
|
"undici": "^7.28.0",
|
|
54
54
|
"ws": "^8.21.0",
|
|
55
|
-
"@rynx-ai/core": "0.1.11-beta.
|
|
56
|
-
"@rynx-ai/emulator": "0.1.11-beta.
|
|
57
|
-
"@rynx-ai/plugin-runner": "0.1.11-beta.
|
|
58
|
-
"@rynx-ai/plugin-sdk": "0.1.11-beta.
|
|
59
|
-
"@rynx-ai/protocol": "0.1.11-beta.
|
|
60
|
-
"@rynx-ai/remote-runtime-client": "0.1.11-beta.
|
|
61
|
-
"@rynx-ai/server": "0.1.11-beta.
|
|
55
|
+
"@rynx-ai/core": "0.1.11-beta.51",
|
|
56
|
+
"@rynx-ai/emulator": "0.1.11-beta.51",
|
|
57
|
+
"@rynx-ai/plugin-runner": "0.1.11-beta.51",
|
|
58
|
+
"@rynx-ai/plugin-sdk": "0.1.11-beta.51",
|
|
59
|
+
"@rynx-ai/protocol": "0.1.11-beta.51",
|
|
60
|
+
"@rynx-ai/remote-runtime-client": "0.1.11-beta.51",
|
|
61
|
+
"@rynx-ai/server": "0.1.11-beta.51"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@types/ws": "^8.18.1",
|
|
65
|
-
"@rynx-ai/browser-cdp": "0.1.11-beta.
|
|
66
|
-
"@rynx-ai/plugin-channel-lark": "0.1.11-beta.
|
|
65
|
+
"@rynx-ai/browser-cdp": "0.1.11-beta.51",
|
|
66
|
+
"@rynx-ai/plugin-channel-lark": "0.1.11-beta.51"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"build": "rm -rf dist bundled-plugins && tsc -p tsconfig.json && chmod +x dist/index-daemon.js && node scripts/prepare-agent-browser.mjs && node ../../scripts/stage-bundled-plugins.mjs",
|