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 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
- Rent an isolated browser session in seconds, automate it with human-like input, intercept network traffic, solve captchas, and watch a live video stream of everything your script does. Runs in Node.js and the browser.
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
  [![npm](https://img.shields.io/npm/v/browserscale-ts?logo=npm)](https://www.npmjs.com/package/browserscale-ts)
10
10
  ![Node](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js&logoColor=white)
@@ -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
- - **Real browser sessions as a service** — full Chromium in the cloud with
23
- pages, frames, cookies, storage and network state. No local binary.
24
- - **Parallel isolated contexts** — each task gets its own session, fingerprint
25
- and lifecycle; large queues never share browser state. Sessions are browser
26
- contexts, not VMs or processes, so they spin up in under 250 ms and fan out to
27
- thousands in parallel.
28
- - **Fingerprint & proxy handling** — pinnable server-side fingerprints,
29
- native Chrome control without CDP/Playwright/Puppeteer leaks, bring your own
30
- proxy or let browserscale allocate one.
31
- - **Native engine-level control** — automation runs natively inside Chromium
32
- itself, not from outside over the DevTools protocol. Nothing is injected, no
33
- `Runtime.enable`, no DevTools handshake — page JS can't observe it. Waits run
34
- fully async with no polling loop, and built-in steady-time checks only report
35
- an element once it's stable in the DOM.
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` in one tree, no flattened sessions or
38
- per-frame execution-context juggling. `wait`/`click` act across all frames or
39
- a single iframe, and `wait` returns the `frameId` that matched.
40
- - **Human-like interaction** — mouse paths use browserscale's own movement algorithm
41
- instead of instant synthetic jumps.
42
- - **WebRTC live video stream** — watch and control the rented browser live
43
- from the browserscale web interface; mouse and keyboard go back over data channels.
44
- - **Captcha support, no third-party solvers** — passive anti-bot checks are
45
- handled automatically; interactive challenges are solved with `solveCaptcha`
46
- by browserscale's own AI solver, which learns the known challenge types — puzzle,
47
- OCR, slide, hold and more — on its own and keeps improving as they evolve.
48
- No token is ever synthesized or fetched from an external API: the challenge
49
- is completed in the valid live browser and the provider's own JavaScript
50
- issues the token itself — which is why even new or unknown protections
51
- pass.
52
- - **Real hardware, real GPUs** — sessions run hardware-accelerated on real
53
- consumer GPUs, not on VM cores with a WebGL faking layer. Canvas and WebGL
54
- readbacks (`toDataURL`, `getImageData`) return genuinely rendered pixels —
55
- no spoofing layer or fingerprint hash database for new bot protections to
56
- unmask.
57
- - **Network control at the source** — interception sits in the browser's
58
- network stack itself, so every request from every frame (including
59
- cross-origin OOPIFs) passes through it; no handler races, nothing slips
60
- through. Wait for, block, mock or modify requests and responses without
61
- leaving the SDK; mark repeated assets as static with `setStaticPaths` to
62
- serve them from a server-side cache and cut proxy bandwidth on repeat runs.
63
- - **Streaming network capture** — `captureNetwork` reports every request the
64
- session completes as it happens, and "every request" is literal: capture sits
65
- in the browser process rather than in a page, so cross-process iframes,
66
- workers and service workers are included, the headers are the ones actually
67
- put on the wire, and each hop of a redirect chain arrives as its own exchange.
68
- Requests are never paused, so the page loads at full speed.
69
- - **Live DOM mirror** — `mirrorDom` holds the page as one incrementally updated
70
- tree: the browser sends the top once and from then on only what changed in the
71
- part you expanded, so a page churning inside a collapsed subtree costs one
72
- number per batch instead of a re-serialized document. An `<iframe>` is an
73
- ordinary element whose one child is the document it hosts, however deeply
74
- nested or cross-origin, and `getDomRevision` is the O(1) change detector to
75
- poll when you are not consuming events.
76
- - **Agent-friendly observation** — `getObservation` returns one line per visible
77
- element across every frame, under headers carrying the URL, title and scroll
78
- offset, with live form state (typed values, checkbox state, `<select>`
79
- options) and a node handle to act on. A model reasons over what matters
80
- instead of raw HTML, and doesn't need a JS round-trip to ask where it is.
81
- - **Scripts that run inside the browser** — `runScript` sends JavaScript to the
82
- session and runs it in the browser process itself, with a `browser` object
83
- giving it the same operations this SDK exposes — but as local calls rather than
84
- network round trips, so a loop that polls or walks a list costs microseconds
85
- per step instead of tens of milliseconds. The log streams back as the script
86
- produces it. `startScript` leaves a script running without the caller, which is
87
- how work outlives the process that started it, and `followScript` attaches to
88
- one already under way.
89
- - **Sessions you can find again** — `listBrowsers` reports what an API key is
90
- paying for: ids, proxy, egress address and remaining rental. A session
91
- therefore outlives the process that rented it — recover it after a restart, or
92
- from another machine entirely, and hand the `grpcUrl` it reports straight to
93
- `connectSession`.
94
- - **Flow-optimized TypeScript** — fully typed promise-based API, `wait` races
95
- multiple outcomes, JS locators target elements by page logic when CSS is
96
- not enough. Runs in Node.js (native gRPC) and the browser (WebSocket via
97
- `browserscale-ts/browser`).
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 in the browser process, where every operation is a local call; `startScript` leaves it running, `followScript` watches one already going. |
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-cli**](https://github.com/browserscale/browserscale-cli) | `browserscale init` — scaffold a runnable automation module (Go). |
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
- // Defaults the SDK applies before sending a request
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";