@volter/browser-cdp 0.1.47 → 0.1.49
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/chromium-face.d.ts +24 -0
- package/dist/chromium-face.d.ts.map +1 -0
- package/dist/chromium-face.js +144 -0
- package/dist/chromium-face.js.map +1 -0
- package/dist/preview-browser-host.d.ts +42 -0
- package/dist/preview-browser-host.d.ts.map +1 -0
- package/dist/preview-browser-host.js +270 -0
- package/dist/preview-browser-host.js.map +1 -0
- package/dist/preview-cdp-endpoint.d.ts +84 -0
- package/dist/preview-cdp-endpoint.d.ts.map +1 -0
- package/dist/preview-cdp-endpoint.js +153 -0
- package/dist/preview-cdp-endpoint.js.map +1 -0
- package/dist/sandbox-surface.d.ts +2 -0
- package/dist/sandbox-surface.d.ts.map +1 -0
- package/dist/sandbox-surface.js +27 -0
- package/dist/sandbox-surface.js.map +1 -0
- package/dist/tab-chromium.d.ts +51 -0
- package/dist/tab-chromium.d.ts.map +1 -0
- package/dist/tab-chromium.js +113 -0
- package/dist/tab-chromium.js.map +1 -0
- package/package.json +6 -2
- package/src/chromium-face.ts +0 -130
- package/src/preview-browser-host.ts +0 -273
- package/src/preview-cdp-endpoint.ts +0 -206
- package/src/sandbox-surface.ts +0 -27
- package/src/tab-chromium.ts +0 -143
- package/tsconfig.build.json +0 -5
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProtocolPeer } from "@volter/almostcdp/core";
|
|
2
|
+
import type { BrowserProgramRunner } from "@volter/browser-runtime/browser-process-host.js";
|
|
3
|
+
import type { BrowserFileSystem } from "@volter/browser-runtime/browser-filesystem.js";
|
|
4
|
+
/** The program names a placed executable resolves to (a path resolves to its basename). */
|
|
5
|
+
export declare const CHROMIUM_FACE_PROGRAMS: readonly ["chrome", "chrome-headless-shell"];
|
|
6
|
+
/**
|
|
7
|
+
* Chromium as Playwright launches it: `--remote-debugging-pipe`, CDP as
|
|
8
|
+
* NUL-terminated JSON read from fd 3 and written to fd 4. The face owns no
|
|
9
|
+
* protocol behaviour of its own; each launch is one browser-level client of
|
|
10
|
+
* the tab's CDP endpoint, and `Browser.close` ends the process as it ends
|
|
11
|
+
* Chromium's.
|
|
12
|
+
*/
|
|
13
|
+
export declare function chromiumFaceRunner(attachClient: (peer: ProtocolPeer) => void): BrowserProgramRunner;
|
|
14
|
+
/** The Chromium revisions pinned by each `playwright-core` installed under the given roots. */
|
|
15
|
+
export declare function playwrightChromiumRevisions(filesystem: BrowserFileSystem, roots: readonly string[]): Promise<string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Places the face where Playwright's registry looks for each revision, marked
|
|
18
|
+
* installed and host-validated as the registry marks what it downloads, so
|
|
19
|
+
* `playwright install` finds it present and a launch resolves the path to the
|
|
20
|
+
* registered program: the file is the engine's registered-program stub, which
|
|
21
|
+
* it relays to the host rather than running.
|
|
22
|
+
*/
|
|
23
|
+
export declare function placeChromiumFace(filesystem: BrowserFileSystem, cacheDirectory: string, revisions: readonly string[]): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=chromium-face.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chromium-face.d.ts","sourceRoot":"","sources":["../src/chromium-face.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAQvF,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,8CAA+C,CAAC;AAInF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,oBAAoB,CAqDnG;AAUD,+FAA+F;AAC/F,wBAAsB,2BAA2B,CAAC,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa5H;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB1I"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/** Where Playwright's registry keeps each Chromium it launches, under its cache directory. */
|
|
2
|
+
const PLACEMENTS = [
|
|
3
|
+
{ browser: "chromium", directory: "chromium", executable: "chrome-linux64/chrome" },
|
|
4
|
+
{ browser: "chromium-headless-shell", directory: "chromium_headless_shell", executable: "chrome-headless-shell-linux64/chrome-headless-shell" },
|
|
5
|
+
];
|
|
6
|
+
/** The program names a placed executable resolves to (a path resolves to its basename). */
|
|
7
|
+
export const CHROMIUM_FACE_PROGRAMS = ["chrome", "chrome-headless-shell"];
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
/**
|
|
10
|
+
* Chromium as Playwright launches it: `--remote-debugging-pipe`, CDP as
|
|
11
|
+
* NUL-terminated JSON read from fd 3 and written to fd 4. The face owns no
|
|
12
|
+
* protocol behaviour of its own; each launch is one browser-level client of
|
|
13
|
+
* the tab's CDP endpoint, and `Browser.close` ends the process as it ends
|
|
14
|
+
* Chromium's.
|
|
15
|
+
*/
|
|
16
|
+
export function chromiumFaceRunner(attachClient) {
|
|
17
|
+
return async (argv, options) => {
|
|
18
|
+
const name = argv[0]?.slice(argv[0].lastIndexOf("/") + 1) ?? "chrome";
|
|
19
|
+
if (!argv.includes("--remote-debugging-pipe")) {
|
|
20
|
+
return { stdout: "", stderr: `${name}: the tab's Chromium is driven over --remote-debugging-pipe only\n`, exitCode: 1 };
|
|
21
|
+
}
|
|
22
|
+
const commands = options.descriptors?.[3];
|
|
23
|
+
const replies = options.descriptors?.[4];
|
|
24
|
+
if (!commands || !replies) {
|
|
25
|
+
return { stdout: "", stderr: `${name}: --remote-debugging-pipe needs pipes on fds 3 and 4\n`, exitCode: 1 };
|
|
26
|
+
}
|
|
27
|
+
const messageListeners = [];
|
|
28
|
+
const closeListeners = [];
|
|
29
|
+
let open = true;
|
|
30
|
+
let finished;
|
|
31
|
+
const done = new Promise((resolve) => { finished = resolve; });
|
|
32
|
+
const end = () => {
|
|
33
|
+
if (!open)
|
|
34
|
+
return;
|
|
35
|
+
open = false;
|
|
36
|
+
replies.end();
|
|
37
|
+
for (const listener of closeListeners)
|
|
38
|
+
listener();
|
|
39
|
+
finished();
|
|
40
|
+
};
|
|
41
|
+
const peer = {
|
|
42
|
+
get readyState() { return open ? 1 : 3; },
|
|
43
|
+
send: (data) => { if (open)
|
|
44
|
+
replies.write(encoder.encode(`${data}\0`)); },
|
|
45
|
+
close: () => end(),
|
|
46
|
+
on: ((event, listener) => {
|
|
47
|
+
if (event === "message")
|
|
48
|
+
messageListeners.push(listener);
|
|
49
|
+
else
|
|
50
|
+
closeListeners.push(listener);
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
options.signal?.addEventListener("abort", end, { once: true });
|
|
54
|
+
attachClient(peer);
|
|
55
|
+
void (async () => {
|
|
56
|
+
const decoder = new TextDecoder();
|
|
57
|
+
let buffered = "";
|
|
58
|
+
for await (const chunk of commands.input) {
|
|
59
|
+
buffered += decoder.decode(chunk, { stream: true });
|
|
60
|
+
for (let boundary = buffered.indexOf("\0"); boundary >= 0; boundary = buffered.indexOf("\0")) {
|
|
61
|
+
const message = buffered.slice(0, boundary);
|
|
62
|
+
buffered = buffered.slice(boundary + 1);
|
|
63
|
+
const closing = browserClose(message);
|
|
64
|
+
if (closing !== undefined) {
|
|
65
|
+
peer.send(JSON.stringify({ id: closing, result: {} }));
|
|
66
|
+
end();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
for (const listener of messageListeners)
|
|
70
|
+
listener(message);
|
|
71
|
+
if (!open)
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
end();
|
|
76
|
+
})().catch(end);
|
|
77
|
+
await done;
|
|
78
|
+
return { stdout: "", stderr: "", exitCode: 0 };
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** The id of a browser-level `Browser.close`, which ends the process rather than reaching the endpoint. */
|
|
82
|
+
function browserClose(message) {
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(message);
|
|
85
|
+
return parsed.method === "Browser.close" && parsed.sessionId === undefined && typeof parsed.id === "number" ? parsed.id : undefined;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** The Chromium revisions pinned by each `playwright-core` installed under the given roots. */
|
|
92
|
+
export async function playwrightChromiumRevisions(filesystem, roots) {
|
|
93
|
+
const revisions = new Set();
|
|
94
|
+
for (const root of roots) {
|
|
95
|
+
const path = `${root.replace(/\/$/u, "")}/node_modules/playwright-core/browsers.json`;
|
|
96
|
+
if (!filesystem.existsSync(path))
|
|
97
|
+
continue;
|
|
98
|
+
try {
|
|
99
|
+
const pinned = JSON.parse(await filesystem.readFile(path, "utf8"));
|
|
100
|
+
for (const entry of pinned.browsers ?? []) {
|
|
101
|
+
if ((entry.name === "chromium" || entry.name === "chromium-headless-shell") && typeof entry.revision === "string")
|
|
102
|
+
revisions.add(entry.revision);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch { /* A browsers.json that does not parse pins nothing. */ }
|
|
106
|
+
}
|
|
107
|
+
return [...revisions];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Places the face where Playwright's registry looks for each revision, marked
|
|
111
|
+
* installed and host-validated as the registry marks what it downloads, so
|
|
112
|
+
* `playwright install` finds it present and a launch resolves the path to the
|
|
113
|
+
* registered program: the file is the engine's registered-program stub, which
|
|
114
|
+
* it relays to the host rather than running.
|
|
115
|
+
*/
|
|
116
|
+
export async function placeChromiumFace(filesystem, cacheDirectory, revisions) {
|
|
117
|
+
for (const revision of revisions) {
|
|
118
|
+
for (const placement of PLACEMENTS) {
|
|
119
|
+
const root = `${cacheDirectory}/${placement.directory}-${revision}`;
|
|
120
|
+
const executable = `${root}/${placement.executable}`;
|
|
121
|
+
filesystem.mkdirSync(executable.slice(0, executable.lastIndexOf("/")), { recursive: true });
|
|
122
|
+
// The registered-program stub the engine relays to the host, which maps
|
|
123
|
+
// the pathname to the face by its basename.
|
|
124
|
+
const name = placement.executable.slice(placement.executable.lastIndexOf("/") + 1);
|
|
125
|
+
const stub = `#!/bin/sh\n# ${name}: runtime-registered program\n`;
|
|
126
|
+
let current;
|
|
127
|
+
try {
|
|
128
|
+
current = filesystem.existsSync(executable) ? await filesystem.readFile(executable, "utf8") : undefined;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
current = undefined;
|
|
132
|
+
}
|
|
133
|
+
if (current !== stub) {
|
|
134
|
+
filesystem.writeFileSync(executable, stub);
|
|
135
|
+
filesystem.chmodSync?.(executable, 0o755);
|
|
136
|
+
}
|
|
137
|
+
for (const marker of ["INSTALLATION_COMPLETE", "DEPENDENCIES_VALIDATED"]) {
|
|
138
|
+
if (!filesystem.existsSync(`${root}/${marker}`))
|
|
139
|
+
filesystem.writeFileSync(`${root}/${marker}`, "");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=chromium-face.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chromium-face.js","sourceRoot":"","sources":["../src/chromium-face.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { DispatcherOptions, ProtocolPeer } from "@volter/almostcdp/core";
|
|
2
|
+
import { type BrowserSandboxBridgeOptions } from "@volter/browser-runtime/browser-sandbox-bridge.js";
|
|
3
|
+
type BrowserContextHost = NonNullable<DispatcherOptions["contextHost"]>;
|
|
4
|
+
type BrowserPageHost = NonNullable<DispatcherOptions["pageHost"]>;
|
|
5
|
+
type SharedBridgeOptions = Omit<BrowserSandboxBridgeOptions, "preview" | "origin" | "nonce" | "port" | "onReady" | "onPreviewLoad">;
|
|
6
|
+
export interface PreviewBrowserHostOptions {
|
|
7
|
+
/** Where page frames are mounted; the embedding decides how they are shown. */
|
|
8
|
+
mount: HTMLElement;
|
|
9
|
+
/** The deployment's sandbox origin: the default context's pages live on it. */
|
|
10
|
+
sandboxOrigin: string;
|
|
11
|
+
/** The sandbox bootstrap document every page frame loads. */
|
|
12
|
+
sandboxPath?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The origin a context's label is served at, where the deployment's sandbox
|
|
15
|
+
* has its own zone of hosts. By default the label is a subdomain of the
|
|
16
|
+
* sandbox host, which a loopback name (`c-1.localhost`) or a zone apex serves.
|
|
17
|
+
*/
|
|
18
|
+
contextOrigin?(label: string): string;
|
|
19
|
+
bridge: SharedBridgeOptions;
|
|
20
|
+
/** Registers a created page's surface with the endpoint; resolves once the endpoint lists it. */
|
|
21
|
+
attachSurface(peer: ProtocolPeer, id: string, signal: AbortSignal): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export interface PreviewBrowserHost {
|
|
24
|
+
readonly contextHost: BrowserContextHost;
|
|
25
|
+
readonly pageHost: BrowserPageHost;
|
|
26
|
+
dispose(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Browser contexts and pages for the tab's CDP endpoint. A context is its own
|
|
30
|
+
* origin, a sibling of the sandbox origin, so its storage and cookies are the
|
|
31
|
+
* browser's own partition; its pages are sandbox frames on that origin, each
|
|
32
|
+
* lent to the endpoint like the preview. A closed context's origin is emptied
|
|
33
|
+
* and given to the next context, keeping its service worker: a fresh origin
|
|
34
|
+
* per context registered a worker per context, and a browser with a debugger
|
|
35
|
+
* attached keeps every one of them running (a suite run reached about 985
|
|
36
|
+
* renderers in ten minutes). Every context shares the tab's container: the
|
|
37
|
+
* servers a page reaches are the project's, as they are for a real browser's
|
|
38
|
+
* contexts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createPreviewBrowserHost(options: PreviewBrowserHostOptions): PreviewBrowserHost;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=preview-browser-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-browser-host.d.ts","sourceRoot":"","sources":["../src/preview-browser-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,mDAAmD,CAAC;AAI3H,KAAK,kBAAkB,GAAG,WAAW,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC;AACxE,KAAK,eAAe,GAAG,WAAW,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;AAClE,KAAK,mBAAmB,GAAG,IAAI,CAAC,2BAA2B,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,eAAe,CAAC,CAAC;AAEpI,MAAM,WAAW,yBAAyB;IACxC,+EAA+E;IAC/E,KAAK,EAAE,WAAW,CAAC;IACnB,+EAA+E;IAC/E,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,aAAa,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,iGAAiG;IACjG,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CAoM/F"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { BrowserSandboxBridge } from "@volter/browser-runtime/browser-sandbox-bridge.js";
|
|
2
|
+
import { SANDBOX_CHANNEL } from "@volter/browser-runtime/sandbox-protocol.js";
|
|
3
|
+
import { MessagePortTransport } from "@volter/almostcdp/message-port";
|
|
4
|
+
const CLEAR_TIMEOUT_MS = 15_000;
|
|
5
|
+
/** The page's record of the context origins it made, in its own storage. */
|
|
6
|
+
const ORIGINS_RECORD = "browser-substrate.context-origins";
|
|
7
|
+
/** A context origin in use is held under this lock by the tab using it. */
|
|
8
|
+
const ORIGIN_LOCK = "browser-substrate.context-origin:";
|
|
9
|
+
/** Emptied origins kept for the next contexts; past this, one is emptied for good. */
|
|
10
|
+
const SPARE_ORIGINS = 4;
|
|
11
|
+
/**
|
|
12
|
+
* Browser contexts and pages for the tab's CDP endpoint. A context is its own
|
|
13
|
+
* origin, a sibling of the sandbox origin, so its storage and cookies are the
|
|
14
|
+
* browser's own partition; its pages are sandbox frames on that origin, each
|
|
15
|
+
* lent to the endpoint like the preview. A closed context's origin is emptied
|
|
16
|
+
* and given to the next context, keeping its service worker: a fresh origin
|
|
17
|
+
* per context registered a worker per context, and a browser with a debugger
|
|
18
|
+
* attached keeps every one of them running (a suite run reached about 985
|
|
19
|
+
* renderers in ten minutes). Every context shares the tab's container: the
|
|
20
|
+
* servers a page reaches are the project's, as they are for a real browser's
|
|
21
|
+
* contexts.
|
|
22
|
+
*/
|
|
23
|
+
export function createPreviewBrowserHost(options) {
|
|
24
|
+
const sandboxPath = options.sandboxPath ?? "/sandbox.html";
|
|
25
|
+
const contexts = new Map();
|
|
26
|
+
/** Closed contexts' origins, each usable once its emptying has succeeded. */
|
|
27
|
+
const emptied = [];
|
|
28
|
+
const held = new Map();
|
|
29
|
+
// A tab that ends before its contexts are closed leaves their origins, each
|
|
30
|
+
// with its worker registered and its storage, and no page knew them again
|
|
31
|
+
// (a morning's work left eight). The page records every origin it makes and
|
|
32
|
+
// holds a lock on each while it lives: a recorded origin whose lock is free
|
|
33
|
+
// belongs to no tab, and is taken for the next context or emptied for good.
|
|
34
|
+
const recorded = () => {
|
|
35
|
+
try {
|
|
36
|
+
const value = JSON.parse(localStorage.getItem(ORIGINS_RECORD) ?? "[]");
|
|
37
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const record = (origins) => {
|
|
44
|
+
try {
|
|
45
|
+
localStorage.setItem(ORIGINS_RECORD, JSON.stringify([...new Set(origins)]));
|
|
46
|
+
}
|
|
47
|
+
catch { /* storage refused: the origin is still usable */ }
|
|
48
|
+
};
|
|
49
|
+
/** Takes an origin's lock, or with `ifFree` only if no tab holds it; resolves whether it is held. */
|
|
50
|
+
const hold = (origin, ifFree) => new Promise((acquired) => {
|
|
51
|
+
if (!("locks" in navigator)) {
|
|
52
|
+
acquired(!ifFree);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
void navigator.locks.request(`${ORIGIN_LOCK}${origin}`, { ifAvailable: ifFree }, (lock) => {
|
|
56
|
+
if (!lock) {
|
|
57
|
+
acquired(false);
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
acquired(true);
|
|
61
|
+
return new Promise((release) => held.set(origin, release));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
/** Empties an origin for good: its worker too. It leaves the record once that succeeded. */
|
|
65
|
+
const retire = (origin) => clearOrigin(origin).then(() => { record(recorded().filter((item) => item !== origin)); }, () => undefined).finally(() => { held.get(origin)?.(); held.delete(origin); });
|
|
66
|
+
/** A closed context's origin, emptied for the next context, or for good past the spares. */
|
|
67
|
+
const release = (origin) => {
|
|
68
|
+
if (emptied.length >= SPARE_ORIGINS) {
|
|
69
|
+
void retire(origin);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
emptied.push({ origin, ready: clearOrigin(origin, "reuse").then(() => true, () => false) });
|
|
73
|
+
};
|
|
74
|
+
let adopting = Promise.resolve();
|
|
75
|
+
for (const origin of recorded()) {
|
|
76
|
+
// One at a time: each is a frame of its origin loaded to empty it.
|
|
77
|
+
adopting = adopting.then(async () => { if (await hold(origin, true))
|
|
78
|
+
release(origin); });
|
|
79
|
+
}
|
|
80
|
+
const pages = new Map();
|
|
81
|
+
const contextOrigin = () => {
|
|
82
|
+
const label = `c-${[...crypto.getRandomValues(new Uint8Array(8))].map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
83
|
+
if (options.contextOrigin)
|
|
84
|
+
return new URL(options.contextOrigin(label)).origin;
|
|
85
|
+
const base = new URL(options.sandboxOrigin);
|
|
86
|
+
if (/^[0-9.]+$/u.test(base.hostname) || base.hostname.startsWith("[")) {
|
|
87
|
+
throw new Error(`Isolated browser contexts need a sandbox host name; ${base.hostname} is an address.`);
|
|
88
|
+
}
|
|
89
|
+
// workers.dev serves one level of names: a context host under the
|
|
90
|
+
// sandbox's own name does not exist there.
|
|
91
|
+
if (base.hostname.endsWith(".workers.dev")) {
|
|
92
|
+
throw new Error(`Isolated browser contexts need the sandbox on a zone of its own; ${base.hostname} is a workers.dev host.`);
|
|
93
|
+
}
|
|
94
|
+
return `${base.protocol}//${label}.${base.host}`;
|
|
95
|
+
};
|
|
96
|
+
const frameFor = (origin, query) => {
|
|
97
|
+
const frame = document.createElement("iframe");
|
|
98
|
+
frame.style.cssText = "border:0;width:1280px;height:720px;display:block";
|
|
99
|
+
const url = new URL(sandboxPath, origin);
|
|
100
|
+
for (const [key, value] of Object.entries(query))
|
|
101
|
+
url.searchParams.set(key, value);
|
|
102
|
+
frame.src = url.href;
|
|
103
|
+
options.mount.append(frame);
|
|
104
|
+
return frame;
|
|
105
|
+
};
|
|
106
|
+
const closePage = async (id) => {
|
|
107
|
+
const page = pages.get(id);
|
|
108
|
+
if (!page)
|
|
109
|
+
return;
|
|
110
|
+
pages.delete(id);
|
|
111
|
+
page.bridge.dispose();
|
|
112
|
+
page.frame.remove();
|
|
113
|
+
};
|
|
114
|
+
/** Empties an origin's storage from a frame of that origin, then removes the frame. */
|
|
115
|
+
const clearOrigin = async (origin, clear = "1") => {
|
|
116
|
+
const nonce = crypto.randomUUID();
|
|
117
|
+
const frame = frameFor(origin, { parentOrigin: location.origin, nonce, clear });
|
|
118
|
+
try {
|
|
119
|
+
await new Promise((resolve, reject) => {
|
|
120
|
+
const timer = setTimeout(() => { cleanup(); reject(new Error(`Clearing ${origin} timed out.`)); }, CLEAR_TIMEOUT_MS);
|
|
121
|
+
const receive = (event) => {
|
|
122
|
+
if (event.origin !== origin || event.source !== frame.contentWindow)
|
|
123
|
+
return;
|
|
124
|
+
const data = event.data;
|
|
125
|
+
if (data?.channel !== SANDBOX_CHANNEL || data.nonce !== nonce)
|
|
126
|
+
return;
|
|
127
|
+
if (data.type === "cleared") {
|
|
128
|
+
cleanup();
|
|
129
|
+
resolve();
|
|
130
|
+
}
|
|
131
|
+
else if (data.type === "error") {
|
|
132
|
+
cleanup();
|
|
133
|
+
reject(new Error(data.payload?.message ?? `Clearing ${origin} failed.`));
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const cleanup = () => { clearTimeout(timer); window.removeEventListener("message", receive); };
|
|
137
|
+
window.addEventListener("message", receive);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
frame.remove();
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const contextHost = {
|
|
145
|
+
async createContext(context, signal) {
|
|
146
|
+
if (context.proxyServer !== undefined || context.proxyBypassList !== undefined) {
|
|
147
|
+
throw new Error("A context's network is the tab's; a per-context proxy is unavailable.");
|
|
148
|
+
}
|
|
149
|
+
if (context.originsWithUniversalNetworkAccess?.length) {
|
|
150
|
+
throw new Error("Universal network access for named origins is unavailable in the tab.");
|
|
151
|
+
}
|
|
152
|
+
signal.throwIfAborted();
|
|
153
|
+
let origin;
|
|
154
|
+
while (!origin && emptied.length > 0) {
|
|
155
|
+
const candidate = emptied.shift();
|
|
156
|
+
if (await candidate.ready)
|
|
157
|
+
origin = candidate.origin;
|
|
158
|
+
// Not emptied: it stays recorded, and a later page tries again.
|
|
159
|
+
else {
|
|
160
|
+
held.get(candidate.origin)?.();
|
|
161
|
+
held.delete(candidate.origin);
|
|
162
|
+
}
|
|
163
|
+
signal.throwIfAborted();
|
|
164
|
+
}
|
|
165
|
+
if (!origin) {
|
|
166
|
+
origin = contextOrigin();
|
|
167
|
+
await hold(origin, false);
|
|
168
|
+
record([...recorded(), origin]);
|
|
169
|
+
}
|
|
170
|
+
contexts.set(context.id, { origin });
|
|
171
|
+
},
|
|
172
|
+
async disposeContext(id) {
|
|
173
|
+
const context = contexts.get(id);
|
|
174
|
+
if (!context)
|
|
175
|
+
return;
|
|
176
|
+
await Promise.all([...pages].filter(([, page]) => page.contextId === id).map(([pageId]) => closePage(pageId)));
|
|
177
|
+
contexts.delete(id);
|
|
178
|
+
// The context is closed once its pages are, so emptying its storage
|
|
179
|
+
// (a frame of the origin loaded to do it) goes on after the answer, as
|
|
180
|
+
// Chromium's closing does not wait on disk: awaited, it held
|
|
181
|
+
// Playwright's context teardown past a test's timeout. The next context
|
|
182
|
+
// waits for it instead; an origin that could not be emptied is never
|
|
183
|
+
// given out again.
|
|
184
|
+
release(context.origin);
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
const pageHost = {
|
|
188
|
+
async createPage(page, signal) {
|
|
189
|
+
const context = page.browserContextId === undefined ? undefined : contexts.get(page.browserContextId);
|
|
190
|
+
if (page.browserContextId !== undefined && !context)
|
|
191
|
+
throw new Error("No browser context with given id");
|
|
192
|
+
const origin = context?.origin ?? new URL(options.sandboxOrigin).origin;
|
|
193
|
+
const nonce = crypto.randomUUID();
|
|
194
|
+
// A page opens blank, is attached, and is then taken to the guest
|
|
195
|
+
// server it names under that port's prefix, the way a client's own
|
|
196
|
+
// first navigation takes it there, as Chromium's page starts blank and
|
|
197
|
+
// then loads its URL. Opened on the guest's port and navigated before
|
|
198
|
+
// attaching, a page never attached (a window.open's popup,
|
|
199
|
+
// Target.createTarget with a URL): creation hung.
|
|
200
|
+
const opening = guestAddress(page.url);
|
|
201
|
+
const port = 0;
|
|
202
|
+
const frame = frameFor(origin, { parentOrigin: location.origin, nonce, port: String(port) });
|
|
203
|
+
const bridge = new BrowserSandboxBridge({ ...options.bridge, preview: frame, origin, nonce, port });
|
|
204
|
+
pages.set(page.id, { frame, bridge, ...(page.browserContextId !== undefined ? { contextId: page.browserContextId } : {}) });
|
|
205
|
+
const abort = () => { void closePage(page.id); };
|
|
206
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
207
|
+
try {
|
|
208
|
+
// The surface registers under the target id before creation resolves.
|
|
209
|
+
const channel = await bridge.connectProtocol(page.id);
|
|
210
|
+
const transport = new MessagePortTransport(channel.port);
|
|
211
|
+
void channel.closed.then((reason) => transport.close(1001, reason));
|
|
212
|
+
// A page is handed over once its first document has loaded, as
|
|
213
|
+
// Chromium's is committed before `Target.createTarget` answers: a
|
|
214
|
+
// client's first navigation otherwise interrupts the frame's own.
|
|
215
|
+
await bridge.initialPreviewReady;
|
|
216
|
+
signal.throwIfAborted();
|
|
217
|
+
await options.attachSurface(transport, page.id, signal);
|
|
218
|
+
// Attached first, then taken to its URL: a navigation while the
|
|
219
|
+
// surface attached kept it from ever attaching.
|
|
220
|
+
if (opening)
|
|
221
|
+
await bridge.navigate(`${origin}/__virtual__/${opening.port}${opening.path}`);
|
|
222
|
+
}
|
|
223
|
+
catch (cause) {
|
|
224
|
+
await closePage(page.id);
|
|
225
|
+
throw cause;
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
signal.removeEventListener("abort", abort);
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
closePage,
|
|
232
|
+
};
|
|
233
|
+
return {
|
|
234
|
+
contextHost,
|
|
235
|
+
pageHost,
|
|
236
|
+
async dispose() {
|
|
237
|
+
await Promise.allSettled([...pages.keys()].map(closePage));
|
|
238
|
+
const origins = [...contexts.values()].map((context) => context.origin);
|
|
239
|
+
contexts.clear();
|
|
240
|
+
await adopting;
|
|
241
|
+
for (const entry of emptied.splice(0))
|
|
242
|
+
if (await entry.ready)
|
|
243
|
+
origins.push(entry.origin);
|
|
244
|
+
await Promise.allSettled(origins.map(retire));
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* The guest server a page is opened on: `about:blank` opens the default port,
|
|
250
|
+
* a loopback URL opens its own port and path. Anything else is not served in
|
|
251
|
+
* the tab.
|
|
252
|
+
*/
|
|
253
|
+
function guestAddress(url) {
|
|
254
|
+
if (url === "" || url === "about:blank")
|
|
255
|
+
return undefined;
|
|
256
|
+
let parsed;
|
|
257
|
+
try {
|
|
258
|
+
parsed = new URL(url);
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
throw new Error(`Invalid page URL: ${url}`);
|
|
262
|
+
}
|
|
263
|
+
const loopback = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]";
|
|
264
|
+
if ((parsed.protocol !== "http:" && parsed.protocol !== "https:") || !loopback) {
|
|
265
|
+
throw new Error(`A page opens on a guest server of the tab; ${url} is not one.`);
|
|
266
|
+
}
|
|
267
|
+
const port = Number(parsed.port || (parsed.protocol === "https:" ? 443 : 80));
|
|
268
|
+
return { port, path: `${parsed.pathname}${parsed.search}${parsed.hash}` };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=preview-browser-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-browser-host.js","sourceRoot":"","sources":["../src/preview-browser-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type ByteSocket } from "@volter/almostcdp/socket";
|
|
2
|
+
import type { ProtocolPeer } from "@volter/almostcdp/core";
|
|
3
|
+
import type { BrowserSandboxBridge } from "@volter/browser-runtime/browser-sandbox-bridge.js";
|
|
4
|
+
import type { BrowserServerBridge } from "@volter/browser-runtime/browser-http.js";
|
|
5
|
+
import type { BrowserVirtualWebSocketRegistry } from "@volter/browser-runtime/browser-virtual-websocket.js";
|
|
6
|
+
import { type PreviewBrowserHostOptions } from "./preview-browser-host.js";
|
|
7
|
+
/** A loopback listener of the tab: WALI's `listenTcp`, a Node container's `listenNet`. */
|
|
8
|
+
export type PreviewCdpListener = (port: number, accept: (socket: ByteSocket) => void) => () => void;
|
|
9
|
+
export interface PreviewCdpPublication {
|
|
10
|
+
readonly port: number;
|
|
11
|
+
/** What a client inside the tab passes to `connectOverCDP`. */
|
|
12
|
+
readonly url: string;
|
|
13
|
+
/** A browser-level client over a transport the host decodes, such as a launch pipe. */
|
|
14
|
+
attachClient(peer: ProtocolPeer): void;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The preview as a Chrome DevTools Protocol endpoint on a loopback port of the
|
|
19
|
+
* tab. AlmostCDP serves discovery and the DevTools WebSockets on each accepted
|
|
20
|
+
* connection; the preview's surface is lent through the authenticated sandbox
|
|
21
|
+
* bridge and lent again whenever the sandbox document is replaced, which a
|
|
22
|
+
* client sees as its page target closing and a new one appearing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function publishPreviewCdp(options: {
|
|
25
|
+
/**
|
|
26
|
+
* The preview's bridge, which lends the preview as a page target. Without
|
|
27
|
+
* one the endpoint still serves contexts and pages a client creates, which
|
|
28
|
+
* is all a launched browser needs.
|
|
29
|
+
*/
|
|
30
|
+
bridge?: BrowserSandboxBridge;
|
|
31
|
+
port: number;
|
|
32
|
+
listen: PreviewCdpListener;
|
|
33
|
+
targetId?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Browser contexts and pages beyond the preview: `Target.createBrowserContext`
|
|
36
|
+
* and `Target.createTarget` open sandbox frames here. Without it they refuse.
|
|
37
|
+
*/
|
|
38
|
+
browser?: Omit<PreviewBrowserHostOptions, "attachSurface">;
|
|
39
|
+
/**
|
|
40
|
+
* The same endpoint as a server in the tab's port table, so a page of the
|
|
41
|
+
* tab reaches it and a live tunnel of that port carries it off the machine.
|
|
42
|
+
*/
|
|
43
|
+
portTable?: {
|
|
44
|
+
port: number;
|
|
45
|
+
ports: Pick<BrowserServerBridge, "registerServer" | "unregisterServer">;
|
|
46
|
+
webSockets: BrowserVirtualWebSocketRegistry;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* The endpoint's discovery documents alone (`/json/version`, `/json/list`)
|
|
50
|
+
* in the tab's port table, where a program's `fetch` to a loopback port
|
|
51
|
+
* goes: Puppeteer reads `browserURL` so. The WebSocket they name stays on
|
|
52
|
+
* the listener, which the tab's programs reach and a page of the tab does
|
|
53
|
+
* not, so a page learns the address and cannot drive the browser.
|
|
54
|
+
*/
|
|
55
|
+
discoveryTable?: {
|
|
56
|
+
port: number;
|
|
57
|
+
ports: Pick<BrowserServerBridge, "registerServer" | "unregisterServer">;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Where a download a page makes is written: the path Playwright names in
|
|
61
|
+
* its client's filesystem, which is the container's. Without it the
|
|
62
|
+
* endpoint refuses download policy by name.
|
|
63
|
+
*/
|
|
64
|
+
downloads?: {
|
|
65
|
+
write(path: string, bytes: Uint8Array): Promise<void>;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Reads a file a client names by path for a page's file input
|
|
69
|
+
* (DOM.setFileInputFiles): the client's filesystem, the container's. The
|
|
70
|
+
* page is given those files' bytes alone. Without it the endpoint refuses
|
|
71
|
+
* file paths by name.
|
|
72
|
+
*/
|
|
73
|
+
files?: {
|
|
74
|
+
read(path: string): Promise<{
|
|
75
|
+
data: Uint8Array;
|
|
76
|
+
name?: string;
|
|
77
|
+
type?: string;
|
|
78
|
+
lastModified?: number;
|
|
79
|
+
}>;
|
|
80
|
+
/** A directory's files by their paths relative to it (a folder upload); undefined for a file. */
|
|
81
|
+
list?(path: string): Promise<string[] | undefined>;
|
|
82
|
+
};
|
|
83
|
+
}): PreviewCdpPublication;
|
|
84
|
+
//# sourceMappingURL=preview-cdp-endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-cdp-endpoint.d.ts","sourceRoot":"","sources":["../src/preview-cdp-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,UAAU,EAAuB,MAAM,0BAA0B,CAAC;AACtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AAC9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,+BAA+B,EAA4B,MAAM,sDAAsD,CAAC;AACtI,OAAO,EAA4B,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAErG,0FAA0F;AAC1F,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;AAEpG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC;;;;OAIG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,eAAe,CAAC,CAAC;IAC3D;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,CAAC;QAAC,UAAU,EAAE,+BAA+B,CAAA;KAAE,CAAC;IACnJ;;;;;;OAMG;IACH,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,CAAA;KAAE,CAAC;IAC3G;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACtE;;;;;OAKG;IACH,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE,UAAU,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,YAAY,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACvG,iGAAiG;QACjG,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;KACpD,CAAC;CACH,GAAG,qBAAqB,CAmDxB"}
|