browserscale-ts 1.7.0 → 1.8.0
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 +136 -78
- package/dist/browser.js +1 -1
- package/dist/browserscale.browser.js +427 -162
- package/dist/client.d.ts +241 -62
- package/dist/client.js +312 -83
- package/dist/defaults.d.ts +11 -9
- package/dist/defaults.js +15 -12
- package/dist/dom-mirror.d.ts +27 -0
- package/dist/dom-mirror.js +27 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.js +37 -0
- package/dist/gen/wrc_pb.d.ts +348 -91
- package/dist/gen/wrc_pb.js +53 -58
- package/dist/index.d.ts +8 -5
- package/dist/index.js +8 -5
- package/dist/internal/convert.js +1 -0
- package/dist/locator.d.ts +12 -11
- package/dist/locator.js +14 -22
- package/dist/network-capture.d.ts +3 -2
- package/dist/network-capture.js +3 -2
- package/dist/options.d.ts +1 -1
- package/dist/scripts.d.ts +4 -3
- package/dist/scripts.js +4 -3
- package/dist/types.d.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**The official TypeScript SDK for [browserscale](https://browserscale.cloud) — real Chromium browsers in the cloud, driven over gRPC.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Browser automation that doesn't guess. Waits, clicks and frames are handled inside the browser engine instead of being approximated from outside — rent an isolated session in under 250 ms, drive it with input that arrives like hardware, see every request it makes, and watch it live. Runs in Node.js and the browser.
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/browserscale-ts)
|
|
10
10
|

