kiro-mobile-bridge 1.0.8 → 1.0.11
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/README.md +9 -5
- package/package.json +1 -1
- package/src/public/index.html +258 -11
- package/src/routes/api.js +257 -76
- package/src/server.js +33 -17
- package/src/services/cdp.js +70 -16
- package/src/services/click.js +325 -74
- package/src/services/message.js +9 -1
- package/src/services/snapshot.js +64 -25
- package/src/utils/constants.js +116 -0
- package/src/utils/hash.js +12 -0
- package/src/utils/network.js +72 -2
- package/src/utils/security.js +160 -0
package/src/services/cdp.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import http from 'http';
|
|
5
5
|
import { WebSocket } from 'ws';
|
|
6
|
+
import { CDP_CALL_TIMEOUT, HTTP_TIMEOUT } from '../utils/constants.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Fetch JSON from a CDP endpoint
|
|
@@ -14,7 +15,7 @@ export function fetchCDPTargets(port, path = '/json/list') {
|
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
15
16
|
const url = `http://127.0.0.1:${port}${path}`;
|
|
16
17
|
|
|
17
|
-
const req = http.get(url, { timeout:
|
|
18
|
+
const req = http.get(url, { timeout: HTTP_TIMEOUT }, (res) => {
|
|
18
19
|
let data = '';
|
|
19
20
|
res.on('data', chunk => data += chunk);
|
|
20
21
|
res.on('end', () => {
|
|
@@ -34,6 +35,22 @@ export function fetchCDPTargets(port, path = '/json/list') {
|
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {Object} PendingCall
|
|
40
|
+
* @property {Function} resolve - Promise resolve function
|
|
41
|
+
* @property {Function} reject - Promise reject function
|
|
42
|
+
* @property {NodeJS.Timeout} timeoutId - Timeout handle for cleanup
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {Object} CDPConnection
|
|
47
|
+
* @property {WebSocket} ws - WebSocket connection
|
|
48
|
+
* @property {Array} contexts - Execution contexts
|
|
49
|
+
* @property {number|null} rootContextId - Root context ID
|
|
50
|
+
* @property {Function} call - Make a CDP call
|
|
51
|
+
* @property {Function} close - Close the connection
|
|
52
|
+
*/
|
|
53
|
+
|
|
37
54
|
/**
|
|
38
55
|
* Create a CDP connection to a target
|
|
39
56
|
* @param {string} wsUrl - WebSocket debugger URL
|
|
@@ -43,11 +60,27 @@ export function connectToCDP(wsUrl) {
|
|
|
43
60
|
return new Promise((resolve, reject) => {
|
|
44
61
|
const ws = new WebSocket(wsUrl);
|
|
45
62
|
let idCounter = 1;
|
|
63
|
+
/** @type {Map<number, PendingCall>} */
|
|
46
64
|
const pendingCalls = new Map();
|
|
47
65
|
const contexts = [];
|
|
48
66
|
let rootContextId = null;
|
|
49
67
|
let isConnected = false;
|
|
50
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Clear all pending calls and their timeouts
|
|
71
|
+
* @param {Error} error - Error to reject pending calls with
|
|
72
|
+
*/
|
|
73
|
+
function clearAllPendingCalls(error) {
|
|
74
|
+
for (const [id, pending] of pendingCalls) {
|
|
75
|
+
// Clear the timeout to prevent memory leak
|
|
76
|
+
if (pending.timeoutId) {
|
|
77
|
+
clearTimeout(pending.timeoutId);
|
|
78
|
+
}
|
|
79
|
+
pending.reject(error);
|
|
80
|
+
}
|
|
81
|
+
pendingCalls.clear();
|
|
82
|
+
}
|
|
83
|
+
|
|
51
84
|
ws.on('message', (rawMsg) => {
|
|
52
85
|
try {
|
|
53
86
|
const msg = JSON.parse(rawMsg.toString());
|
|
@@ -75,12 +108,19 @@ export function connectToCDP(wsUrl) {
|
|
|
75
108
|
}
|
|
76
109
|
|
|
77
110
|
if (msg.id !== undefined && pendingCalls.has(msg.id)) {
|
|
78
|
-
const
|
|
111
|
+
const pending = pendingCalls.get(msg.id);
|
|
112
|
+
|
|
113
|
+
// Clear the timeout since we got a response
|
|
114
|
+
if (pending.timeoutId) {
|
|
115
|
+
clearTimeout(pending.timeoutId);
|
|
116
|
+
}
|
|
117
|
+
|
|
79
118
|
pendingCalls.delete(msg.id);
|
|
119
|
+
|
|
80
120
|
if (msg.error) {
|
|
81
|
-
|
|
121
|
+
pending.reject(new Error(`CDP Error: ${msg.error.message} (code: ${msg.error.code})`));
|
|
82
122
|
} else {
|
|
83
|
-
|
|
123
|
+
pending.resolve(msg.result);
|
|
84
124
|
}
|
|
85
125
|
}
|
|
86
126
|
} catch (e) {
|
|
@@ -97,6 +137,12 @@ export function connectToCDP(wsUrl) {
|
|
|
97
137
|
contexts,
|
|
98
138
|
get rootContextId() { return rootContextId; },
|
|
99
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Make a CDP call
|
|
142
|
+
* @param {string} method - CDP method name
|
|
143
|
+
* @param {object} params - Method parameters
|
|
144
|
+
* @returns {Promise<any>} - Call result
|
|
145
|
+
*/
|
|
100
146
|
call(method, params = {}) {
|
|
101
147
|
return new Promise((res, rej) => {
|
|
102
148
|
if (!isConnected) {
|
|
@@ -105,24 +151,35 @@ export function connectToCDP(wsUrl) {
|
|
|
105
151
|
}
|
|
106
152
|
|
|
107
153
|
const id = idCounter++;
|
|
108
|
-
pendingCalls.set(id, { resolve: res, reject: rej });
|
|
109
|
-
ws.send(JSON.stringify({ id, method, params }));
|
|
110
154
|
|
|
111
|
-
|
|
155
|
+
// Set up timeout with cleanup
|
|
156
|
+
const timeoutId = setTimeout(() => {
|
|
112
157
|
if (pendingCalls.has(id)) {
|
|
113
158
|
pendingCalls.delete(id);
|
|
114
159
|
rej(new Error(`CDP call timeout: ${method}`));
|
|
115
160
|
}
|
|
116
|
-
},
|
|
161
|
+
}, CDP_CALL_TIMEOUT);
|
|
162
|
+
|
|
163
|
+
// Store pending call with timeout reference for cleanup
|
|
164
|
+
pendingCalls.set(id, { resolve: res, reject: rej, timeoutId });
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
ws.send(JSON.stringify({ id, method, params }));
|
|
168
|
+
} catch (sendError) {
|
|
169
|
+
// Clean up on send failure
|
|
170
|
+
clearTimeout(timeoutId);
|
|
171
|
+
pendingCalls.delete(id);
|
|
172
|
+
rej(new Error(`Failed to send CDP call: ${sendError.message}`));
|
|
173
|
+
}
|
|
117
174
|
});
|
|
118
175
|
},
|
|
119
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Close the CDP connection
|
|
179
|
+
*/
|
|
120
180
|
close() {
|
|
121
181
|
isConnected = false;
|
|
122
|
-
|
|
123
|
-
reject(new Error('CDP connection closed'));
|
|
124
|
-
}
|
|
125
|
-
pendingCalls.clear();
|
|
182
|
+
clearAllPendingCalls(new Error('CDP connection closed'));
|
|
126
183
|
ws.terminate();
|
|
127
184
|
}
|
|
128
185
|
};
|
|
@@ -147,10 +204,7 @@ export function connectToCDP(wsUrl) {
|
|
|
147
204
|
ws.on('close', () => {
|
|
148
205
|
console.log('[CDP] Connection closed');
|
|
149
206
|
isConnected = false;
|
|
150
|
-
|
|
151
|
-
reject(new Error('CDP connection closed'));
|
|
152
|
-
}
|
|
153
|
-
pendingCalls.clear();
|
|
207
|
+
clearAllPendingCalls(new Error('CDP connection closed'));
|
|
154
208
|
});
|
|
155
209
|
});
|
|
156
210
|
}
|