@narumitw/pi-chrome-devtools 0.52.3 → 0.53.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/README.md +62 -9
- package/dist/chunks/{browser-settings-menu-VWCNG4HB.js → browser-settings-menu-REIU7C3Q.js} +83 -7
- package/dist/chunks/browser-settings-menu-REIU7C3Q.js.map +7 -0
- package/dist/chunks/chunk-GTTYS5GT.js +384 -0
- package/dist/chunks/chunk-GTTYS5GT.js.map +7 -0
- package/dist/chunks/{chunk-RH6KESL3.js → chunk-SRT3UUIP.js} +473 -574
- package/dist/chunks/chunk-SRT3UUIP.js.map +7 -0
- package/dist/chunks/chunk-YJVYJ2L2.js +469 -0
- package/dist/chunks/chunk-YJVYJ2L2.js.map +7 -0
- package/dist/chunks/{menu-PLD3S3EO.js → menu-H5HMVGHI.js} +72 -39
- package/dist/chunks/menu-H5HMVGHI.js.map +7 -0
- package/dist/chunks/tools-6P7EUX37.js +964 -0
- package/dist/chunks/tools-6P7EUX37.js.map +7 -0
- package/dist/index.ts +166 -199
- package/dist/index.ts.map +4 -4
- package/package.json +4 -3
- package/src/browser-manager.ts +408 -169
- package/src/browser-settings-menu.ts +100 -5
- package/src/cdp-client.ts +347 -90
- package/src/chrome-devtools.ts +58 -11
- package/src/lazy-tools.ts +37 -4
- package/src/menu.ts +80 -39
- package/src/render.ts +12 -1
- package/src/runtime.ts +92 -0
- package/src/settings.ts +47 -10
- package/src/tool-names.ts +16 -1
- package/src/tool-selector.ts +85 -44
- package/src/tools.ts +91 -15
- package/src/webmcp/discovery.ts +235 -0
- package/src/webmcp/policy.ts +409 -0
- package/src/webmcp/protocol.ts +426 -0
- package/src/webmcp/tools.ts +190 -0
- package/dist/chunks/browser-settings-menu-VWCNG4HB.js.map +0 -7
- package/dist/chunks/chunk-RH6KESL3.js.map +0 -7
- package/dist/chunks/menu-PLD3S3EO.js.map +0 -7
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_ENDPOINT_WAIT_MS,
|
|
5
|
+
DEFAULT_TIMEOUT_MS,
|
|
6
|
+
devToolsEndpoint,
|
|
7
|
+
ensureDevToolsEndpoint,
|
|
8
|
+
fetchDevToolsJson,
|
|
9
|
+
formatPageListItem,
|
|
10
|
+
launchHint,
|
|
11
|
+
state,
|
|
12
|
+
withEndpointRetry
|
|
13
|
+
} from "./chunk-SRT3UUIP.js";
|
|
14
|
+
|
|
15
|
+
// src/cdp-client.ts
|
|
16
|
+
var MAX_BUFFERED_EVENTS_PER_METHOD = 32;
|
|
17
|
+
var MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;
|
|
18
|
+
var activePageIds = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
async function listPages(options = {}) {
|
|
20
|
+
const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;
|
|
21
|
+
await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);
|
|
22
|
+
return withEndpointRetry(
|
|
23
|
+
async () => {
|
|
24
|
+
const pages = await fetchDevToolsJson(
|
|
25
|
+
"/json/list",
|
|
26
|
+
{ signal: options.signal },
|
|
27
|
+
options.sessionOwner
|
|
28
|
+
);
|
|
29
|
+
return pages.filter((page) => page.type === "page" && page.webSocketDebuggerUrl);
|
|
30
|
+
},
|
|
31
|
+
waitMs,
|
|
32
|
+
options.signal
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
async function getPage(pageId, options = {}) {
|
|
36
|
+
const pages = await listPages(options);
|
|
37
|
+
return requirePage(pageId, pages);
|
|
38
|
+
}
|
|
39
|
+
async function resolvePage(pageId, options = {}) {
|
|
40
|
+
const pages = await listPages(options);
|
|
41
|
+
if (pageId) return requirePage(pageId, pages);
|
|
42
|
+
const page = resolveDefaultPage(pages, options.sessionOwner);
|
|
43
|
+
if (!page) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
[
|
|
46
|
+
`No Chrome pages found at ${devToolsEndpoint(options.sessionOwner)}.`,
|
|
47
|
+
"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.",
|
|
48
|
+
launchHint(options.sessionOwner)
|
|
49
|
+
].join("\n")
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return page;
|
|
53
|
+
}
|
|
54
|
+
async function resolvePageForNavigation(pageId, options = {}) {
|
|
55
|
+
const pages = await listPages(options);
|
|
56
|
+
if (pageId) return { created: false, page: requirePage(pageId, pages) };
|
|
57
|
+
const page = resolveDefaultPage(pages, options.sessionOwner);
|
|
58
|
+
if (page) return { created: false, page };
|
|
59
|
+
return { created: true, page: await createPage("about:blank", options) };
|
|
60
|
+
}
|
|
61
|
+
function resolveDefaultPage(pages, owner) {
|
|
62
|
+
const activePageId = owner ? activePageIds.get(owner) : state.activePageId;
|
|
63
|
+
if (!activePageId) return pages[0];
|
|
64
|
+
const activePage = pages.find((candidate) => candidate.id === activePageId);
|
|
65
|
+
if (activePage) return activePage;
|
|
66
|
+
setActivePageId(owner, void 0);
|
|
67
|
+
return pages[0];
|
|
68
|
+
}
|
|
69
|
+
function setActivePageId(owner, pageId) {
|
|
70
|
+
if (!owner) {
|
|
71
|
+
state.activePageId = pageId;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (pageId) activePageIds.set(owner, pageId);
|
|
75
|
+
else activePageIds.delete(owner);
|
|
76
|
+
}
|
|
77
|
+
function requirePage(pageId, pages) {
|
|
78
|
+
const page = pages.find((candidate) => candidate.id === pageId);
|
|
79
|
+
if (page) return page;
|
|
80
|
+
const availablePages = pages.map(formatPageListItem).join("\n");
|
|
81
|
+
throw new Error(
|
|
82
|
+
[
|
|
83
|
+
`Chrome DevTools page not found: ${pageId}.`,
|
|
84
|
+
availablePages ? `Available pages:
|
|
85
|
+
${availablePages}` : "No inspectable Chrome pages are currently available."
|
|
86
|
+
].join("\n")
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
async function createPage(url, options = {}) {
|
|
90
|
+
const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;
|
|
91
|
+
await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);
|
|
92
|
+
const page = await withEndpointRetry(
|
|
93
|
+
() => fetchDevToolsJson(
|
|
94
|
+
`/json/new?${encodeURIComponent(url)}`,
|
|
95
|
+
{ method: "PUT", signal: options.signal },
|
|
96
|
+
options.sessionOwner
|
|
97
|
+
),
|
|
98
|
+
waitMs,
|
|
99
|
+
options.signal
|
|
100
|
+
);
|
|
101
|
+
if (page.type !== "page" || !page.webSocketDebuggerUrl) {
|
|
102
|
+
throw new Error("Chrome DevTools created a target that is not an inspectable page.");
|
|
103
|
+
}
|
|
104
|
+
return page;
|
|
105
|
+
}
|
|
106
|
+
function formatPage(page) {
|
|
107
|
+
return {
|
|
108
|
+
id: page.id,
|
|
109
|
+
type: page.type,
|
|
110
|
+
title: page.title,
|
|
111
|
+
url: page.url
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function textResult(text, details) {
|
|
115
|
+
return {
|
|
116
|
+
content: [{ type: "text", text }],
|
|
117
|
+
details
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async function withCdp(page, callback, options = {}) {
|
|
121
|
+
if (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);
|
|
122
|
+
const client = await CdpClient.connect(page.webSocketDebuggerUrl, options);
|
|
123
|
+
try {
|
|
124
|
+
return await callback(client);
|
|
125
|
+
} finally {
|
|
126
|
+
client.close();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
var CdpClient = class _CdpClient {
|
|
130
|
+
#closed = false;
|
|
131
|
+
#eventBuffers = /* @__PURE__ */ new Map();
|
|
132
|
+
#eventWaiters = /* @__PURE__ */ new Set();
|
|
133
|
+
#nextId = 1;
|
|
134
|
+
#pending = /* @__PURE__ */ new Map();
|
|
135
|
+
#socket;
|
|
136
|
+
constructor(socket) {
|
|
137
|
+
this.#socket = socket;
|
|
138
|
+
socket.addEventListener("message", this.onMessage);
|
|
139
|
+
socket.addEventListener("close", this.onClose);
|
|
140
|
+
socket.addEventListener("error", this.onError);
|
|
141
|
+
}
|
|
142
|
+
static connect(url, options = {}) {
|
|
143
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
144
|
+
const WebSocketImplementation = options.webSocketConstructor ?? WebSocket;
|
|
145
|
+
options.signal?.throwIfAborted();
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
const socket = new WebSocketImplementation(url);
|
|
148
|
+
let settled = false;
|
|
149
|
+
const settle = (callback) => {
|
|
150
|
+
if (settled) return;
|
|
151
|
+
settled = true;
|
|
152
|
+
clearTimeout(timeout);
|
|
153
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
154
|
+
socket.removeEventListener("open", onOpen);
|
|
155
|
+
socket.removeEventListener("error", onConnectError);
|
|
156
|
+
callback();
|
|
157
|
+
};
|
|
158
|
+
const onOpen = () => settle(() => resolve(new _CdpClient(socket)));
|
|
159
|
+
const onConnectError = () => settle(() => {
|
|
160
|
+
socket.close();
|
|
161
|
+
reject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));
|
|
162
|
+
});
|
|
163
|
+
const onAbort = () => settle(() => {
|
|
164
|
+
socket.close();
|
|
165
|
+
reject(options.signal?.reason ?? abortError("Chrome DevTools connection aborted"));
|
|
166
|
+
});
|
|
167
|
+
const timeout = setTimeout(
|
|
168
|
+
() => settle(() => {
|
|
169
|
+
socket.close();
|
|
170
|
+
reject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));
|
|
171
|
+
}),
|
|
172
|
+
timeoutMs
|
|
173
|
+
);
|
|
174
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
175
|
+
socket.addEventListener("open", onOpen, { once: true });
|
|
176
|
+
socket.addEventListener("error", onConnectError, { once: true });
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
send(method, params = {}, options = {}) {
|
|
180
|
+
this.throwIfClosed();
|
|
181
|
+
options.signal?.throwIfAborted();
|
|
182
|
+
const id = this.#nextId;
|
|
183
|
+
this.#nextId += 1;
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
const onAbort = () => {
|
|
186
|
+
this.#pending.delete(id);
|
|
187
|
+
cleanup();
|
|
188
|
+
reject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));
|
|
189
|
+
};
|
|
190
|
+
const timeout = setTimeout(() => {
|
|
191
|
+
this.#pending.delete(id);
|
|
192
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
193
|
+
reject(new Error(`Timed out waiting for CDP response: ${method}`));
|
|
194
|
+
}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
195
|
+
const cleanup = () => {
|
|
196
|
+
clearTimeout(timeout);
|
|
197
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
198
|
+
};
|
|
199
|
+
this.#pending.set(id, {
|
|
200
|
+
cleanup,
|
|
201
|
+
reject,
|
|
202
|
+
resolve
|
|
203
|
+
});
|
|
204
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
205
|
+
try {
|
|
206
|
+
this.#socket.send(JSON.stringify({ id, method, params }));
|
|
207
|
+
} catch (error) {
|
|
208
|
+
this.#pending.delete(id);
|
|
209
|
+
cleanup();
|
|
210
|
+
reject(error);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
waitForEvent(method, predicate, options = {}) {
|
|
215
|
+
this.throwIfClosed();
|
|
216
|
+
options.signal?.throwIfAborted();
|
|
217
|
+
const buffered = this.#eventBuffers.get(method) ?? [];
|
|
218
|
+
for (const [index, params] of buffered.entries()) {
|
|
219
|
+
if (!predicate(params)) continue;
|
|
220
|
+
buffered.splice(index, 1);
|
|
221
|
+
if (buffered.length === 0) this.#eventBuffers.delete(method);
|
|
222
|
+
return Promise.resolve(params);
|
|
223
|
+
}
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const waiter = {};
|
|
226
|
+
const onAbort = () => {
|
|
227
|
+
this.#eventWaiters.delete(waiter);
|
|
228
|
+
cleanup();
|
|
229
|
+
reject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));
|
|
230
|
+
};
|
|
231
|
+
const timeout = setTimeout(() => {
|
|
232
|
+
this.#eventWaiters.delete(waiter);
|
|
233
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
234
|
+
reject(new Error(`Timed out waiting for CDP event: ${method}`));
|
|
235
|
+
}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
236
|
+
const cleanup = () => {
|
|
237
|
+
clearTimeout(timeout);
|
|
238
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
239
|
+
};
|
|
240
|
+
Object.assign(waiter, { cleanup, method, predicate, reject, resolve });
|
|
241
|
+
this.#eventWaiters.add(waiter);
|
|
242
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
close(reason = new Error("Chrome DevTools WebSocket closed")) {
|
|
246
|
+
if (this.#closed) return;
|
|
247
|
+
this.#closed = true;
|
|
248
|
+
this.#socket.removeEventListener("message", this.onMessage);
|
|
249
|
+
this.#socket.removeEventListener("close", this.onClose);
|
|
250
|
+
this.#socket.removeEventListener("error", this.onError);
|
|
251
|
+
this.rejectAll(reason);
|
|
252
|
+
this.#eventBuffers.clear();
|
|
253
|
+
try {
|
|
254
|
+
this.#socket.close();
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
onClose = () => {
|
|
259
|
+
this.close(new Error("Chrome DevTools WebSocket closed"));
|
|
260
|
+
};
|
|
261
|
+
onError = () => {
|
|
262
|
+
this.close(new Error("Chrome DevTools WebSocket error"));
|
|
263
|
+
};
|
|
264
|
+
onMessage = (event) => {
|
|
265
|
+
if (typeof event.data !== "string") {
|
|
266
|
+
this.close(new Error("Chrome DevTools WebSocket sent an unsupported binary message"));
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (event.data.length > MAX_CDP_MESSAGE_BYTES || Buffer.byteLength(event.data, "utf8") > MAX_CDP_MESSAGE_BYTES) {
|
|
270
|
+
this.close(new Error("Chrome DevTools WebSocket message exceeds the 8 MB limit"));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
let payload;
|
|
274
|
+
try {
|
|
275
|
+
payload = JSON.parse(event.data);
|
|
276
|
+
} catch {
|
|
277
|
+
this.close(new Error("Chrome DevTools WebSocket sent malformed JSON"));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (!isRecord(payload)) {
|
|
281
|
+
this.close(new Error("Chrome DevTools WebSocket sent a malformed message"));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (typeof payload.id === "number") {
|
|
285
|
+
this.handleResponse(payload);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (typeof payload.method !== "string") {
|
|
289
|
+
this.close(new Error("Chrome DevTools WebSocket sent a malformed event"));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this.handleEvent(payload);
|
|
293
|
+
};
|
|
294
|
+
handleResponse(response) {
|
|
295
|
+
const pending = this.#pending.get(response.id);
|
|
296
|
+
if (!pending) return;
|
|
297
|
+
this.#pending.delete(response.id);
|
|
298
|
+
pending.cleanup();
|
|
299
|
+
if (response.error) {
|
|
300
|
+
pending.reject(
|
|
301
|
+
new Error(
|
|
302
|
+
`CDP error ${response.error.code}: ${response.error.message}${response.error.data === void 0 ? "" : ` (${safeJson(response.error.data)})`}`
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
pending.resolve(response.result);
|
|
308
|
+
}
|
|
309
|
+
handleEvent(event) {
|
|
310
|
+
if (event.method === "Inspector.detached" || event.method === "Target.detachedFromTarget") {
|
|
311
|
+
this.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
for (const waiter of this.#eventWaiters) {
|
|
315
|
+
if (waiter.method !== event.method) continue;
|
|
316
|
+
let matched;
|
|
317
|
+
try {
|
|
318
|
+
matched = waiter.predicate(event.params);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
this.#eventWaiters.delete(waiter);
|
|
321
|
+
waiter.cleanup();
|
|
322
|
+
waiter.reject(error);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (!matched) continue;
|
|
326
|
+
this.#eventWaiters.delete(waiter);
|
|
327
|
+
waiter.cleanup();
|
|
328
|
+
waiter.resolve(event.params);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const buffer = this.#eventBuffers.get(event.method) ?? [];
|
|
332
|
+
buffer.push(event.params);
|
|
333
|
+
if (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {
|
|
334
|
+
this.close(
|
|
335
|
+
new Error(
|
|
336
|
+
`Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
this.#eventBuffers.set(event.method, buffer);
|
|
342
|
+
}
|
|
343
|
+
rejectAll(reason) {
|
|
344
|
+
for (const [id, pending] of this.#pending) {
|
|
345
|
+
this.#pending.delete(id);
|
|
346
|
+
pending.cleanup();
|
|
347
|
+
pending.reject(reason);
|
|
348
|
+
}
|
|
349
|
+
for (const waiter of this.#eventWaiters) {
|
|
350
|
+
this.#eventWaiters.delete(waiter);
|
|
351
|
+
waiter.cleanup();
|
|
352
|
+
waiter.reject(reason);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
throwIfClosed() {
|
|
356
|
+
if (this.#closed) throw new Error("Chrome DevTools WebSocket is closed");
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
function abortError(message) {
|
|
360
|
+
return new DOMException(message, "AbortError");
|
|
361
|
+
}
|
|
362
|
+
function isRecord(value) {
|
|
363
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
364
|
+
}
|
|
365
|
+
function safeJson(value) {
|
|
366
|
+
try {
|
|
367
|
+
return JSON.stringify(value);
|
|
368
|
+
} catch {
|
|
369
|
+
return String(value);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export {
|
|
374
|
+
listPages,
|
|
375
|
+
getPage,
|
|
376
|
+
resolvePage,
|
|
377
|
+
resolvePageForNavigation,
|
|
378
|
+
setActivePageId,
|
|
379
|
+
formatPage,
|
|
380
|
+
textResult,
|
|
381
|
+
withCdp,
|
|
382
|
+
CdpClient
|
|
383
|
+
};
|
|
384
|
+
//# sourceMappingURL=chunk-GTTYS5GT.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/cdp-client.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n\tdevToolsEndpoint,\n\tensureDevToolsEndpoint,\n\tfetchDevToolsJson,\n\tformatPageListItem,\n\tlaunchHint,\n\twithEndpointRetry,\n} from \"./browser-manager.js\";\nimport {\n\tDEFAULT_ENDPOINT_WAIT_MS,\n\tDEFAULT_TIMEOUT_MS,\n\ttype DevToolsPage,\n\tstate,\n} from \"./runtime.js\";\n\ninterface CdpResponse<T = unknown> {\n\terror?: { code: number; data?: unknown; message: string };\n\tid: number;\n\tresult?: T;\n}\n\ninterface CdpEvent {\n\tmethod: string;\n\tparams?: unknown;\n}\n\ninterface PendingRequest {\n\tcleanup: () => void;\n\treject: (reason: unknown) => void;\n\tresolve: (value: unknown) => void;\n}\n\ninterface EventWaiter<T = unknown> {\n\tcleanup: () => void;\n\tmethod: string;\n\tpredicate: (params: unknown) => params is T;\n\treject: (reason: unknown) => void;\n\tresolve: (params: T) => void;\n}\n\nexport type CdpWebSocketConstructor = new (url: string | URL) => WebSocket;\n\nexport interface CdpOperationOptions {\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface CdpConnectOptions extends CdpOperationOptions {\n\twebSocketConstructor?: CdpWebSocketConstructor;\n}\n\nconst MAX_BUFFERED_EVENTS_PER_METHOD = 32;\nconst MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;\nconst activePageIds = new WeakMap<object, string>();\n\ninterface PageOperationOptions {\n\tsessionOwner?: object;\n\tsignal?: AbortSignal;\n\twaitMs?: number;\n}\n\nexport async function listPages(options: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\treturn withEndpointRetry(\n\t\tasync () => {\n\t\t\tconst pages = await fetchDevToolsJson<DevToolsPage[]>(\n\t\t\t\t\"/json/list\",\n\t\t\t\t{ signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t);\n\t\t\treturn pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n\t\t},\n\t\twaitMs,\n\t\toptions.signal,\n\t);\n}\n\nexport async function getPage(pageId: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\n\treturn requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\n\tif (pageId) return requirePage(pageId, pages);\n\n\tconst page = resolveDefaultPage(pages, options.sessionOwner);\n\tif (!page) {\n\t\tthrow new Error(\n\t\t\t[\n\t\t\t\t`No Chrome pages found at ${devToolsEndpoint(options.sessionOwner)}.`,\n\t\t\t\t\"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.\",\n\t\t\t\tlaunchHint(options.sessionOwner),\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t}\n\n\treturn page;\n}\n\nexport async function resolvePageForNavigation(\n\tpageId?: string,\n\toptions: PageOperationOptions = {},\n) {\n\tconst pages = await listPages(options);\n\tif (pageId) return { created: false, page: requirePage(pageId, pages) };\n\n\tconst page = resolveDefaultPage(pages, options.sessionOwner);\n\tif (page) return { created: false, page };\n\n\treturn { created: true, page: await createPage(\"about:blank\", options) };\n}\n\nfunction resolveDefaultPage(pages: DevToolsPage[], owner?: object) {\n\tconst activePageId = owner ? activePageIds.get(owner) : state.activePageId;\n\tif (!activePageId) return pages[0];\n\n\tconst activePage = pages.find((candidate) => candidate.id === activePageId);\n\tif (activePage) return activePage;\n\n\tsetActivePageId(owner, undefined);\n\treturn pages[0];\n}\n\nexport function setActivePageId(owner: object | undefined, pageId: string | undefined) {\n\tif (!owner) {\n\t\tstate.activePageId = pageId;\n\t\treturn;\n\t}\n\tif (pageId) activePageIds.set(owner, pageId);\n\telse activePageIds.delete(owner);\n}\n\nfunction requirePage(pageId: string, pages: DevToolsPage[]) {\n\tconst page = pages.find((candidate) => candidate.id === pageId);\n\tif (page) return page;\n\n\tconst availablePages = pages.map(formatPageListItem).join(\"\\n\");\n\tthrow new Error(\n\t\t[\n\t\t\t`Chrome DevTools page not found: ${pageId}.`,\n\t\t\tavailablePages\n\t\t\t\t? `Available pages:\\n${availablePages}`\n\t\t\t\t: \"No inspectable Chrome pages are currently available.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nexport async function createPage(url: string, options: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\tconst page = await withEndpointRetry(\n\t\t() =>\n\t\t\tfetchDevToolsJson<DevToolsPage>(\n\t\t\t\t`/json/new?${encodeURIComponent(url)}`,\n\t\t\t\t{ method: \"PUT\", signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t),\n\t\twaitMs,\n\t\toptions.signal,\n\t);\n\tif (page.type !== \"page\" || !page.webSocketDebuggerUrl) {\n\t\tthrow new Error(\"Chrome DevTools created a target that is not an inspectable page.\");\n\t}\n\n\treturn page;\n}\n\nexport function formatPage(page: DevToolsPage) {\n\treturn {\n\t\tid: page.id,\n\t\ttype: page.type,\n\t\ttitle: page.title,\n\t\turl: page.url,\n\t};\n}\n\nexport function textResult<T>(text: string, details: T) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport async function withCdp<T>(\n\tpage: DevToolsPage,\n\tcallback: (client: CdpClient) => Promise<T>,\n\toptions: CdpConnectOptions = {},\n) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n\tconst client = await CdpClient.connect(page.webSocketDebuggerUrl, options);\n\ttry {\n\t\treturn await callback(client);\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nexport class CdpClient {\n\t#closed = false;\n\t#eventBuffers = new Map<string, unknown[]>();\n\t#eventWaiters = new Set<EventWaiter>();\n\t#nextId = 1;\n\t#pending = new Map<number, PendingRequest>();\n\treadonly #socket: WebSocket;\n\n\tprivate constructor(socket: WebSocket) {\n\t\tthis.#socket = socket;\n\t\tsocket.addEventListener(\"message\", this.onMessage);\n\t\tsocket.addEventListener(\"close\", this.onClose);\n\t\tsocket.addEventListener(\"error\", this.onError);\n\t}\n\n\tstatic connect(url: string, options: CdpConnectOptions = {}) {\n\t\tconst timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tconst WebSocketImplementation = options.webSocketConstructor ?? WebSocket;\n\t\toptions.signal?.throwIfAborted();\n\t\treturn new Promise<CdpClient>((resolve, reject) => {\n\t\t\tconst socket = new WebSocketImplementation(url);\n\t\t\tlet settled = false;\n\t\t\tconst settle = (callback: () => void) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tsocket.removeEventListener(\"open\", onOpen);\n\t\t\t\tsocket.removeEventListener(\"error\", onConnectError);\n\t\t\t\tcallback();\n\t\t\t};\n\t\t\tconst onOpen = () => settle(() => resolve(new CdpClient(socket)));\n\t\t\tconst onConnectError = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t});\n\t\t\tconst onAbort = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(options.signal?.reason ?? abortError(\"Chrome DevTools connection aborted\"));\n\t\t\t\t});\n\t\t\tconst timeout = setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tsettle(() => {\n\t\t\t\t\t\tsocket.close();\n\t\t\t\t\t\treject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t\t}),\n\t\t\t\ttimeoutMs,\n\t\t\t);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tsocket.addEventListener(\"open\", onOpen, { once: true });\n\t\t\tsocket.addEventListener(\"error\", onConnectError, { once: true });\n\t\t});\n\t}\n\n\tsend<T = unknown>(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> = {},\n\t\toptions: CdpOperationOptions = {},\n\t) {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst id = this.#nextId;\n\t\tthis.#nextId += 1;\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP response: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tthis.#pending.set(id, {\n\t\t\t\tcleanup,\n\t\t\t\treject,\n\t\t\t\tresolve: resolve as (value: unknown) => void,\n\t\t\t});\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\ttry {\n\t\t\t\tthis.#socket.send(JSON.stringify({ id, method, params }));\n\t\t\t} catch (error) {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t}\n\t\t});\n\t}\n\n\twaitForEvent<T>(\n\t\tmethod: string,\n\t\tpredicate: (params: unknown) => params is T,\n\t\toptions: CdpOperationOptions = {},\n\t): Promise<T> {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst buffered = this.#eventBuffers.get(method) ?? [];\n\t\tfor (const [index, params] of buffered.entries()) {\n\t\t\tif (!predicate(params)) continue;\n\t\t\tbuffered.splice(index, 1);\n\t\t\tif (buffered.length === 0) this.#eventBuffers.delete(method);\n\t\t\treturn Promise.resolve(params);\n\t\t}\n\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst waiter = {} as EventWaiter<T>;\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP event: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tObject.assign(waiter, { cleanup, method, predicate, reject, resolve });\n\t\t\tthis.#eventWaiters.add(waiter as EventWaiter);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t});\n\t}\n\n\tclose(reason: unknown = new Error(\"Chrome DevTools WebSocket closed\")) {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#socket.removeEventListener(\"message\", this.onMessage);\n\t\tthis.#socket.removeEventListener(\"close\", this.onClose);\n\t\tthis.#socket.removeEventListener(\"error\", this.onError);\n\t\tthis.rejectAll(reason);\n\t\tthis.#eventBuffers.clear();\n\t\ttry {\n\t\t\tthis.#socket.close();\n\t\t} catch {\n\t\t\t// The transport is already unusable; pending work has still been rejected.\n\t\t}\n\t}\n\n\tprivate readonly onClose = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket closed\"));\n\t};\n\n\tprivate readonly onError = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket error\"));\n\t};\n\n\tprivate readonly onMessage = (event: MessageEvent) => {\n\t\tif (typeof event.data !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent an unsupported binary message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tevent.data.length > MAX_CDP_MESSAGE_BYTES ||\n\t\t\tBuffer.byteLength(event.data, \"utf8\") > MAX_CDP_MESSAGE_BYTES\n\t\t) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket message exceeds the 8 MB limit\"));\n\t\t\treturn;\n\t\t}\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(event.data) as unknown;\n\t\t} catch {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent malformed JSON\"));\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecord(payload)) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.id === \"number\") {\n\t\t\tthis.handleResponse(payload as unknown as CdpResponse);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.method !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed event\"));\n\t\t\treturn;\n\t\t}\n\t\tthis.handleEvent(payload as unknown as CdpEvent);\n\t};\n\n\tprivate handleResponse(response: CdpResponse) {\n\t\tconst pending = this.#pending.get(response.id);\n\t\tif (!pending) return;\n\t\tthis.#pending.delete(response.id);\n\t\tpending.cleanup();\n\t\tif (response.error) {\n\t\t\tpending.reject(\n\t\t\t\tnew Error(\n\t\t\t\t\t`CDP error ${response.error.code}: ${response.error.message}${\n\t\t\t\t\t\tresponse.error.data === undefined ? \"\" : ` (${safeJson(response.error.data)})`\n\t\t\t\t\t}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tpending.resolve(response.result);\n\t}\n\n\tprivate handleEvent(event: CdpEvent) {\n\t\tif (event.method === \"Inspector.detached\" || event.method === \"Target.detachedFromTarget\") {\n\t\t\tthis.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));\n\t\t\treturn;\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tif (waiter.method !== event.method) continue;\n\t\t\tlet matched: boolean;\n\t\t\ttry {\n\t\t\t\tmatched = waiter.predicate(event.params);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\t\twaiter.cleanup();\n\t\t\t\twaiter.reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!matched) continue;\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.resolve(event.params);\n\t\t\treturn;\n\t\t}\n\t\tconst buffer = this.#eventBuffers.get(event.method) ?? [];\n\t\tbuffer.push(event.params);\n\t\tif (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {\n\t\t\tthis.close(\n\t\t\t\tnew Error(\n\t\t\t\t\t`Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.#eventBuffers.set(event.method, buffer);\n\t}\n\n\tprivate rejectAll(reason: unknown) {\n\t\tfor (const [id, pending] of this.#pending) {\n\t\t\tthis.#pending.delete(id);\n\t\t\tpending.cleanup();\n\t\t\tpending.reject(reason);\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.reject(reason);\n\t\t}\n\t}\n\n\tprivate throwIfClosed() {\n\t\tif (this.#closed) throw new Error(\"Chrome DevTools WebSocket is closed\");\n\t}\n}\n\nfunction abortError(message: string) {\n\treturn new DOMException(message, \"AbortError\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown) {\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|