|
|
@@ -19,82 +19,139 @@ Rent an isolated browser session in seconds, automate it with human-like input,
|
|
|
19
19
|
|
|
20
20
|
## Features
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
### Acting on the page
|
|
23
|
+
|
|
24
|
+
- **Clicks that check before they press** — the element is scrolled genuinely
|
|
25
|
+
into view (through nested scroll containers and up the frame chain), held
|
|
26
|
+
until it stops moving, approached on a human pointer path, and the exact pixel
|
|
27
|
+
is verified to belong to it — across process boundaries — before the button
|
|
28
|
+
goes down. Covered? The click re-aims at the visible part or steps out of a
|
|
29
|
+
hover overlay's way. Still blocked? It throws a `ClickError` naming the
|
|
30
|
+
element in the way.
|
|
31
|
+
- **Input the way hardware sends it** — pointer and key events take the path a
|
|
32
|
+
real mouse and keyboard take, with none of the markers of remote-controlled
|
|
33
|
+
input. Typing follows the session region's keyboard layout with per-character
|
|
34
|
+
timing that varies like a hand.
|
|
35
|
+
- **Failures you can act on** — every command answers with success or a stable
|
|
36
|
+
error code (`not_found`, `occluded_after_evade`, `timeout`, …) and throws a
|
|
37
|
+
typed error carrying the detail, so code and models repair a failure instead
|
|
38
|
+
of blindly retrying.
|
|
39
|
+
|
|
40
|
+
### Waiting & reacting
|
|
41
|
+
|
|
42
|
+
- **Waits the page reports, not a poll** — each document tells the wait the
|
|
43
|
+
moment a condition holds, usually within a frame; an idle wait does no work,
|
|
44
|
+
and more conditions or more frames cost a registration, not another loop. By
|
|
45
|
+
default a match means visible and holding still, not merely in the DOM.
|
|
46
|
+
- **Timeouts that explain themselves** — a `WaitError` says per condition how
|
|
47
|
+
far it got: `not_found`, `found_hidden`, `found_occluded` (with the blocker)
|
|
48
|
+
or `pending_steady`.
|
|
49
|
+
- **Reactions** — `addReaction` arms a one-shot handler in the browser for the
|
|
50
|
+
cookie banner or popup that may or may not show up. It fires between your
|
|
51
|
+
calls while the pointer is idle, across every frame and navigation, and
|
|
52
|
+
retires itself — so a click blocked by a modal lands because the reaction
|
|
53
|
+
cleared the modal mid-retry.
|
|
54
|
+
|
|
55
|
+
### Frames
|
|
56
|
+
|
|
36
57
|
- **One flat frame tree** — main document, same-origin iframes and cross-origin
|
|
37
|
-
OOPIFs are all just a `frameId
|
|
38
|
-
|
|
39
|
-
a
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
58
|
+
OOPIFs are all just a `frameId`: no per-frame sessions, no isolated worlds,
|
|
59
|
+
no depth limit. A frame created mid-wait is covered the moment it exists, and
|
|
60
|
+
a match returns the frame plus a node handle the next action routes on its own.
|
|
61
|
+
|
|
62
|
+
### Scripts beside the browser (BrowserVM, early access)
|
|
63
|
+
|
|
64
|
+
- **`runScript`** runs JavaScript in its own isolate next to the page, reaching
|
|
65
|
+
the document through the engine: a cross-origin `<iframe>` is plain
|
|
66
|
+
`contentDocument`, values are live objects, an element goes straight into
|
|
67
|
+
`browser.click`, and the page sees nothing injected. A refusal throws the
|
|
68
|
+
same error classes as this SDK. Steps cost
|
|
69
|
+
microseconds instead of round trips, so loops are affordable. `startScript`
|
|
70
|
+
leaves a script running without the caller; `followScript` attaches to one
|
|
71
|
+
already under way. [More on BrowserVM](https://browserscale.cloud/browservm).
|
|
72
|
+
Access is opened per account while in early access: ask
|
|
73
|
+
[support](mailto:support@browserscale.cloud) or on [Discord](https://discord.gg/SfE9C9K28D).
|
|
74
|
+
|
|
75
|
+
### Stealth on real hardware
|
|
76
|
+
|
|
77
|
+
- **Control lives below the page** — commands are carried out by the browser
|
|
78
|
+
itself: nothing injected, no `Runtime.enable`, no DevTools handshake, nothing
|
|
79
|
+
for page JavaScript to observe.
|
|
80
|
+
- **Real consumer GPUs, our own hardware** — Canvas, WebGL, audio and codec
|
|
81
|
+
readbacks are genuinely rendered; there is no spoofing layer or hash database
|
|
82
|
+
for deeper checks to unmask.
|
|
83
|
+
- **A shipped Chrome, not a build of one** — sessions carry the state and wire
|
|
84
|
+
behavior of a consumer browser, consistent with the region they exit from and
|
|
85
|
+
reproducible run over run.
|
|
86
|
+
|
|
87
|
+
### Network
|
|
88
|
+
|
|
89
|
+
- **Armed at the root, before anything loads** — interception sits in the
|
|
90
|
+
browser's network stack, so every frame, cross-process iframe, worker and
|
|
91
|
+
service worker passes through it. No attach race, nothing slips.
|
|
92
|
+
- **Capture that never pauses the page** — `captureNetwork` streams every
|
|
93
|
+
finished request with the headers and cookies actually put on the wire, each
|
|
94
|
+
redirect hop as its own exchange, bodies copied off to the side.
|
|
95
|
+
- **Catch one call and change it** — wait for a request or response, block,
|
|
96
|
+
mock, rewrite headers or bodies, or answer a whole navigation yourself with
|
|
97
|
+
`loadHTML`.
|
|
98
|
+
- **Pay for static assets once** — `setStaticPaths` serves heavy JS, CSS and
|
|
99
|
+
images from a server-side cache reached outside the proxy, so repeat runs pay
|
|
100
|
+
neither the download nor the proxy bandwidth.
|
|
101
|
+
|
|
102
|
+
### Identity & state
|
|
103
|
+
|
|
104
|
+
- **A login as one portable object** — `getAuthSession` / `setAuthSession`
|
|
105
|
+
export a signed-in persona, device-bound sessions (DBSC) included, and bring
|
|
106
|
+
it up signed in inside a fresh context.
|
|
107
|
+
- **Cookies and storage as data** — the whole jar, partitioned cookies
|
|
108
|
+
included, and local storage per origin, read and written with no page open.
|
|
109
|
+
- **A machine you can come back as** — a country sets language, locale,
|
|
110
|
+
timezone and keyboard together; cores, memory and renderer stay consistent in
|
|
111
|
+
every frame and worker. Pin the fingerprint and the next run is the same
|
|
112
|
+
computer returning. Bring your own proxy or let browserscale allocate one.
|
|
113
|
+
|
|
114
|
+
### Seeing the page
|
|
115
|
+
|
|
116
|
+
- **Agent-friendly observation** — `getObservation` returns one line per
|
|
117
|
+
element across every frame and closed shadow root, with role, live value,
|
|
118
|
+
label and flags, under a token budget — prompt-sized instead of a megabyte of
|
|
119
|
+
HTML, in one round trip.
|
|
120
|
+
- **Live DOM mirror** — `mirrorDom` keeps an incrementally updated copy of the
|
|
121
|
+
page: only what changed in the part you expanded is sent, an `<iframe>` is an
|
|
122
|
+
ordinary element holding its document, and `getDomRevision` is an O(1)
|
|
123
|
+
change check.
|
|
124
|
+
- Plus `screenshot`, `readCanvas` and `inspectAtPosition`.
|
|
125
|
+
|
|
126
|
+
### Sessions at scale
|
|
127
|
+
|
|
128
|
+
- **Contexts, not machines** — a session is an isolated browser context with
|
|
129
|
+
its own cookies, storage, cache, proxy and persona, ready in under 250 ms;
|
|
130
|
+
thousands run side by side without sharing state.
|
|
131
|
+
- **Sessions you can find again** — the browser lives server-side, so a session
|
|
132
|
+
outlives the process that rented it. `listBrowsers` shows what a key holds,
|
|
133
|
+
and the `grpcUrl` it reports goes straight into `connectSession` from any
|
|
134
|
+
machine.
|
|
135
|
+
- **Operated for you** — heavy sessions can't starve their neighbours, capacity
|
|
136
|
+
is warm before you rent (and a full host fails fast instead of hanging), and
|
|
137
|
+
sessions are rotated onto fresh processes without losing capacity.
|
|
138
|
+
- **Live stream and takeover** — a WebRTC stream encoded on the GPU that paints
|
|
139
|
+
the page; take over with mouse, keyboard and clipboard from the dashboard or
|
|
140
|
+
the CLI.
|
|
141
|
+
- **Captchas, no third-party solvers** — `solveCaptcha` completes interactive
|
|
142
|
+
challenges in the live session with browserscale's own solver; the provider's
|
|
143
|
+
own JavaScript issues the token, nothing is synthesized or bought from an
|
|
144
|
+
external API.
|
|
145
|
+
|
|
146
|
+
### Built for agents
|
|
147
|
+
|
|
148
|
+
- **MCP server** — `https://mcp.browserscale.cloud/mcp` exposes the same verbs
|
|
149
|
+
as this SDK to Cursor, Claude, Codex or any MCP client; the key stays in an
|
|
150
|
+
`Authorization` header, never in the model's context.
|
|
151
|
+
- **Flow-optimized TypeScript** — fully typed and promise-based, `wait` races
|
|
152
|
+
several outcomes, `js(...)` locators target by page logic when CSS is not
|
|
153
|
+
enough. Native gRPC in Node.js, WebSocket in the browser via
|
|
154
|
+
`browserscale-ts/browser`.
|
|
98
155
|
|
|
99
156
|
## Install
|
|
100
157
|
|
|
@@ -152,7 +209,7 @@ reports the element that occluded the click.
|
|
|
152
209
|
| `browser.click(target, opts?)` | Human-like click; throws a rich `ClickError` on failure. |
|
|
153
210
|
| `browser.fill(target, text, opts?)` | Per-key typing that fires real input events; `insertText` for bulk commit. |
|
|
154
211
|
| `browser.evaluate(expr)` | Run JS in the page/frame and get a typed value back. |
|
|
155
|
-
| `browser.runScript(source)` | Run JavaScript
|
|
212
|
+
| `browser.runScript(source)` | Run JavaScript beside the browser, where cross-origin frames are property access and every step is local; `startScript` leaves it running, `followScript` watches one already going. |
|
|
156
213
|
| `browser.getObservation(opts?)` | Compact, node-handle-tagged view of the visible page across frames; `opts` tunes budgets and format. |
|
|
157
214
|
| `browser.captureNetwork(opts, onExchange)` | Stream every request the session completes, optionally with response bodies. |
|
|
158
215
|
| `browser.mirrorDom(opts, onChange, onResync?)` | Live, incrementally updated copy of the page's DOM across every frame. |
|
|
@@ -194,8 +251,9 @@ import { rentBrowser, css } from "browserscale-ts/browser";
|
|
|
194
251
|
| --- | --- |
|
|
195
252
|
| **browserscale-ts** (you are here) | The TypeScript SDK (Node.js + browser). |
|
|
196
253
|
| [**browserscale-go**](https://github.com/browserscale/browserscale-go) | The Go SDK. |
|
|
197
|
-
| [**browserscale
|
|
254
|
+
| [**browserscale**](https://github.com/browserscale/browserscale) | The CLI: `browserscale init` scaffolds a runnable automation module (Go), `dev` builds and streams it, `list`/`rent`/`view`/`stop` manage your cloud browsers. |
|
|
198
255
|
| [**browserscale-kit**](https://github.com/browserscale/browserscale-kit) | Go toolkit around the browser: config, store, queues, proxies, logging, mail. |
|
|
256
|
+
| [**MCP server**](https://mcp.browserscale.cloud/mcp) | The browser as tools for any MCP client, one-to-one with the SDK. |
|
|
199
257
|
|
|
200
258
|
## License
|
|
201
259
|
|
package/dist/browser.js
CHANGED
|
@@ -6,7 +6,7 @@ export { WebSocketTransport } from "./ws-transport.js";
|
|
|
6
6
|
export { BrowserConfig } from "./config.js";
|
|
7
7
|
// Locator + constructors + AllFrames sentinel
|
|
8
8
|
export { Locator, css, js, node, at, AllFrames } from "./locator.js";
|
|
9
|
-
//
|
|
9
|
+
// Server-side defaults, re-exported for reference only (all deprecated)
|
|
10
10
|
export { DefaultWaitTimeoutMs, DefaultVisible, DefaultSteadyMs, } from "./defaults.js";
|
|
11
11
|
// Errors — base class plus the typed semantic-failure subclasses
|
|
12
12
|
export { BrowserScaleError, ClickError, FillError, DragError, ScrollError, MoveError, SelectOptionError, WaitError, } from "./errors.js";
|