@dyyz1993/agent-browser 0.28.0 → 0.29.1
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/actions/context.d.ts +4 -0
- package/dist/actions/context.d.ts.map +1 -1
- package/dist/actions/context.js +41 -1
- package/dist/actions/context.js.map +1 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +164 -297
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/interaction.d.ts.map +1 -1
- package/dist/actions/interaction.js +96 -30
- package/dist/actions/interaction.js.map +1 -1
- package/dist/actions/touch.d.ts +25 -0
- package/dist/actions/touch.d.ts.map +1 -0
- package/dist/actions/touch.js +114 -0
- package/dist/actions/touch.js.map +1 -0
- package/dist/browser/browser-manager.d.ts +15 -0
- package/dist/browser/browser-manager.d.ts.map +1 -1
- package/dist/browser/browser-manager.js +75 -7
- package/dist/browser/browser-manager.js.map +1 -1
- package/dist/browser/network-analysis.d.ts +65 -0
- package/dist/browser/network-analysis.d.ts.map +1 -0
- package/dist/browser/network-analysis.js +359 -0
- package/dist/browser/network-analysis.js.map +1 -0
- package/dist/browser/network-tracker.d.ts +4 -0
- package/dist/browser/network-tracker.d.ts.map +1 -1
- package/dist/browser/network-tracker.js +41 -0
- package/dist/browser/network-tracker.js.map +1 -1
- package/dist/browser/popup-detector.d.ts +22 -0
- package/dist/browser/popup-detector.d.ts.map +1 -0
- package/dist/browser/popup-detector.js +138 -0
- package/dist/browser/popup-detector.js.map +1 -0
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +219 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/interact.d.ts +7 -0
- package/dist/cli/commands/interact.d.ts.map +1 -0
- package/dist/cli/commands/interact.js +371 -0
- package/dist/cli/commands/interact.js.map +1 -0
- package/dist/cli/commands/navigate.d.ts +4 -0
- package/dist/cli/commands/navigate.d.ts.map +1 -0
- package/dist/cli/commands/navigate.js +46 -0
- package/dist/cli/commands/navigate.js.map +1 -0
- package/dist/cli/commands/network.d.ts +3 -0
- package/dist/cli/commands/network.d.ts.map +1 -0
- package/dist/cli/commands/network.js +292 -0
- package/dist/cli/commands/network.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +3 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +84 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/query.d.ts +7 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +333 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/session.d.ts +3 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +372 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/shared.d.ts +24 -0
- package/dist/cli/commands/shared.d.ts.map +1 -0
- package/dist/cli/commands/shared.js +113 -0
- package/dist/cli/commands/shared.js.map +1 -0
- package/dist/cli/commands.d.ts +1 -7
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +1 -1684
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/connection.d.ts.map +1 -1
- package/dist/cli/connection.js +9 -1
- package/dist/cli/connection.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +1 -24
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +21 -1
- package/dist/daemon.js.map +1 -1
- package/dist/diff.d.ts +4 -0
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +16 -0
- package/dist/diff.js.map +1 -1
- package/dist/flow/exporters/cypress.js +1 -1
- package/dist/flow/exporters/cypress.js.map +1 -1
- package/dist/flow/exporters/selenium.js +1 -1
- package/dist/flow/exporters/selenium.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +2 -1
- package/dist/openapi.js.map +1 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +4 -1
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/types.d.ts +4 -4
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +30 -7
- package/dist/protocol.js.map +1 -1
- package/dist/snapshot/constants.d.ts +6 -0
- package/dist/snapshot/constants.d.ts.map +1 -0
- package/dist/snapshot/constants.js +77 -0
- package/dist/snapshot/constants.js.map +1 -0
- package/dist/snapshot/dom-scripts.d.ts +12 -0
- package/dist/snapshot/dom-scripts.d.ts.map +1 -0
- package/dist/snapshot/dom-scripts.js +438 -0
- package/dist/snapshot/dom-scripts.js.map +1 -0
- package/dist/snapshot/format.d.ts +13 -0
- package/dist/snapshot/format.d.ts.map +1 -0
- package/dist/snapshot/format.js +175 -0
- package/dist/snapshot/format.js.map +1 -0
- package/dist/snapshot/index.d.ts +6 -0
- package/dist/snapshot/index.d.ts.map +1 -0
- package/dist/snapshot/index.js +5 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/snapshot/refs.d.ts +3 -0
- package/dist/snapshot/refs.d.ts.map +1 -0
- package/dist/snapshot/refs.js +8 -0
- package/dist/snapshot/refs.js.map +1 -0
- package/dist/snapshot/selectors.d.ts +17 -0
- package/dist/snapshot/selectors.d.ts.map +1 -0
- package/dist/snapshot/selectors.js +619 -0
- package/dist/snapshot/selectors.js.map +1 -0
- package/dist/snapshot/snapshot.d.ts +12 -0
- package/dist/snapshot/snapshot.d.ts.map +1 -0
- package/dist/snapshot/snapshot.js +104 -0
- package/dist/snapshot/snapshot.js.map +1 -0
- package/dist/snapshot/types.d.ts +27 -0
- package/dist/snapshot/types.d.ts.map +1 -0
- package/dist/snapshot/types.js +2 -0
- package/dist/snapshot/types.js.map +1 -0
- package/dist/snapshot.d.ts +1 -79
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +1 -1800
- package/dist/snapshot.js.map +1 -1
- package/dist/stream/client-state.d.ts +13 -0
- package/dist/stream/client-state.d.ts.map +1 -0
- package/dist/stream/client-state.js +2 -0
- package/dist/stream/client-state.js.map +1 -0
- package/dist/stream/element-utils.d.ts +8 -0
- package/dist/stream/element-utils.d.ts.map +1 -0
- package/dist/stream/element-utils.js +25 -0
- package/dist/stream/element-utils.js.map +1 -0
- package/dist/stream/frame-processor.d.ts +63 -0
- package/dist/stream/frame-processor.d.ts.map +1 -0
- package/dist/stream/frame-processor.js +178 -0
- package/dist/stream/frame-processor.js.map +1 -0
- package/dist/stream/index.d.ts +10 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +5 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/input-handler.d.ts +10 -0
- package/dist/stream/input-handler.d.ts.map +1 -0
- package/dist/stream/input-handler.js +81 -0
- package/dist/stream/input-handler.js.map +1 -0
- package/dist/stream/messages.d.ts +144 -0
- package/dist/stream/messages.d.ts.map +1 -0
- package/dist/stream/messages.js +46 -0
- package/dist/stream/messages.js.map +1 -0
- package/dist/stream-server-standalone.d.ts +0 -3
- package/dist/stream-server-standalone.d.ts.map +1 -1
- package/dist/stream-server-standalone.js +22 -82
- package/dist/stream-server-standalone.js.map +1 -1
- package/dist/stream-server.d.ts +8 -212
- package/dist/stream-server.d.ts.map +1 -1
- package/dist/stream-server.js +35 -389
- package/dist/stream-server.js.map +1 -1
- package/dist/types/base.d.ts +11 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +2 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/browser.d.ts +26 -0
- package/dist/types/browser.d.ts.map +1 -0
- package/dist/types/browser.js +2 -0
- package/dist/types/browser.js.map +1 -0
- package/dist/types/commands.d.ts +768 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +2 -0
- package/dist/types/commands.js.map +1 -0
- package/dist/types/crawl.d.ts +89 -0
- package/dist/types/crawl.d.ts.map +1 -0
- package/dist/types/crawl.js +2 -0
- package/dist/types/crawl.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interact.d.ts +61 -0
- package/dist/types/interact.d.ts.map +1 -0
- package/dist/types/interact.js +2 -0
- package/dist/types/interact.js.map +1 -0
- package/dist/types/plugins.d.ts +39 -0
- package/dist/types/plugins.d.ts.map +1 -0
- package/dist/types/plugins.js +2 -0
- package/dist/types/plugins.js.map +1 -0
- package/dist/types/responses.d.ts +140 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +4 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/types/utils.d.ts +12 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +2 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types.d.ts +1 -1125
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -3
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +31 -0
- package/dist/version.js.map +1 -0
- package/package.json +11 -11
package/dist/stream-server.js
CHANGED
|
@@ -2,203 +2,16 @@ import * as net from 'net';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
5
|
-
import sharp from 'sharp';
|
|
6
5
|
import { setScreencastFrameCallback, setEventCallbacks } from './browser-events.js';
|
|
7
6
|
import { executeCommand } from './actions/index.js';
|
|
8
7
|
import { errorResponse, serializeResponse } from './protocol.js';
|
|
9
8
|
import { getSocketDir, getSession, getInstanceId } from './daemon.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
currentState = 'static';
|
|
17
|
-
isUserInteracting = false;
|
|
18
|
-
userInteractionTimer = null;
|
|
19
|
-
lastFrameTime = 0;
|
|
20
|
-
frameInterval = Infinity;
|
|
21
|
-
onStateChange = null;
|
|
22
|
-
staticTimer = null;
|
|
23
|
-
USER_INTERACTION_TIMEOUT_MS = 1000;
|
|
24
|
-
SCREEN_MOVING_THRESHOLD_MS = 1000;
|
|
25
|
-
STATIC_TIMEOUT_MS = 1500;
|
|
26
|
-
setStateChangeCallback(callback) {
|
|
27
|
-
this.onStateChange = callback;
|
|
28
|
-
}
|
|
29
|
-
setState(newState) {
|
|
30
|
-
if (newState !== this.currentState) {
|
|
31
|
-
const previousState = this.currentState;
|
|
32
|
-
this.currentState = newState;
|
|
33
|
-
this.onStateChange?.(newState, previousState);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
resetStaticTimer() {
|
|
37
|
-
if (this.staticTimer) {
|
|
38
|
-
clearTimeout(this.staticTimer);
|
|
39
|
-
}
|
|
40
|
-
this.staticTimer = setTimeout(() => {
|
|
41
|
-
if (!this.isUserInteracting) {
|
|
42
|
-
this.setState('static');
|
|
43
|
-
}
|
|
44
|
-
}, this.STATIC_TIMEOUT_MS);
|
|
45
|
-
}
|
|
46
|
-
onUserInteraction() {
|
|
47
|
-
this.setState('user_interacting');
|
|
48
|
-
this.isUserInteracting = true;
|
|
49
|
-
this.resetUserInteractionTimeout();
|
|
50
|
-
this.resetStaticTimer();
|
|
51
|
-
}
|
|
52
|
-
resetUserInteractionTimeout() {
|
|
53
|
-
if (this.userInteractionTimer) {
|
|
54
|
-
clearTimeout(this.userInteractionTimer);
|
|
55
|
-
}
|
|
56
|
-
this.userInteractionTimer = setTimeout(() => {
|
|
57
|
-
this.isUserInteracting = false;
|
|
58
|
-
const newState = this.frameInterval < this.SCREEN_MOVING_THRESHOLD_MS ? 'screen_moving' : 'static';
|
|
59
|
-
this.setState(newState);
|
|
60
|
-
}, this.USER_INTERACTION_TIMEOUT_MS);
|
|
61
|
-
}
|
|
62
|
-
onFrameReceived() {
|
|
63
|
-
const now = Date.now();
|
|
64
|
-
this.frameInterval = now - this.lastFrameTime;
|
|
65
|
-
this.lastFrameTime = now;
|
|
66
|
-
if (!this.isUserInteracting) {
|
|
67
|
-
const newState = this.frameInterval < this.SCREEN_MOVING_THRESHOLD_MS ? 'screen_moving' : 'static';
|
|
68
|
-
this.setState(newState);
|
|
69
|
-
}
|
|
70
|
-
this.resetStaticTimer();
|
|
71
|
-
}
|
|
72
|
-
getConfig() {
|
|
73
|
-
return STATE_CONFIGS[this.currentState];
|
|
74
|
-
}
|
|
75
|
-
getState() {
|
|
76
|
-
return this.currentState;
|
|
77
|
-
}
|
|
78
|
-
getFrameInterval() {
|
|
79
|
-
return this.frameInterval;
|
|
80
|
-
}
|
|
81
|
-
getIsUserInteracting() {
|
|
82
|
-
return this.isUserInteracting;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export class FrameRateController {
|
|
86
|
-
lastSentTime = 0;
|
|
87
|
-
fpsFrameCount = 0;
|
|
88
|
-
fpsLastTime = Date.now();
|
|
89
|
-
currentFps = 0;
|
|
90
|
-
FPS_CALCULATION_INTERVAL_MS = 1000;
|
|
91
|
-
shouldSendFrame(maxFps) {
|
|
92
|
-
const now = Date.now();
|
|
93
|
-
const minInterval = 1000 / maxFps;
|
|
94
|
-
if (now - this.lastSentTime >= minInterval) {
|
|
95
|
-
this.lastSentTime = now;
|
|
96
|
-
this.fpsFrameCount++;
|
|
97
|
-
this.calculateFps();
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
calculateFps() {
|
|
103
|
-
const now = Date.now();
|
|
104
|
-
const elapsed = now - this.fpsLastTime;
|
|
105
|
-
if (elapsed >= this.FPS_CALCULATION_INTERVAL_MS) {
|
|
106
|
-
this.currentFps = Math.round((this.fpsFrameCount * 1000) / elapsed);
|
|
107
|
-
this.fpsFrameCount = 0;
|
|
108
|
-
this.fpsLastTime = now;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
getCurrentFps() {
|
|
112
|
-
return this.currentFps;
|
|
113
|
-
}
|
|
114
|
-
reset() {
|
|
115
|
-
this.lastSentTime = 0;
|
|
116
|
-
this.fpsFrameCount = 0;
|
|
117
|
-
this.fpsLastTime = Date.now();
|
|
118
|
-
this.currentFps = 0;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
export class FrameProcessor {
|
|
122
|
-
screencastFormat = 'jpeg';
|
|
123
|
-
screencastQuality = 80;
|
|
124
|
-
async process(data, config, viewportWidth, viewportHeight, cropConfig) {
|
|
125
|
-
const buffer = Buffer.from(data, 'base64');
|
|
126
|
-
const needsResize = config.scale < 1 && viewportWidth && viewportHeight;
|
|
127
|
-
const needsCrop = !!cropConfig;
|
|
128
|
-
const needsReencode = config.format !== this.screencastFormat || config.quality !== this.screencastQuality;
|
|
129
|
-
if (!needsResize && !needsCrop && !needsReencode) {
|
|
130
|
-
return buffer;
|
|
131
|
-
}
|
|
132
|
-
let processed = sharp(buffer);
|
|
133
|
-
if (cropConfig) {
|
|
134
|
-
processed = processed.extract({
|
|
135
|
-
left: Math.round(cropConfig.x),
|
|
136
|
-
top: Math.round(cropConfig.y),
|
|
137
|
-
width: Math.round(cropConfig.width),
|
|
138
|
-
height: Math.round(cropConfig.height),
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
if (needsResize) {
|
|
142
|
-
const newWidth = Math.round((viewportWidth ?? 0) * config.scale);
|
|
143
|
-
const newHeight = Math.round((viewportHeight ?? 0) * config.scale);
|
|
144
|
-
processed = processed.resize(newWidth, newHeight);
|
|
145
|
-
}
|
|
146
|
-
if (config.format === 'jpeg') {
|
|
147
|
-
processed = processed.jpeg({ quality: config.quality });
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
processed = processed.webp({ quality: config.quality });
|
|
151
|
-
}
|
|
152
|
-
return processed.toBuffer();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function isPrivateIP(hostname) {
|
|
156
|
-
// IPv4 check
|
|
157
|
-
const parts = hostname.split('.').map(Number);
|
|
158
|
-
if (parts.length === 4 && parts.every((p) => !isNaN(p))) {
|
|
159
|
-
const [a, b] = parts;
|
|
160
|
-
if (a === 10)
|
|
161
|
-
return true;
|
|
162
|
-
if (a === 172 && b >= 16 && b <= 31)
|
|
163
|
-
return true;
|
|
164
|
-
if (a === 192 && b === 168)
|
|
165
|
-
return true;
|
|
166
|
-
if (a === 127)
|
|
167
|
-
return true;
|
|
168
|
-
if (a === 0)
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
// IPv6 check
|
|
172
|
-
const lower = hostname.toLowerCase();
|
|
173
|
-
if (lower === '::1' || lower === '[::1]' || lower === '::' || lower === 'localhost')
|
|
174
|
-
return true;
|
|
175
|
-
if (lower.startsWith('fc') || lower.startsWith('fd') || lower.startsWith('fe80'))
|
|
176
|
-
return true;
|
|
177
|
-
if (hostname === 'localhost')
|
|
178
|
-
return true;
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
export function isAllowedOrigin(origin) {
|
|
182
|
-
// CLI connections (no browser origin) are allowed — CLI clients don't send Origin headers
|
|
183
|
-
if (!origin) {
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
if (origin.startsWith('file://')) {
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
try {
|
|
190
|
-
const url = new URL(origin);
|
|
191
|
-
if (isPrivateIP(url.hostname)) {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
// Invalid origin URL - reject
|
|
197
|
-
}
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
function isCommandMessage(msg) {
|
|
201
|
-
return 'id' in msg && 'action' in msg && !('type' in msg);
|
|
9
|
+
import { getVersion } from './version.js';
|
|
10
|
+
import { StreamStateManager, FrameRateController, FrameProcessor, STATE_CONFIGS, isCommandMessage, isAllowedOrigin, getElementBox, handleInputEvent, } from './stream/index.js';
|
|
11
|
+
export { StreamStateManager, FrameRateController, FrameProcessor, STATE_CONFIGS, isAllowedOrigin };
|
|
12
|
+
const STREAM_SERVER_IPC_FILE = 'stream-server.ipc';
|
|
13
|
+
export function getStreamServerIpcPath() {
|
|
14
|
+
return path.join(getSocketDir(), STREAM_SERVER_IPC_FILE);
|
|
202
15
|
}
|
|
203
16
|
export class StreamServer {
|
|
204
17
|
wss = null;
|
|
@@ -332,7 +145,7 @@ export class StreamServer {
|
|
|
332
145
|
clientState.elementCheckTimer = setInterval(() => {
|
|
333
146
|
if (!clientState.selector)
|
|
334
147
|
return;
|
|
335
|
-
this.
|
|
148
|
+
getElementBox(this.browser, clientState.selector)
|
|
336
149
|
.then((newBox) => {
|
|
337
150
|
if (!newBox) {
|
|
338
151
|
if (clientState.elementBox || !clientState.degraded) {
|
|
@@ -418,50 +231,16 @@ export class StreamServer {
|
|
|
418
231
|
try {
|
|
419
232
|
switch (message.type) {
|
|
420
233
|
case 'input_mouse':
|
|
421
|
-
this.stateManager.onUserInteraction();
|
|
422
|
-
await this.browser.injectMouseEvent({
|
|
423
|
-
type: message.eventType,
|
|
424
|
-
x: message.x,
|
|
425
|
-
y: message.y,
|
|
426
|
-
button: message.button,
|
|
427
|
-
clickCount: message.clickCount,
|
|
428
|
-
deltaX: message.deltaX,
|
|
429
|
-
deltaY: message.deltaY,
|
|
430
|
-
modifiers: message.modifiers,
|
|
431
|
-
});
|
|
432
|
-
break;
|
|
433
234
|
case 'input_keyboard':
|
|
434
|
-
this.stateManager.onUserInteraction();
|
|
435
|
-
await this.browser.injectKeyboardEvent({
|
|
436
|
-
type: message.eventType,
|
|
437
|
-
key: message.key,
|
|
438
|
-
code: message.code,
|
|
439
|
-
text: message.text,
|
|
440
|
-
modifiers: message.modifiers,
|
|
441
|
-
});
|
|
442
|
-
break;
|
|
443
235
|
case 'input_touch':
|
|
444
|
-
this.stateManager.onUserInteraction();
|
|
445
|
-
await this.browser.injectTouchEvent({
|
|
446
|
-
type: message.eventType,
|
|
447
|
-
touchPoints: message.touchPoints,
|
|
448
|
-
modifiers: message.modifiers,
|
|
449
|
-
});
|
|
450
|
-
break;
|
|
451
236
|
case 'input_text':
|
|
452
|
-
this.stateManager.onUserInteraction();
|
|
453
|
-
await this.browser.insertText(message.text);
|
|
454
|
-
break;
|
|
455
237
|
case 'keyboard_down':
|
|
456
|
-
this.stateManager.onUserInteraction();
|
|
457
|
-
await this.browser.getPage().keyboard.down(message.key);
|
|
458
|
-
break;
|
|
459
238
|
case 'keyboard_up':
|
|
460
|
-
await this.browser.getPage().keyboard.up(message.key);
|
|
461
|
-
break;
|
|
462
239
|
case 'keyboard_insert_text':
|
|
463
|
-
|
|
464
|
-
|
|
240
|
+
case 'input_fill':
|
|
241
|
+
case 'input_blur_element':
|
|
242
|
+
case 'user_activity':
|
|
243
|
+
await handleInputEvent(message, this.browser, this.stateManager);
|
|
465
244
|
break;
|
|
466
245
|
case 'input_focused':
|
|
467
246
|
case 'input_value':
|
|
@@ -477,9 +256,6 @@ export class StreamServer {
|
|
|
477
256
|
}
|
|
478
257
|
}
|
|
479
258
|
break;
|
|
480
|
-
case 'user_activity':
|
|
481
|
-
this.stateManager.onUserInteraction();
|
|
482
|
-
break;
|
|
483
259
|
case 'status':
|
|
484
260
|
const cs = this.clients.get(ws);
|
|
485
261
|
if (cs?.selector) {
|
|
@@ -579,25 +355,26 @@ export class StreamServer {
|
|
|
579
355
|
}
|
|
580
356
|
}
|
|
581
357
|
}
|
|
582
|
-
async
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const rect = el.getBoundingClientRect();
|
|
590
|
-
return {
|
|
591
|
-
x: rect.x,
|
|
592
|
-
y: rect.y,
|
|
593
|
-
width: rect.width,
|
|
594
|
-
height: rect.height,
|
|
595
|
-
};
|
|
596
|
-
}, selector);
|
|
597
|
-
return box ?? undefined;
|
|
358
|
+
async refreshElementBox(ws, clientState) {
|
|
359
|
+
if (!clientState.selector)
|
|
360
|
+
return;
|
|
361
|
+
const box = await getElementBox(this.browser, clientState.selector);
|
|
362
|
+
if (box) {
|
|
363
|
+
clientState.elementBox = box;
|
|
364
|
+
clientState.degraded = false;
|
|
598
365
|
}
|
|
599
|
-
|
|
600
|
-
|
|
366
|
+
else if (!clientState.degraded) {
|
|
367
|
+
clientState.elementBox = undefined;
|
|
368
|
+
clientState.degraded = true;
|
|
369
|
+
const message = {
|
|
370
|
+
type: 'status',
|
|
371
|
+
connected: true,
|
|
372
|
+
screencasting: this.isScreencasting,
|
|
373
|
+
degraded: true,
|
|
374
|
+
};
|
|
375
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
376
|
+
ws.send(JSON.stringify(message));
|
|
377
|
+
}
|
|
601
378
|
}
|
|
602
379
|
}
|
|
603
380
|
sendStatus(ws, clientState) {
|
|
@@ -620,7 +397,7 @@ export class StreamServer {
|
|
|
620
397
|
viewportHeight,
|
|
621
398
|
fps: this.frameRateController.getCurrentFps(),
|
|
622
399
|
state: this.stateManager.getState(),
|
|
623
|
-
version:
|
|
400
|
+
version: getVersion(),
|
|
624
401
|
};
|
|
625
402
|
if (clientState?.elementBox) {
|
|
626
403
|
message.element = {
|
|
@@ -640,28 +417,6 @@ export class StreamServer {
|
|
|
640
417
|
ws.send(JSON.stringify(message));
|
|
641
418
|
}
|
|
642
419
|
}
|
|
643
|
-
async refreshElementBox(ws, clientState) {
|
|
644
|
-
if (!clientState.selector)
|
|
645
|
-
return;
|
|
646
|
-
const box = await this.getElementBox(clientState.selector);
|
|
647
|
-
if (box) {
|
|
648
|
-
clientState.elementBox = box;
|
|
649
|
-
clientState.degraded = false;
|
|
650
|
-
}
|
|
651
|
-
else if (!clientState.degraded) {
|
|
652
|
-
clientState.elementBox = undefined;
|
|
653
|
-
clientState.degraded = true;
|
|
654
|
-
const message = {
|
|
655
|
-
type: 'status',
|
|
656
|
-
connected: true,
|
|
657
|
-
screencasting: this.isScreencasting,
|
|
658
|
-
degraded: true,
|
|
659
|
-
};
|
|
660
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
661
|
-
ws.send(JSON.stringify(message));
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
420
|
sendError(ws, errorMessage) {
|
|
666
421
|
const message = {
|
|
667
422
|
type: 'error',
|
|
@@ -763,10 +518,6 @@ export class StreamServer {
|
|
|
763
518
|
return this.frameRateController;
|
|
764
519
|
}
|
|
765
520
|
}
|
|
766
|
-
const STREAM_SERVER_IPC_FILE = 'stream-server.ipc';
|
|
767
|
-
export function getStreamServerIpcPath() {
|
|
768
|
-
return path.join(getSocketDir(), STREAM_SERVER_IPC_FILE);
|
|
769
|
-
}
|
|
770
521
|
export class StreamServerProxy {
|
|
771
522
|
browser;
|
|
772
523
|
ipcSocket = null;
|
|
@@ -844,13 +595,13 @@ export class StreamServerProxy {
|
|
|
844
595
|
const line = buffer.substring(0, newlineIdx);
|
|
845
596
|
buffer = buffer.substring(newlineIdx + 1);
|
|
846
597
|
if (line.trim()) {
|
|
847
|
-
this.
|
|
598
|
+
this.handleIpcMessage(line);
|
|
848
599
|
}
|
|
849
600
|
}
|
|
850
601
|
});
|
|
851
602
|
});
|
|
852
603
|
}
|
|
853
|
-
|
|
604
|
+
async handleIpcMessage(line) {
|
|
854
605
|
try {
|
|
855
606
|
const message = JSON.parse(line);
|
|
856
607
|
switch (message.type) {
|
|
@@ -864,7 +615,7 @@ export class StreamServerProxy {
|
|
|
864
615
|
case 'input_fill':
|
|
865
616
|
case 'input_blur_element':
|
|
866
617
|
case 'user_activity':
|
|
867
|
-
this.
|
|
618
|
+
await handleInputEvent(message, this.browser, this.stateManager, this.inputFillDebounceMap, StreamServerProxy.INPUT_FILL_DEBOUNCE_MS);
|
|
868
619
|
break;
|
|
869
620
|
case 'client_connected':
|
|
870
621
|
this.handleClientConnected(message.session);
|
|
@@ -874,7 +625,7 @@ export class StreamServerProxy {
|
|
|
874
625
|
break;
|
|
875
626
|
case 'request_element_box':
|
|
876
627
|
(async () => {
|
|
877
|
-
const box = await this.
|
|
628
|
+
const box = await getElementBox(this.browser, message.selector);
|
|
878
629
|
const response = {
|
|
879
630
|
type: 'selector_element',
|
|
880
631
|
session: message.session ?? this.session,
|
|
@@ -919,86 +670,6 @@ export class StreamServerProxy {
|
|
|
919
670
|
console.error('[StreamServerProxy] Failed to stop screencast on client disconnected:', error);
|
|
920
671
|
}
|
|
921
672
|
}
|
|
922
|
-
async handleInputMessage(message) {
|
|
923
|
-
try {
|
|
924
|
-
switch (message.type) {
|
|
925
|
-
case 'input_mouse':
|
|
926
|
-
this.stateManager.onUserInteraction();
|
|
927
|
-
await this.browser.injectMouseEvent({
|
|
928
|
-
type: message.eventType,
|
|
929
|
-
x: message.x,
|
|
930
|
-
y: message.y,
|
|
931
|
-
button: message.button,
|
|
932
|
-
clickCount: message.clickCount,
|
|
933
|
-
deltaX: message.deltaX,
|
|
934
|
-
deltaY: message.deltaY,
|
|
935
|
-
modifiers: message.modifiers,
|
|
936
|
-
});
|
|
937
|
-
break;
|
|
938
|
-
case 'input_keyboard':
|
|
939
|
-
this.stateManager.onUserInteraction();
|
|
940
|
-
await this.browser.injectKeyboardEvent({
|
|
941
|
-
type: message.eventType,
|
|
942
|
-
key: message.key,
|
|
943
|
-
code: message.code,
|
|
944
|
-
text: message.text,
|
|
945
|
-
modifiers: message.modifiers,
|
|
946
|
-
});
|
|
947
|
-
break;
|
|
948
|
-
case 'input_touch':
|
|
949
|
-
this.stateManager.onUserInteraction();
|
|
950
|
-
await this.browser.injectTouchEvent({
|
|
951
|
-
type: message.eventType,
|
|
952
|
-
touchPoints: message.touchPoints,
|
|
953
|
-
modifiers: message.modifiers,
|
|
954
|
-
});
|
|
955
|
-
break;
|
|
956
|
-
case 'input_text':
|
|
957
|
-
this.stateManager.onUserInteraction();
|
|
958
|
-
await this.browser.insertText(message.text);
|
|
959
|
-
break;
|
|
960
|
-
case 'keyboard_down':
|
|
961
|
-
this.stateManager.onUserInteraction();
|
|
962
|
-
await this.browser.getPage().keyboard.down(message.key);
|
|
963
|
-
break;
|
|
964
|
-
case 'keyboard_up':
|
|
965
|
-
await this.browser.getPage().keyboard.up(message.key);
|
|
966
|
-
break;
|
|
967
|
-
case 'keyboard_insert_text':
|
|
968
|
-
this.stateManager.onUserInteraction();
|
|
969
|
-
await this.browser.getPage().keyboard.insertText(message.text);
|
|
970
|
-
break;
|
|
971
|
-
case 'input_fill': {
|
|
972
|
-
const sel = message.selector || '';
|
|
973
|
-
const txt = message.text || '';
|
|
974
|
-
const key = sel || '__global__';
|
|
975
|
-
const prev = this.inputFillDebounceMap.get(key);
|
|
976
|
-
if (prev)
|
|
977
|
-
clearTimeout(prev.timer);
|
|
978
|
-
const timer = setTimeout(async () => {
|
|
979
|
-
this.inputFillDebounceMap.delete(key);
|
|
980
|
-
try {
|
|
981
|
-
await this.browser.fillValue(sel, txt);
|
|
982
|
-
}
|
|
983
|
-
catch (e) {
|
|
984
|
-
console.error('[StreamServer] input_fill debounce error:', e.message);
|
|
985
|
-
}
|
|
986
|
-
}, StreamServerProxy.INPUT_FILL_DEBOUNCE_MS);
|
|
987
|
-
this.inputFillDebounceMap.set(key, { timer, text: txt, selector: sel });
|
|
988
|
-
break;
|
|
989
|
-
}
|
|
990
|
-
case 'input_blur_element':
|
|
991
|
-
await this.browser.blurElement(message.selector || '');
|
|
992
|
-
break;
|
|
993
|
-
case 'user_activity':
|
|
994
|
-
this.stateManager.onUserInteraction();
|
|
995
|
-
break;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
catch (error) {
|
|
999
|
-
console.error('[StreamServerProxy] Failed to handle input:', error);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
673
|
setupFrameCallback() {
|
|
1003
674
|
setScreencastFrameCallback((frame) => {
|
|
1004
675
|
this.sendFrame(frame).catch((err) => {
|
|
@@ -1058,31 +729,6 @@ export class StreamServerProxy {
|
|
|
1058
729
|
elementBox,
|
|
1059
730
|
});
|
|
1060
731
|
}
|
|
1061
|
-
async getElementBox(selector) {
|
|
1062
|
-
try {
|
|
1063
|
-
const page = this.browser.getPage();
|
|
1064
|
-
if (!page) {
|
|
1065
|
-
return undefined;
|
|
1066
|
-
}
|
|
1067
|
-
const box = await page.evaluate((sel) => {
|
|
1068
|
-
const el = document.querySelector(sel);
|
|
1069
|
-
if (!el)
|
|
1070
|
-
return null;
|
|
1071
|
-
const rect = el.getBoundingClientRect();
|
|
1072
|
-
return {
|
|
1073
|
-
x: rect.x,
|
|
1074
|
-
y: rect.y,
|
|
1075
|
-
width: rect.width,
|
|
1076
|
-
height: rect.height,
|
|
1077
|
-
};
|
|
1078
|
-
}, selector);
|
|
1079
|
-
return box ?? undefined;
|
|
1080
|
-
}
|
|
1081
|
-
catch (err) {
|
|
1082
|
-
console.error('[StreamServerProxy] getElementBox error:', err);
|
|
1083
|
-
return undefined;
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
732
|
getDaemonSocketPath() {
|
|
1087
733
|
const isWindows = process.platform === 'win32';
|
|
1088
734
|
if (isWindows) {
|