@roxybrowser/playwright 2.0.2-beta.1 → 2.0.2-beta.12
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 +30 -7
- package/dist/bin/roxybrowser-mcp.js +3 -0
- package/dist/bin/roxybrowser-mcp.js.map +1 -1
- package/dist/browser.d.ts +33 -5
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +134 -15
- package/dist/browser.js.map +1 -1
- package/dist/browserType.d.ts +23 -1
- package/dist/browserType.d.ts.map +1 -1
- package/dist/browserType.js +33 -5
- package/dist/browserType.js.map +1 -1
- package/dist/human/bubbleCursor.d.ts +2 -0
- package/dist/human/bubbleCursor.d.ts.map +1 -0
- package/dist/human/bubbleCursor.js +126 -0
- package/dist/human/bubbleCursor.js.map +1 -0
- package/dist/human/controller.d.ts +1 -0
- package/dist/human/controller.d.ts.map +1 -1
- package/dist/human/controller.js +13 -12
- package/dist/human/controller.js.map +1 -1
- package/dist/human/profile.d.ts.map +1 -1
- package/dist/human/profile.js +0 -4
- package/dist/human/profile.js.map +1 -1
- package/dist/human/types.d.ts +0 -1
- package/dist/human/types.d.ts.map +1 -1
- package/dist/locator.js +1 -1
- package/dist/locator.js.map +1 -1
- package/dist/mcp/backend/connect.d.ts +1 -0
- package/dist/mcp/backend/connect.d.ts.map +1 -1
- package/dist/mcp/backend/connect.js +4 -2
- package/dist/mcp/backend/connect.js.map +1 -1
- package/dist/mcp/backend/context.d.ts +3 -0
- package/dist/mcp/backend/context.d.ts.map +1 -1
- package/dist/mcp/backend/context.js +9 -1
- package/dist/mcp/backend/context.js.map +1 -1
- package/dist/mcp/backend/keyboard.d.ts +28 -0
- package/dist/mcp/backend/keyboard.d.ts.map +1 -1
- package/dist/mcp/backend/keyboard.js +9 -3
- package/dist/mcp/backend/keyboard.js.map +1 -1
- package/dist/mcp/backend/network.d.ts.map +1 -1
- package/dist/mcp/backend/network.js +30 -4
- package/dist/mcp/backend/network.js.map +1 -1
- package/dist/mcp/backend/response.d.ts +2 -0
- package/dist/mcp/backend/response.d.ts.map +1 -1
- package/dist/mcp/backend/response.js +53 -7
- package/dist/mcp/backend/response.js.map +1 -1
- package/dist/mcp/connectedBrowser.d.ts.map +1 -1
- package/dist/mcp/connectedBrowser.js +492 -43
- package/dist/mcp/connectedBrowser.js.map +1 -1
- package/dist/mcp/output.d.ts +5 -0
- package/dist/mcp/output.d.ts.map +1 -1
- package/dist/mcp/output.js +17 -1
- package/dist/mcp/output.js.map +1 -1
- package/dist/mcp/runtime.d.ts +10 -1
- package/dist/mcp/runtime.d.ts.map +1 -1
- package/dist/mcp/runtime.js +82 -13
- package/dist/mcp/runtime.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +3 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/mouse.d.ts.map +1 -1
- package/dist/mcp/tools/mouse.js +5 -2
- package/dist/mcp/tools/mouse.js.map +1 -1
- package/dist/mcp/transports/inMemory.d.ts.map +1 -1
- package/dist/mcp/transports/inMemory.js +1 -0
- package/dist/mcp/transports/inMemory.js.map +1 -1
- package/dist/mcp/types.d.ts +12 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/page.d.ts +2 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +12 -0
- package/dist/page.js.map +1 -1
- package/dist/protocol/adapter.d.ts +1 -0
- package/dist/protocol/adapter.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.d.ts +1 -1
- package/dist/protocol/bidi/backend.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.js +6 -2
- package/dist/protocol/bidi/backend.js.map +1 -1
- package/dist/protocol/cdp/backend.d.ts.map +1 -1
- package/dist/protocol/cdp/backend.js +122 -8
- package/dist/protocol/cdp/backend.js.map +1 -1
- package/dist/roxybrowser.bundle.js +560 -68
- package/dist/roxybrowser.bundle.js.map +1 -1
- package/dist/types/api.d.ts +23 -4
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/options.d.ts +0 -1
- package/dist/types/options.d.ts.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -71,10 +71,11 @@ Useful environment variables:
|
|
|
71
71
|
- `ROXY_HEADLESS=false`
|
|
72
72
|
- `ROXY_CDP_WS_ENDPOINT=ws://127.0.0.1:9222/devtools/browser/<id>`
|
|
73
73
|
- `ROXY_MCP_OUTPUT_DIR=/absolute/path/to/output`
|
|
74
|
+
- `ROXY_MCP_TEMP_DIR=/absolute/path/to/temp`
|
|
74
75
|
|
|
75
76
|
## MCP output directory
|
|
76
77
|
|
|
77
|
-
The MCP tools that
|
|
78
|
+
The MCP tools that produce durable output files, such as `browser_take_screenshot`,
|
|
78
79
|
`browser_network_requests`, `browser_network_request`, `browser_console_messages`,
|
|
79
80
|
and `browser_evaluate`, support a shared output directory.
|
|
80
81
|
|
|
@@ -82,9 +83,25 @@ and `browser_evaluate`, support a shared output directory.
|
|
|
82
83
|
- `PLAYWRIGHT_MCP_OUTPUT_DIR` is also recognized for compatibility with Playwright MCP.
|
|
83
84
|
- If a tool receives a relative `filename`, it will be resolved inside the output directory.
|
|
84
85
|
- If a tool receives an absolute `filename`, it will be used as-is.
|
|
85
|
-
- If no output directory is configured, the default is `.roxybrowser-mcp` under the current working directory, or the system temp directory when the cwd is not writable.
|
|
86
|
+
- If no output directory is configured, the default is `.roxybrowser-playwright-mcp` under the current working directory, or the system temp directory when the cwd is not writable.
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
## MCP temp directory
|
|
89
|
+
|
|
90
|
+
Some MCP runtime files are intentionally kept separate from `outputDir`.
|
|
91
|
+
These are short-lived files created during automation, such as:
|
|
92
|
+
|
|
93
|
+
- `browser_snapshot` files saved with `filename`
|
|
94
|
+
- browser console event log files referenced from snapshots
|
|
95
|
+
|
|
96
|
+
Temp directory behavior:
|
|
97
|
+
|
|
98
|
+
- Set `ROXY_MCP_TEMP_DIR` to choose the default directory for MCP runtime temp files.
|
|
99
|
+
- `PLAYWRIGHT_MCP_TEMP_DIR` is also recognized for compatibility with Playwright MCP.
|
|
100
|
+
- If a tool receives a relative `filename`, it will be resolved inside the temp directory.
|
|
101
|
+
- If a tool receives an absolute `filename`, it will be used as-is.
|
|
102
|
+
- If no temp directory is configured, the default is the system temp directory from Node.js `os.tmpdir()`.
|
|
103
|
+
|
|
104
|
+
You can also set `outputDir` and `tempDir` directly when creating the MCP server or transports:
|
|
88
105
|
|
|
89
106
|
```ts
|
|
90
107
|
import {
|
|
@@ -95,22 +112,27 @@ import {
|
|
|
95
112
|
} from "@roxybrowser/playwright/mcp";
|
|
96
113
|
|
|
97
114
|
const outputDir = "/absolute/path/to/output";
|
|
115
|
+
const tempDir = "/absolute/path/to/temp";
|
|
98
116
|
|
|
99
117
|
createRoxyBrowserMcpServer({
|
|
100
|
-
outputDir
|
|
118
|
+
outputDir,
|
|
119
|
+
tempDir
|
|
101
120
|
});
|
|
102
121
|
|
|
103
122
|
await createRoxyBrowserMcpInMemory({
|
|
104
|
-
outputDir
|
|
123
|
+
outputDir,
|
|
124
|
+
tempDir
|
|
105
125
|
});
|
|
106
126
|
|
|
107
127
|
await startRoxyBrowserMcpHttp({
|
|
108
128
|
port: 3000,
|
|
109
|
-
outputDir
|
|
129
|
+
outputDir,
|
|
130
|
+
tempDir
|
|
110
131
|
});
|
|
111
132
|
|
|
112
133
|
await startRoxyBrowserMcpStdio({
|
|
113
|
-
outputDir
|
|
134
|
+
outputDir,
|
|
135
|
+
tempDir
|
|
114
136
|
});
|
|
115
137
|
```
|
|
116
138
|
|
|
@@ -164,6 +186,7 @@ node ./dist/bin/roxybrowser-mcp.js --transport http --port 3333 --host 127.0.0.1
|
|
|
164
186
|
Optional flags:
|
|
165
187
|
|
|
166
188
|
- `--output-dir /absolute/path`
|
|
189
|
+
- `--temp-dir /absolute/path`
|
|
167
190
|
- `--snapshot-mode full`
|
|
168
191
|
- `--snapshot-mode none`
|
|
169
192
|
|
|
@@ -10,6 +10,7 @@ function parseCliOptions(argv) {
|
|
|
10
10
|
port: { type: "string" },
|
|
11
11
|
path: { type: "string" },
|
|
12
12
|
"output-dir": { type: "string" },
|
|
13
|
+
"temp-dir": { type: "string" },
|
|
13
14
|
"snapshot-mode": { type: "string" }
|
|
14
15
|
},
|
|
15
16
|
allowPositionals: false
|
|
@@ -35,12 +36,14 @@ function parseCliOptions(argv) {
|
|
|
35
36
|
...(port !== undefined ? { port } : {}),
|
|
36
37
|
...(values.path !== undefined ? { path: values.path } : {}),
|
|
37
38
|
...(values["output-dir"] !== undefined ? { outputDir: values["output-dir"] } : {}),
|
|
39
|
+
...(values["temp-dir"] !== undefined ? { tempDir: values["temp-dir"] } : {}),
|
|
38
40
|
...(snapshotMode !== undefined ? { snapshotMode: snapshotMode } : {})
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
43
|
function sharedOptions(options) {
|
|
42
44
|
return {
|
|
43
45
|
...(options.outputDir !== undefined ? { outputDir: options.outputDir } : {}),
|
|
46
|
+
...(options.tempDir !== undefined ? { tempDir: options.tempDir } : {}),
|
|
44
47
|
...(options.snapshotMode !== undefined ? { snapshotMode: options.snapshotMode } : {})
|
|
45
48
|
};
|
|
46
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roxybrowser-mcp.js","sourceRoot":"","sources":["../../src/bin/roxybrowser-mcp.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"roxybrowser-mcp.js","sourceRoot":"","sources":["../../src/bin/roxybrowser-mcp.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAmBpF,SAAS,eAAe,CAAC,IAAc;IACrC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC7B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACpC;QACD,gBAAgB,EAAE,KAAK;KACxB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO,CAAW,CAAC;IAC1D,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,gCAAgC,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IAC7C,IACE,YAAY,KAAK,SAAS;WACvB,YAAY,KAAK,MAAM;WACvB,YAAY,KAAK,MAAM,EAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,YAAY,+BAA+B,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;IAC9B,MAAM,IAAI,GACR,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACvE,IAAI,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,yBAAyB,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,SAAS;QACT,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,YAA4B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAmB;IAIxC,OAAO;QACL,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvD,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,WAAW,GAAmC;YAClD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,aAAa,CAAC,OAAO,CAAC;SAC1B,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC;QAC7C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,MAAM,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,mDAAmD,IAAI,IAAI,WAAW,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;QAEpG,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;YACtC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,wBAAwB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
import type { ProtocolBrowserAdapter, ProtocolBrowserSession } from "./protocol/adapter.js";
|
|
2
|
-
import type { Browser, BrowserContext } from "./types/api.js";
|
|
2
|
+
import type { Browser, BrowserContext, BrowserType, Page } from "./types/api.js";
|
|
3
3
|
import type { BrowserContextOptions } from "./types/options.js";
|
|
4
4
|
import type { ResolvedHumanizationOptions } from "./human/types.js";
|
|
5
5
|
export declare class RoxyBrowser implements Browser {
|
|
6
6
|
private readonly session;
|
|
7
7
|
private readonly adapter;
|
|
8
8
|
private readonly humanDefaults;
|
|
9
|
-
private readonly
|
|
10
|
-
|
|
9
|
+
private readonly _browserName;
|
|
10
|
+
private readonly _browserType;
|
|
11
|
+
private readonly _version;
|
|
12
|
+
private readonly _contexts;
|
|
13
|
+
private readonly _listeners;
|
|
14
|
+
private _connected;
|
|
15
|
+
constructor(session: ProtocolBrowserSession, adapter: ProtocolBrowserAdapter, humanDefaults: ResolvedHumanizationOptions, _browserName: "chromium" | "firefox", _browserType: BrowserType, _version: string);
|
|
16
|
+
on(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
17
|
+
on(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
18
|
+
once(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
19
|
+
once(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
20
|
+
addListener(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
21
|
+
addListener(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
22
|
+
removeListener(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
23
|
+
removeListener(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
24
|
+
off(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
25
|
+
off(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
26
|
+
prependListener(event: 'context', listener: (context: BrowserContext) => any): this;
|
|
27
|
+
prependListener(event: 'disconnected', listener: (browser: Browser) => any): this;
|
|
28
|
+
removeAllListeners(type?: string): this;
|
|
29
|
+
browserType(): BrowserType;
|
|
30
|
+
contexts(): BrowserContext[];
|
|
31
|
+
isConnected(): boolean;
|
|
32
|
+
version(): string;
|
|
11
33
|
newContext(options?: BrowserContextOptions): Promise<BrowserContext>;
|
|
12
|
-
|
|
13
|
-
close(
|
|
34
|
+
newPage(options?: BrowserContextOptions): Promise<Page>;
|
|
35
|
+
close(options?: {
|
|
36
|
+
reason?: string;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
private _addListenerInternal;
|
|
39
|
+
private _removeListenerInternal;
|
|
40
|
+
private _ensureListenerSet;
|
|
41
|
+
private _emit;
|
|
14
42
|
}
|
|
15
43
|
//# sourceMappingURL=browser.d.ts.map
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/browser.js
CHANGED
|
@@ -7,20 +7,79 @@ export class RoxyBrowser {
|
|
|
7
7
|
session;
|
|
8
8
|
adapter;
|
|
9
9
|
humanDefaults;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
_browserName;
|
|
11
|
+
_browserType;
|
|
12
|
+
_version;
|
|
13
|
+
_contexts = [];
|
|
14
|
+
_listeners = new Map();
|
|
15
|
+
_connected = true;
|
|
16
|
+
constructor(session, adapter, humanDefaults, _browserName, _browserType, _version) {
|
|
12
17
|
this.session = session;
|
|
13
18
|
this.adapter = adapter;
|
|
14
19
|
this.humanDefaults = humanDefaults;
|
|
15
|
-
this.
|
|
20
|
+
this._browserName = _browserName;
|
|
21
|
+
this._browserType = _browserType;
|
|
22
|
+
this._version = _version;
|
|
23
|
+
}
|
|
24
|
+
on(event, listener) {
|
|
25
|
+
return this._addListenerInternal(event, listener);
|
|
26
|
+
}
|
|
27
|
+
once(event, listener) {
|
|
28
|
+
const wrapped = (payload) => {
|
|
29
|
+
this._removeListenerInternal(event, listener);
|
|
30
|
+
listener(payload);
|
|
31
|
+
};
|
|
32
|
+
this._ensureListenerSet(event).add({ original: listener, wrapped });
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
addListener(event, listener) {
|
|
36
|
+
return this._addListenerInternal(event, listener);
|
|
37
|
+
}
|
|
38
|
+
removeListener(event, listener) {
|
|
39
|
+
return this._removeListenerInternal(event, listener);
|
|
40
|
+
}
|
|
41
|
+
off(event, listener) {
|
|
42
|
+
return this._removeListenerInternal(event, listener);
|
|
43
|
+
}
|
|
44
|
+
prependListener(event, listener) {
|
|
45
|
+
const entry = { original: listener, wrapped: listener };
|
|
46
|
+
const existing = this._listeners.get(event);
|
|
47
|
+
if (!existing) {
|
|
48
|
+
const s = new Set([entry]);
|
|
49
|
+
this._listeners.set(event, s);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const s = new Set([entry, ...Array.from(existing)]);
|
|
53
|
+
this._listeners.set(event, s);
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
removeAllListeners(type) {
|
|
58
|
+
if (type === undefined) {
|
|
59
|
+
this._listeners.clear();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this._listeners.delete(type);
|
|
63
|
+
}
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
browserType() {
|
|
67
|
+
return this._browserType;
|
|
68
|
+
}
|
|
69
|
+
contexts() {
|
|
70
|
+
return [...this._contexts];
|
|
71
|
+
}
|
|
72
|
+
isConnected() {
|
|
73
|
+
return this._connected;
|
|
74
|
+
}
|
|
75
|
+
version() {
|
|
76
|
+
return this._version;
|
|
16
77
|
}
|
|
17
78
|
async newContext(options = {}) {
|
|
18
79
|
const normalizedOptions = {
|
|
19
80
|
...options,
|
|
20
81
|
...(options.extraHTTPHeaders
|
|
21
|
-
? {
|
|
22
|
-
extraHTTPHeaders: normalizeExtraHTTPHeaders(options.extraHTTPHeaders)
|
|
23
|
-
}
|
|
82
|
+
? { extraHTTPHeaders: normalizeExtraHTTPHeaders(options.extraHTTPHeaders) }
|
|
24
83
|
: {}),
|
|
25
84
|
...(options.recordVideo
|
|
26
85
|
? {
|
|
@@ -32,19 +91,82 @@ export class RoxyBrowser {
|
|
|
32
91
|
: {})
|
|
33
92
|
};
|
|
34
93
|
const contextAdapter = await this.session.newContext(normalizedOptions);
|
|
35
|
-
|
|
94
|
+
const context = new RoxyBrowserContext(contextAdapter, resolveHumanizationOptions(normalizedOptions.human, this.humanDefaults), normalizedOptions, this._browserName);
|
|
95
|
+
this._contexts.push(context);
|
|
96
|
+
context.on("close", () => {
|
|
97
|
+
const index = this._contexts.indexOf(context);
|
|
98
|
+
if (index !== -1)
|
|
99
|
+
this._contexts.splice(index, 1);
|
|
100
|
+
});
|
|
101
|
+
this._emit('context', context);
|
|
102
|
+
// Wait for the adapter's initial page discovery to complete before returning.
|
|
103
|
+
// For CDP contexts this means waiting until all pre-existing tabs have been
|
|
104
|
+
// attached and their page objects emitted to listeners, so context.pages()
|
|
105
|
+
// is non-empty immediately after newContext() resolves.
|
|
106
|
+
// The onPage listener is already registered above (via new RoxyBrowserContext),
|
|
107
|
+
// so pages emitted during ready() will be captured correctly.
|
|
108
|
+
await contextAdapter.ready?.();
|
|
109
|
+
return context;
|
|
36
110
|
}
|
|
37
|
-
async
|
|
38
|
-
|
|
111
|
+
async newPage(options) {
|
|
112
|
+
const context = await this.newContext(options);
|
|
113
|
+
const page = await context.newPage();
|
|
114
|
+
const roxyPage = page;
|
|
115
|
+
if (typeof roxyPage.setOwnedContext === "function") {
|
|
116
|
+
// Closing an owned page tears down its browser context, mirroring
|
|
117
|
+
// Playwright. Other Page implementations fall back to a best-effort
|
|
118
|
+
// close listener.
|
|
119
|
+
roxyPage.setOwnedContext(context);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
page.once('close', () => context.close().catch(() => { }));
|
|
123
|
+
}
|
|
124
|
+
return page;
|
|
39
125
|
}
|
|
40
|
-
async close() {
|
|
126
|
+
async close(options) {
|
|
127
|
+
if (!this._connected)
|
|
128
|
+
return;
|
|
129
|
+
this._connected = false;
|
|
41
130
|
try {
|
|
42
131
|
await withCloseTimeout(this.session.close(), BROWSER_SESSION_CLOSE_TIMEOUT_MS);
|
|
43
132
|
}
|
|
44
133
|
finally {
|
|
45
134
|
await this.adapter.close();
|
|
135
|
+
this._emit('disconnected', this);
|
|
46
136
|
}
|
|
47
137
|
}
|
|
138
|
+
_addListenerInternal(event, listener) {
|
|
139
|
+
this._ensureListenerSet(event).add({ original: listener, wrapped: listener });
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
_removeListenerInternal(event, listener) {
|
|
143
|
+
const entries = this._listeners.get(event);
|
|
144
|
+
if (!entries)
|
|
145
|
+
return this;
|
|
146
|
+
for (const entry of Array.from(entries)) {
|
|
147
|
+
if (entry.original === listener)
|
|
148
|
+
entries.delete(entry);
|
|
149
|
+
}
|
|
150
|
+
if (entries.size === 0)
|
|
151
|
+
this._listeners.delete(event);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
_ensureListenerSet(event) {
|
|
155
|
+
const existing = this._listeners.get(event);
|
|
156
|
+
if (existing)
|
|
157
|
+
return existing;
|
|
158
|
+
const created = new Set();
|
|
159
|
+
this._listeners.set(event, created);
|
|
160
|
+
return created;
|
|
161
|
+
}
|
|
162
|
+
_emit(event, payload) {
|
|
163
|
+
const entries = this._listeners.get(event);
|
|
164
|
+
if (!entries?.size)
|
|
165
|
+
return false;
|
|
166
|
+
for (const entry of Array.from(entries))
|
|
167
|
+
entry.wrapped(payload);
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
48
170
|
}
|
|
49
171
|
async function withCloseTimeout(promise, timeoutMs) {
|
|
50
172
|
let timer;
|
|
@@ -52,16 +174,13 @@ async function withCloseTimeout(promise, timeoutMs) {
|
|
|
52
174
|
return await Promise.race([
|
|
53
175
|
promise,
|
|
54
176
|
new Promise((_, reject) => {
|
|
55
|
-
timer = setTimeout(() => {
|
|
56
|
-
reject(new Error(`Timed out closing browser session after ${timeoutMs}ms.`));
|
|
57
|
-
}, timeoutMs);
|
|
177
|
+
timer = setTimeout(() => reject(new Error(`Timed out closing browser session after ${timeoutMs}ms.`)), timeoutMs);
|
|
58
178
|
})
|
|
59
179
|
]);
|
|
60
180
|
}
|
|
61
181
|
finally {
|
|
62
|
-
if (timer)
|
|
182
|
+
if (timer)
|
|
63
183
|
clearTimeout(timer);
|
|
64
|
-
}
|
|
65
184
|
}
|
|
66
185
|
}
|
|
67
186
|
//# sourceMappingURL=browser.js.map
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/browserType.d.ts
CHANGED
|
@@ -6,7 +6,29 @@ export declare class RoxyBrowserType implements BrowserType {
|
|
|
6
6
|
private readonly adapterFactories;
|
|
7
7
|
constructor(browserName: NonNullable<BrowserConnectOptions["browserName"]>, adapterFactories: Record<SupportedProtocol, ProtocolBrowserAdapterFactory>);
|
|
8
8
|
launch(options?: LaunchOptions): Promise<Browser>;
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Connect to an already-running browser over a WebSocket endpoint.
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ DIVERGENCE FROM PLAYWRIGHT — DO NOT "FIX" THIS BACK TO CDP-ONLY:
|
|
13
|
+
*
|
|
14
|
+
* In upstream Playwright, `BrowserType.connect()` is a CDP-only operation: it
|
|
15
|
+
* connects to a running Chromium over the DevTools Protocol. Firefox/WebKit are
|
|
16
|
+
* not supported here (Playwright routes BiDi through `connectOverCDP`-style
|
|
17
|
+
* helpers or its own internal plumbing, not this method).
|
|
18
|
+
*
|
|
19
|
+
* Roxy intentionally changes that semantics. This method dispatches on
|
|
20
|
+
* `browserName` so a single entry point serves both browser families:
|
|
21
|
+
* - chromium → CDP (ws:// DevTools endpoint)
|
|
22
|
+
* - firefox → BiDi (ws:// WebDriver BiDi endpoint)
|
|
23
|
+
*
|
|
24
|
+
* This is deliberate, not a bug. If you are an agent "normalizing" this code to
|
|
25
|
+
* match Playwright upstream, STOP — the dual-protocol dispatch is the feature.
|
|
26
|
+
* To force CDP specifically, call `connectOverCDP()` instead, which remains
|
|
27
|
+
* chromium-only and CDP-only by design (see the guard below).
|
|
28
|
+
*
|
|
29
|
+
* `options.protocol` may still be passed to override the per-browser default.
|
|
30
|
+
*/
|
|
31
|
+
connect(endpointURL: string, options?: ConnectOverCDPOptions): Promise<Browser>;
|
|
10
32
|
connectOverCDP(endpointURL: string, options?: ConnectOverCDPOptions): Promise<Browser>;
|
|
11
33
|
connectOverCDP(progress: Progress, endpointURL: string, options?: ConnectOverCDPOptions): Promise<Browser>;
|
|
12
34
|
private connectBrowser;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserType.d.ts","sourceRoot":"","sources":["../src/browserType.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,eAAgB,YAAW,WAAW;IAE/C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,WAAW,EAAE,WAAW,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAC9D,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,EAAE,6BAA6B,CAAC;IAGvF,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"browserType.d.ts","sourceRoot":"","sources":["../src/browserType.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,eAAgB,YAAW,WAAW;IAE/C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,WAAW,EAAE,WAAW,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAC9D,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,EAAE,6BAA6B,CAAC;IAGvF,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ3D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/E,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,CAAC;IACb,cAAc,CAClB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,CAAC;YAoCL,cAAc;CA2B7B;AAED,eAAO,MAAM,QAAQ,EAAE,WAGrB,CAAC;AAEH,eAAO,MAAM,OAAO,EAAE,WAGpB,CAAC"}
|
package/dist/browserType.js
CHANGED
|
@@ -16,11 +16,34 @@ export class RoxyBrowserType {
|
|
|
16
16
|
protocol: options.protocol ?? (this.browserName === "firefox" ? "bidi" : "cdp")
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Connect to an already-running browser over a WebSocket endpoint.
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ DIVERGENCE FROM PLAYWRIGHT — DO NOT "FIX" THIS BACK TO CDP-ONLY:
|
|
23
|
+
*
|
|
24
|
+
* In upstream Playwright, `BrowserType.connect()` is a CDP-only operation: it
|
|
25
|
+
* connects to a running Chromium over the DevTools Protocol. Firefox/WebKit are
|
|
26
|
+
* not supported here (Playwright routes BiDi through `connectOverCDP`-style
|
|
27
|
+
* helpers or its own internal plumbing, not this method).
|
|
28
|
+
*
|
|
29
|
+
* Roxy intentionally changes that semantics. This method dispatches on
|
|
30
|
+
* `browserName` so a single entry point serves both browser families:
|
|
31
|
+
* - chromium → CDP (ws:// DevTools endpoint)
|
|
32
|
+
* - firefox → BiDi (ws:// WebDriver BiDi endpoint)
|
|
33
|
+
*
|
|
34
|
+
* This is deliberate, not a bug. If you are an agent "normalizing" this code to
|
|
35
|
+
* match Playwright upstream, STOP — the dual-protocol dispatch is the feature.
|
|
36
|
+
* To force CDP specifically, call `connectOverCDP()` instead, which remains
|
|
37
|
+
* chromium-only and CDP-only by design (see the guard below).
|
|
38
|
+
*
|
|
39
|
+
* `options.protocol` may still be passed to override the per-browser default.
|
|
40
|
+
*/
|
|
41
|
+
async connect(endpointURL, options) {
|
|
20
42
|
return this.connectBrowser({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
browserName: this.browserName,
|
|
44
|
+
protocol: this.browserName === "chromium" ? "cdp" : "bidi",
|
|
45
|
+
wsEndpoint: endpointURL,
|
|
46
|
+
...options
|
|
24
47
|
});
|
|
25
48
|
}
|
|
26
49
|
async connectOverCDP(progressOrEndpointURL, endpointURLOrOptions, maybeOptions = {}) {
|
|
@@ -54,7 +77,12 @@ export class RoxyBrowserType {
|
|
|
54
77
|
});
|
|
55
78
|
await adapter.connect();
|
|
56
79
|
const session = await adapter.browser();
|
|
57
|
-
|
|
80
|
+
const versionStr = await session.version();
|
|
81
|
+
const browser = new RoxyBrowser(session, adapter, resolveHumanizationOptions(options.human), options.browserName ?? this.browserName, this, versionStr);
|
|
82
|
+
if (options.wsEndpoint) {
|
|
83
|
+
await browser.newContext({ reuseDefaultUserContext: true });
|
|
84
|
+
}
|
|
85
|
+
return browser;
|
|
58
86
|
}
|
|
59
87
|
}
|
|
60
88
|
export const chromium = new RoxyBrowserType("chromium", {
|
package/dist/browserType.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserType.js","sourceRoot":"","sources":["../src/browserType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAWrE,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,WAA8D,EAC9D,gBAA0E;QAD1E,gBAAW,GAAX,WAAW,CAAmD;QAC9D,qBAAgB,GAAhB,gBAAgB,CAA0D;IAC1F,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,UAAyB,EAAE;QACtC,OAAO,IAAI,CAAC,cAAc,CAAC;YACzB,GAAG,OAAO;YACV,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;SAChF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"browserType.js","sourceRoot":"","sources":["../src/browserType.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const BUBBLE_CURSOR_INSTALL_SOURCE = "(() => {\n const globalState = globalThis;\n if (globalState.__roxyBubbleCursor?.installed) {\n return true;\n }\n\n const prefersReducedMotion = globalState.matchMedia?.('(prefers-reduced-motion: reduce)');\n if (prefersReducedMotion?.matches) {\n globalState.__roxyBubbleCursor = {\n installed: false,\n reducedMotion: true\n };\n return false;\n }\n\n class Particle {\n constructor(x, y) {\n this.initialLifeSpan = Math.floor(Math.random() * 60 + 60);\n this.lifeSpan = this.initialLifeSpan;\n this.velocity = {\n x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 10),\n y: -0.4 + Math.random() * -1\n };\n this.position = { x, y };\n this.baseDimension = 4;\n }\n\n update(context) {\n this.position.x += this.velocity.x;\n this.position.y += this.velocity.y;\n this.velocity.x += ((Math.random() < 0.5 ? -1 : 1) * 2) / 75;\n this.velocity.y -= Math.random() / 600;\n this.lifeSpan -= 1;\n\n const scale = 0.2 + (this.initialLifeSpan - this.lifeSpan) / this.initialLifeSpan;\n\n context.fillStyle = '#e6f1f7';\n context.strokeStyle = '#3a92c5';\n context.beginPath();\n context.arc(\n this.position.x - (this.baseDimension / 2) * scale,\n this.position.y - this.baseDimension / 2,\n this.baseDimension * scale,\n 0,\n 2 * Math.PI\n );\n context.stroke();\n context.fill();\n context.closePath();\n }\n }\n\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if (!context) {\n return false;\n }\n\n let particles = [];\n let animationFrameId = null;\n\n canvas.style.position = 'fixed';\n canvas.style.top = '0px';\n canvas.style.left = '0px';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '2147483647';\n\n const resize = () => {\n canvas.width = globalState.innerWidth;\n canvas.height = globalState.innerHeight;\n };\n\n const addParticle = (x, y) => {\n particles.push(new Particle(x, y));\n };\n\n const onPointerMove = (event) => {\n addParticle(event.clientX, event.clientY);\n };\n\n const onTouchMove = (event) => {\n for (const touch of event.touches) {\n addParticle(touch.clientX, touch.clientY);\n }\n };\n\n const updateParticles = () => {\n context.clearRect(0, 0, canvas.width, canvas.height);\n for (const particle of particles) {\n particle.update(context);\n }\n particles = particles.filter((particle) => particle.lifeSpan >= 0);\n };\n\n const loop = () => {\n updateParticles();\n animationFrameId = globalState.requestAnimationFrame(loop);\n };\n\n resize();\n document.documentElement.appendChild(canvas);\n document.addEventListener('mousemove', onPointerMove, true);\n document.addEventListener('touchmove', onTouchMove, { passive: true, capture: true });\n document.addEventListener('touchstart', onTouchMove, { passive: true, capture: true });\n globalState.addEventListener('resize', resize);\n loop();\n\n globalState.__roxyBubbleCursor = {\n installed: true,\n destroy: () => {\n document.removeEventListener('mousemove', onPointerMove, true);\n document.removeEventListener('touchmove', onTouchMove, true);\n document.removeEventListener('touchstart', onTouchMove, true);\n globalState.removeEventListener('resize', resize);\n if (animationFrameId !== null) {\n globalState.cancelAnimationFrame(animationFrameId);\n }\n particles = [];\n canvas.remove();\n delete globalState.__roxyBubbleCursor;\n }\n };\n\n return true;\n})()";
|
|
2
|
+
//# sourceMappingURL=bubbleCursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubbleCursor.d.ts","sourceRoot":"","sources":["../../src/human/bubbleCursor.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,klHA4HpC,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
export const BUBBLE_CURSOR_INSTALL_SOURCE = `(() => {
|
|
2
|
+
const globalState = globalThis;
|
|
3
|
+
if (globalState.__roxyBubbleCursor?.installed) {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const prefersReducedMotion = globalState.matchMedia?.('(prefers-reduced-motion: reduce)');
|
|
8
|
+
if (prefersReducedMotion?.matches) {
|
|
9
|
+
globalState.__roxyBubbleCursor = {
|
|
10
|
+
installed: false,
|
|
11
|
+
reducedMotion: true
|
|
12
|
+
};
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class Particle {
|
|
17
|
+
constructor(x, y) {
|
|
18
|
+
this.initialLifeSpan = Math.floor(Math.random() * 60 + 60);
|
|
19
|
+
this.lifeSpan = this.initialLifeSpan;
|
|
20
|
+
this.velocity = {
|
|
21
|
+
x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 10),
|
|
22
|
+
y: -0.4 + Math.random() * -1
|
|
23
|
+
};
|
|
24
|
+
this.position = { x, y };
|
|
25
|
+
this.baseDimension = 4;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
update(context) {
|
|
29
|
+
this.position.x += this.velocity.x;
|
|
30
|
+
this.position.y += this.velocity.y;
|
|
31
|
+
this.velocity.x += ((Math.random() < 0.5 ? -1 : 1) * 2) / 75;
|
|
32
|
+
this.velocity.y -= Math.random() / 600;
|
|
33
|
+
this.lifeSpan -= 1;
|
|
34
|
+
|
|
35
|
+
const scale = 0.2 + (this.initialLifeSpan - this.lifeSpan) / this.initialLifeSpan;
|
|
36
|
+
|
|
37
|
+
context.fillStyle = '#e6f1f7';
|
|
38
|
+
context.strokeStyle = '#3a92c5';
|
|
39
|
+
context.beginPath();
|
|
40
|
+
context.arc(
|
|
41
|
+
this.position.x - (this.baseDimension / 2) * scale,
|
|
42
|
+
this.position.y - this.baseDimension / 2,
|
|
43
|
+
this.baseDimension * scale,
|
|
44
|
+
0,
|
|
45
|
+
2 * Math.PI
|
|
46
|
+
);
|
|
47
|
+
context.stroke();
|
|
48
|
+
context.fill();
|
|
49
|
+
context.closePath();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const canvas = document.createElement('canvas');
|
|
54
|
+
const context = canvas.getContext('2d');
|
|
55
|
+
if (!context) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let particles = [];
|
|
60
|
+
let animationFrameId = null;
|
|
61
|
+
|
|
62
|
+
canvas.style.position = 'fixed';
|
|
63
|
+
canvas.style.top = '0px';
|
|
64
|
+
canvas.style.left = '0px';
|
|
65
|
+
canvas.style.pointerEvents = 'none';
|
|
66
|
+
canvas.style.zIndex = '2147483647';
|
|
67
|
+
|
|
68
|
+
const resize = () => {
|
|
69
|
+
canvas.width = globalState.innerWidth;
|
|
70
|
+
canvas.height = globalState.innerHeight;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const addParticle = (x, y) => {
|
|
74
|
+
particles.push(new Particle(x, y));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const onPointerMove = (event) => {
|
|
78
|
+
addParticle(event.clientX, event.clientY);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const onTouchMove = (event) => {
|
|
82
|
+
for (const touch of event.touches) {
|
|
83
|
+
addParticle(touch.clientX, touch.clientY);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const updateParticles = () => {
|
|
88
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
89
|
+
for (const particle of particles) {
|
|
90
|
+
particle.update(context);
|
|
91
|
+
}
|
|
92
|
+
particles = particles.filter((particle) => particle.lifeSpan >= 0);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const loop = () => {
|
|
96
|
+
updateParticles();
|
|
97
|
+
animationFrameId = globalState.requestAnimationFrame(loop);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
resize();
|
|
101
|
+
document.documentElement.appendChild(canvas);
|
|
102
|
+
document.addEventListener('mousemove', onPointerMove, true);
|
|
103
|
+
document.addEventListener('touchmove', onTouchMove, { passive: true, capture: true });
|
|
104
|
+
document.addEventListener('touchstart', onTouchMove, { passive: true, capture: true });
|
|
105
|
+
globalState.addEventListener('resize', resize);
|
|
106
|
+
loop();
|
|
107
|
+
|
|
108
|
+
globalState.__roxyBubbleCursor = {
|
|
109
|
+
installed: true,
|
|
110
|
+
destroy: () => {
|
|
111
|
+
document.removeEventListener('mousemove', onPointerMove, true);
|
|
112
|
+
document.removeEventListener('touchmove', onTouchMove, true);
|
|
113
|
+
document.removeEventListener('touchstart', onTouchMove, true);
|
|
114
|
+
globalState.removeEventListener('resize', resize);
|
|
115
|
+
if (animationFrameId !== null) {
|
|
116
|
+
globalState.cancelAnimationFrame(animationFrameId);
|
|
117
|
+
}
|
|
118
|
+
particles = [];
|
|
119
|
+
canvas.remove();
|
|
120
|
+
delete globalState.__roxyBubbleCursor;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return true;
|
|
125
|
+
})()`;
|
|
126
|
+
//# sourceMappingURL=bubbleCursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubbleCursor.js","sourceRoot":"","sources":["../../src/human/bubbleCursor.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4HvC,CAAC"}
|