browser-pilot 0.0.13 → 0.0.15
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 +82 -617
- package/dist/actions.cjs +1438 -17
- package/dist/actions.d.cts +21 -3
- package/dist/actions.d.ts +21 -3
- package/dist/actions.mjs +1 -1
- package/dist/browser-MEWT75IB.mjs +11 -0
- package/dist/browser.cjs +1583 -22
- package/dist/browser.d.cts +12 -3
- package/dist/browser.d.ts +12 -3
- package/dist/browser.mjs +3 -3
- package/dist/cdp.cjs +36 -3
- package/dist/cdp.d.cts +1 -1
- package/dist/cdp.d.ts +1 -1
- package/dist/cdp.mjs +3 -1
- package/dist/{chunk-A2ZRAEO3.mjs → chunk-7YVCOL2W.mjs} +1428 -17
- package/dist/chunk-BVZALQT4.mjs +303 -0
- package/dist/chunk-DTVRFXKI.mjs +35 -0
- package/dist/{chunk-HP6R3W32.mjs → chunk-LCNFBXB5.mjs} +33 -6
- package/dist/chunk-LUGLEMVR.mjs +11 -0
- package/dist/chunk-USYSHCI3.mjs +8640 -0
- package/dist/chunk-WPNW23CE.mjs +466 -0
- package/dist/{chunk-VDAMDOS6.mjs → chunk-ZAXQ5OTV.mjs} +151 -7
- package/dist/cli.mjs +3225 -8434
- package/dist/{client-DRqxBdHv.d.ts → client-B5QBRgIy.d.cts} +10 -6
- package/dist/{client-DRqxBdHv.d.cts → client-B5QBRgIy.d.ts} +10 -6
- package/dist/client-JWWZWO6L.mjs +12 -0
- package/dist/index.cjs +1629 -24
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +3 -3
- package/dist/page-XPS6IC6V.mjs +7 -0
- package/dist/transport-WHEBAZUP.mjs +83 -0
- package/dist/{types-CzgQjai9.d.ts → types-C9ySEdOX.d.cts} +78 -4
- package/dist/{types-BXMGFtnB.d.cts → types-Cvvf0oGu.d.ts} +78 -4
- package/package.json +2 -2
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CDPError
|
|
3
|
+
} from "./chunk-JXAUPHZM.mjs";
|
|
4
|
+
|
|
5
|
+
// src/utils/json.ts
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === "object" && value !== null;
|
|
8
|
+
}
|
|
9
|
+
function stringifyUnknown(value) {
|
|
10
|
+
if (typeof value === "string") return value;
|
|
11
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
12
|
+
return String(value);
|
|
13
|
+
}
|
|
14
|
+
if (value === null) return "null";
|
|
15
|
+
if (value === void 0) return "undefined";
|
|
16
|
+
try {
|
|
17
|
+
return JSON.stringify(value);
|
|
18
|
+
} catch {
|
|
19
|
+
return Object.prototype.toString.call(value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/cdp/transport.ts
|
|
24
|
+
function createTransport(wsUrl, options = {}) {
|
|
25
|
+
const { timeout = 3e4 } = options;
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const timeoutId = setTimeout(() => {
|
|
28
|
+
reject(new Error(`WebSocket connection timeout after ${timeout}ms`));
|
|
29
|
+
}, timeout);
|
|
30
|
+
const ws = new WebSocket(wsUrl);
|
|
31
|
+
const messageHandlers = [];
|
|
32
|
+
const closeHandlers = [];
|
|
33
|
+
const errorHandlers = [];
|
|
34
|
+
ws.addEventListener("open", () => {
|
|
35
|
+
clearTimeout(timeoutId);
|
|
36
|
+
const transport = {
|
|
37
|
+
send(message) {
|
|
38
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
39
|
+
ws.send(message);
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Cannot send message, WebSocket is ${getReadyStateString(ws.readyState)}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
async close() {
|
|
47
|
+
return new Promise((resolveClose) => {
|
|
48
|
+
if (ws.readyState === WebSocket.CLOSED) {
|
|
49
|
+
resolveClose();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let settled = false;
|
|
53
|
+
let fallbackTimer;
|
|
54
|
+
const finish = () => {
|
|
55
|
+
if (settled) return;
|
|
56
|
+
settled = true;
|
|
57
|
+
if (fallbackTimer) clearTimeout(fallbackTimer);
|
|
58
|
+
ws.removeEventListener("close", onClose);
|
|
59
|
+
resolveClose();
|
|
60
|
+
};
|
|
61
|
+
const onClose = () => {
|
|
62
|
+
finish();
|
|
63
|
+
};
|
|
64
|
+
ws.addEventListener("close", onClose);
|
|
65
|
+
try {
|
|
66
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
67
|
+
ws.close();
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
finish();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
fallbackTimer = setTimeout(finish, 200);
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
onMessage(handler) {
|
|
77
|
+
messageHandlers.push(handler);
|
|
78
|
+
},
|
|
79
|
+
onClose(handler) {
|
|
80
|
+
closeHandlers.push(handler);
|
|
81
|
+
},
|
|
82
|
+
onError(handler) {
|
|
83
|
+
errorHandlers.push(handler);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
resolve(transport);
|
|
87
|
+
});
|
|
88
|
+
ws.addEventListener("message", (event) => {
|
|
89
|
+
const data = typeof event.data === "string" ? event.data : String(event.data);
|
|
90
|
+
for (const handler of messageHandlers) {
|
|
91
|
+
handler(data);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
ws.addEventListener("close", () => {
|
|
95
|
+
for (const handler of closeHandlers) {
|
|
96
|
+
handler();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
ws.addEventListener("error", (_event) => {
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
const error = new Error("WebSocket connection error");
|
|
102
|
+
for (const handler of errorHandlers) {
|
|
103
|
+
handler(error);
|
|
104
|
+
}
|
|
105
|
+
reject(error);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function getReadyStateString(state) {
|
|
110
|
+
switch (state) {
|
|
111
|
+
case WebSocket.CONNECTING:
|
|
112
|
+
return "CONNECTING";
|
|
113
|
+
case WebSocket.OPEN:
|
|
114
|
+
return "OPEN";
|
|
115
|
+
case WebSocket.CLOSING:
|
|
116
|
+
return "CLOSING";
|
|
117
|
+
case WebSocket.CLOSED:
|
|
118
|
+
return "CLOSED";
|
|
119
|
+
default:
|
|
120
|
+
return "UNKNOWN";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/cdp/client.ts
|
|
125
|
+
function createCDPClientFromTransport(transport, options = {}) {
|
|
126
|
+
return buildCDPClient(transport, options);
|
|
127
|
+
}
|
|
128
|
+
async function createCDPClient(wsUrl, options = {}) {
|
|
129
|
+
const { timeout = 3e4 } = options;
|
|
130
|
+
const transport = await createTransport(wsUrl, { timeout });
|
|
131
|
+
return buildCDPClient(transport, options);
|
|
132
|
+
}
|
|
133
|
+
function buildCDPClient(transport, options = {}) {
|
|
134
|
+
const { debug = false, timeout = 3e4 } = options;
|
|
135
|
+
let messageId = 0;
|
|
136
|
+
let currentSessionId;
|
|
137
|
+
let connected = true;
|
|
138
|
+
const pending = /* @__PURE__ */ new Map();
|
|
139
|
+
const eventHandlers = /* @__PURE__ */ new Map();
|
|
140
|
+
const anyEventHandlers = /* @__PURE__ */ new Set();
|
|
141
|
+
transport.onMessage((raw) => {
|
|
142
|
+
let msg;
|
|
143
|
+
try {
|
|
144
|
+
const parsed = JSON.parse(raw);
|
|
145
|
+
if (!isRecord(parsed)) {
|
|
146
|
+
if (debug) console.error("[CDP] Ignoring non-object message:", raw);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if ("id" in parsed && typeof parsed["id"] === "number") {
|
|
150
|
+
msg = parsed;
|
|
151
|
+
} else if ("method" in parsed && typeof parsed["method"] === "string") {
|
|
152
|
+
msg = parsed;
|
|
153
|
+
} else {
|
|
154
|
+
if (debug) console.error("[CDP] Ignoring invalid message shape:", raw);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
if (debug) console.error("[CDP] Failed to parse message:", raw);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (debug) {
|
|
162
|
+
console.log("[CDP] <--", JSON.stringify(msg, null, 2).slice(0, 500));
|
|
163
|
+
}
|
|
164
|
+
if ("id" in msg && typeof msg.id === "number") {
|
|
165
|
+
const response = msg;
|
|
166
|
+
const request = pending.get(response.id);
|
|
167
|
+
if (request) {
|
|
168
|
+
pending.delete(response.id);
|
|
169
|
+
clearTimeout(request.timer);
|
|
170
|
+
if (response.error) {
|
|
171
|
+
const error = typeof response.error === "string" ? { code: -32e3, message: response.error } : response.error;
|
|
172
|
+
request.reject(new CDPError(error));
|
|
173
|
+
} else {
|
|
174
|
+
request.resolve(response.result);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if ("method" in msg) {
|
|
180
|
+
const event = msg;
|
|
181
|
+
const params = event.params ?? {};
|
|
182
|
+
for (const handler of anyEventHandlers) {
|
|
183
|
+
try {
|
|
184
|
+
handler(event.method, params);
|
|
185
|
+
} catch (e) {
|
|
186
|
+
if (debug) console.error("[CDP] Error in any-event handler:", e);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const handlers = eventHandlers.get(event.method);
|
|
190
|
+
if (handlers) {
|
|
191
|
+
for (const handler of handlers) {
|
|
192
|
+
try {
|
|
193
|
+
handler(params);
|
|
194
|
+
} catch (e) {
|
|
195
|
+
if (debug) console.error(`[CDP] Error in handler for ${event.method}:`, e);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
transport.onClose(() => {
|
|
202
|
+
connected = false;
|
|
203
|
+
for (const [id, request] of pending) {
|
|
204
|
+
clearTimeout(request.timer);
|
|
205
|
+
request.reject(new Error("WebSocket connection closed"));
|
|
206
|
+
pending.delete(id);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
transport.onError((error) => {
|
|
210
|
+
if (debug) console.error("[CDP] Transport error:", error);
|
|
211
|
+
});
|
|
212
|
+
const client = {
|
|
213
|
+
async send(method, params, sessionId) {
|
|
214
|
+
if (!connected) {
|
|
215
|
+
throw new Error("CDP client is not connected");
|
|
216
|
+
}
|
|
217
|
+
const id = ++messageId;
|
|
218
|
+
const effectiveSessionId = sessionId === null ? void 0 : sessionId ?? currentSessionId;
|
|
219
|
+
const request = { id, method };
|
|
220
|
+
if (params !== void 0) {
|
|
221
|
+
request.params = params;
|
|
222
|
+
}
|
|
223
|
+
if (effectiveSessionId !== void 0) {
|
|
224
|
+
request.sessionId = effectiveSessionId;
|
|
225
|
+
}
|
|
226
|
+
const message = JSON.stringify(request);
|
|
227
|
+
if (debug) {
|
|
228
|
+
console.log("[CDP] -->", message.slice(0, 500));
|
|
229
|
+
}
|
|
230
|
+
return new Promise((resolve, reject) => {
|
|
231
|
+
const timer = setTimeout(() => {
|
|
232
|
+
pending.delete(id);
|
|
233
|
+
reject(new Error(`CDP command ${method} timed out after ${timeout}ms`));
|
|
234
|
+
}, timeout);
|
|
235
|
+
pending.set(id, {
|
|
236
|
+
resolve,
|
|
237
|
+
reject,
|
|
238
|
+
method,
|
|
239
|
+
timer
|
|
240
|
+
});
|
|
241
|
+
try {
|
|
242
|
+
transport.send(message);
|
|
243
|
+
} catch (e) {
|
|
244
|
+
pending.delete(id);
|
|
245
|
+
clearTimeout(timer);
|
|
246
|
+
reject(e);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
},
|
|
250
|
+
on(event, handler) {
|
|
251
|
+
let handlers = eventHandlers.get(event);
|
|
252
|
+
if (!handlers) {
|
|
253
|
+
handlers = /* @__PURE__ */ new Set();
|
|
254
|
+
eventHandlers.set(event, handlers);
|
|
255
|
+
}
|
|
256
|
+
handlers.add(handler);
|
|
257
|
+
},
|
|
258
|
+
off(event, handler) {
|
|
259
|
+
const handlers = eventHandlers.get(event);
|
|
260
|
+
if (handlers) {
|
|
261
|
+
handlers.delete(handler);
|
|
262
|
+
if (handlers.size === 0) {
|
|
263
|
+
eventHandlers.delete(event);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
onAny(handler) {
|
|
268
|
+
anyEventHandlers.add(handler);
|
|
269
|
+
},
|
|
270
|
+
offAny(handler) {
|
|
271
|
+
anyEventHandlers.delete(handler);
|
|
272
|
+
},
|
|
273
|
+
async close() {
|
|
274
|
+
connected = false;
|
|
275
|
+
await transport.close();
|
|
276
|
+
},
|
|
277
|
+
async attachToTarget(targetId) {
|
|
278
|
+
const result = await this.send("Target.attachToTarget", {
|
|
279
|
+
targetId,
|
|
280
|
+
flatten: true
|
|
281
|
+
});
|
|
282
|
+
currentSessionId = result.sessionId;
|
|
283
|
+
return result.sessionId;
|
|
284
|
+
},
|
|
285
|
+
get sessionId() {
|
|
286
|
+
return currentSessionId;
|
|
287
|
+
},
|
|
288
|
+
setSessionId(sessionId) {
|
|
289
|
+
currentSessionId = sessionId;
|
|
290
|
+
},
|
|
291
|
+
get isConnected() {
|
|
292
|
+
return connected;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
return client;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export {
|
|
299
|
+
stringifyUnknown,
|
|
300
|
+
createTransport,
|
|
301
|
+
createCDPClientFromTransport,
|
|
302
|
+
createCDPClient
|
|
303
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/cdp/protocol.ts
|
|
2
|
+
var CDPError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
data;
|
|
5
|
+
constructor(error) {
|
|
6
|
+
super(error.message);
|
|
7
|
+
this.name = "CDPError";
|
|
8
|
+
this.code = error.code;
|
|
9
|
+
this.data = error.data;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/utils/json.ts
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return typeof value === "object" && value !== null;
|
|
16
|
+
}
|
|
17
|
+
function stringifyUnknown(value) {
|
|
18
|
+
if (typeof value === "string") return value;
|
|
19
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
20
|
+
return String(value);
|
|
21
|
+
}
|
|
22
|
+
if (value === null) return "null";
|
|
23
|
+
if (value === void 0) return "undefined";
|
|
24
|
+
try {
|
|
25
|
+
return JSON.stringify(value);
|
|
26
|
+
} catch {
|
|
27
|
+
return Object.prototype.toString.call(value);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
CDPError,
|
|
33
|
+
isRecord,
|
|
34
|
+
stringifyUnknown
|
|
35
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CDPError
|
|
3
|
-
|
|
2
|
+
CDPError,
|
|
3
|
+
isRecord
|
|
4
|
+
} from "./chunk-DTVRFXKI.mjs";
|
|
4
5
|
|
|
5
6
|
// src/cdp/transport.ts
|
|
6
7
|
function createTransport(wsUrl, options = {}) {
|
|
@@ -104,9 +105,16 @@ function getReadyStateString(state) {
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
// src/cdp/client.ts
|
|
108
|
+
function createCDPClientFromTransport(transport, options = {}) {
|
|
109
|
+
return buildCDPClient(transport, options);
|
|
110
|
+
}
|
|
107
111
|
async function createCDPClient(wsUrl, options = {}) {
|
|
108
|
-
const {
|
|
112
|
+
const { timeout = 3e4 } = options;
|
|
109
113
|
const transport = await createTransport(wsUrl, { timeout });
|
|
114
|
+
return buildCDPClient(transport, options);
|
|
115
|
+
}
|
|
116
|
+
function buildCDPClient(transport, options = {}) {
|
|
117
|
+
const { debug = false, timeout = 3e4 } = options;
|
|
110
118
|
let messageId = 0;
|
|
111
119
|
let currentSessionId;
|
|
112
120
|
let connected = true;
|
|
@@ -116,7 +124,19 @@ async function createCDPClient(wsUrl, options = {}) {
|
|
|
116
124
|
transport.onMessage((raw) => {
|
|
117
125
|
let msg;
|
|
118
126
|
try {
|
|
119
|
-
|
|
127
|
+
const parsed = JSON.parse(raw);
|
|
128
|
+
if (!isRecord(parsed)) {
|
|
129
|
+
if (debug) console.error("[CDP] Ignoring non-object message:", raw);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if ("id" in parsed && typeof parsed["id"] === "number") {
|
|
133
|
+
msg = parsed;
|
|
134
|
+
} else if ("method" in parsed && typeof parsed["method"] === "string") {
|
|
135
|
+
msg = parsed;
|
|
136
|
+
} else {
|
|
137
|
+
if (debug) console.error("[CDP] Ignoring invalid message shape:", raw);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
120
140
|
} catch {
|
|
121
141
|
if (debug) console.error("[CDP] Failed to parse message:", raw);
|
|
122
142
|
return;
|
|
@@ -131,7 +151,8 @@ async function createCDPClient(wsUrl, options = {}) {
|
|
|
131
151
|
pending.delete(response.id);
|
|
132
152
|
clearTimeout(request.timer);
|
|
133
153
|
if (response.error) {
|
|
134
|
-
|
|
154
|
+
const error = typeof response.error === "string" ? { code: -32e3, message: response.error } : response.error;
|
|
155
|
+
request.reject(new CDPError(error));
|
|
135
156
|
} else {
|
|
136
157
|
request.resolve(response.result);
|
|
137
158
|
}
|
|
@@ -229,6 +250,9 @@ async function createCDPClient(wsUrl, options = {}) {
|
|
|
229
250
|
onAny(handler) {
|
|
230
251
|
anyEventHandlers.add(handler);
|
|
231
252
|
},
|
|
253
|
+
offAny(handler) {
|
|
254
|
+
anyEventHandlers.delete(handler);
|
|
255
|
+
},
|
|
232
256
|
async close() {
|
|
233
257
|
connected = false;
|
|
234
258
|
await transport.close();
|
|
@@ -244,6 +268,9 @@ async function createCDPClient(wsUrl, options = {}) {
|
|
|
244
268
|
get sessionId() {
|
|
245
269
|
return currentSessionId;
|
|
246
270
|
},
|
|
271
|
+
setSessionId(sessionId) {
|
|
272
|
+
currentSessionId = sessionId;
|
|
273
|
+
},
|
|
247
274
|
get isConnected() {
|
|
248
275
|
return connected;
|
|
249
276
|
}
|
|
@@ -252,6 +279,6 @@ async function createCDPClient(wsUrl, options = {}) {
|
|
|
252
279
|
}
|
|
253
280
|
|
|
254
281
|
export {
|
|
255
|
-
|
|
282
|
+
createCDPClientFromTransport,
|
|
256
283
|
createCDPClient
|
|
257
284
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/daemon/types.ts
|
|
2
|
+
var DAEMON_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
3
|
+
var DAEMON_CONNECT_TIMEOUT_MS = 500;
|
|
4
|
+
var DAEMON_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
5
|
+
var DAEMON_READY_TIMEOUT_MS = 3e3;
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
DAEMON_MAX_AGE_MS,
|
|
9
|
+
DAEMON_CONNECT_TIMEOUT_MS,
|
|
10
|
+
DAEMON_READY_TIMEOUT_MS
|
|
11
|
+
};
|