nothing-browser 0.0.19 → 0.0.20
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/LICENSE +20 -20
- package/README.md +253 -253
- package/dist/launch/detect.js +0 -8
- package/dist/launch/spawn.js +0 -8
- package/dist/piggy/launch/detect.d.ts +1 -1
- package/dist/piggy/launch/detect.d.ts.map +1 -1
- package/dist/piggy/register/index.d.ts.map +1 -1
- package/dist/piggy.d.ts +0 -1
- package/dist/piggy.d.ts.map +1 -1
- package/dist/piggy.js +14 -11
- package/dist/register/index.js +14 -3
- package/nothing_browser_pig_pink.svg +58 -58
- package/package.json +4 -3
- package/piggy/cache/memory.d.ts +6 -6
- package/piggy/cache/memory.ts +37 -37
- package/piggy/client/index.d.ts +78 -78
- package/piggy/client/index.ts +567 -567
- package/piggy/human/index.d.ts +6 -6
- package/piggy/human/index.ts +52 -52
- package/piggy/intercept/scripts.d.ts +12 -12
- package/piggy/intercept/scripts.ts +152 -152
- package/piggy/launch/detect.d.ts +2 -2
- package/piggy/launch/detect.ts +42 -51
- package/piggy/launch/spawn.d.ts +5 -5
- package/piggy/launch/spawn.ts +164 -164
- package/piggy/logger/index.d.ts +2 -2
- package/piggy/logger/index.ts +58 -58
- package/piggy/open/index.d.ts +3 -3
- package/piggy/open/index.ts +4 -4
- package/piggy/pool/index.d.ts +11 -11
- package/piggy/pool/index.ts +74 -74
- package/piggy/register/index.d.ts +6 -6
- package/piggy/register/index.ts +517 -506
- package/piggy/server/index.d.ts +57 -57
- package/piggy/server/index.ts +189 -189
- package/piggy/store/index.d.ts +25 -25
- package/piggy/store/index.ts +229 -229
- package/piggy.ts +216 -221
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 BunElysiaReact
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BunElysiaReact
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,254 +1,254 @@
|
|
|
1
|
-
# `nothing-browser`
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img src="nothing_browser_pig_pink.svg" width="160" alt="Nothing Browser logo"/>
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
<h1 align="center">nothing-browser</h1>
|
|
8
|
-
<p align="center"><em>Does nothing... except everything that matters.</em></p>
|
|
9
|
-
|
|
10
|
-
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package/nothing-browser"><img src="https://img.shields.io/npm/v/nothing-browser" alt="npm version"/></a>
|
|
12
|
-
<a href="LICENSE"><img src="https://img.shields.io/github/license/BunElysiaReact/nothing-browser" alt="license"/></a>
|
|
13
|
-
<a href="https://github.com/BunElysiaReact/nothing-browser/releases"><img src="https://img.shields.io/github/v/release/BunElysiaReact/nothing-browser" alt="releases"/></a>
|
|
14
|
-
</p>
|
|
15
|
-
|
|
16
|
-
**A scraper-first headless browser library** powered by the Nothing Browser Qt6/Chromium engine. Control real browser tabs, intercept network traffic, spoof fingerprints, capture WebSockets — all from Bun + TypeScript.
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import piggy from "nothing-browser";
|
|
20
|
-
|
|
21
|
-
await piggy.launch();
|
|
22
|
-
await piggy.register("books", "https://books.toscrape.com");
|
|
23
|
-
await piggy.books.navigate();
|
|
24
|
-
|
|
25
|
-
const books = await piggy.books.evaluate(() =>
|
|
26
|
-
Array.from(document.querySelectorAll(".product_pod")).map(el => ({
|
|
27
|
-
title: el.querySelector("h3 a")?.getAttribute("title") ?? "",
|
|
28
|
-
price: el.querySelector(".price_color")?.textContent?.trim() ?? "",
|
|
29
|
-
}))
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
console.log(books);
|
|
33
|
-
await piggy.close();
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
> **📚 Full documentation is available here:**
|
|
37
|
-
> [https://nothing-browser-docs.pages.dev/guide/piggy/quickstart](https://nothing-browser-docs.pages.dev/guide/piggy/quickstart)
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Why nothing-browser?
|
|
42
|
-
|
|
43
|
-
| | nothing-browser | Puppeteer | Playwright |
|
|
44
|
-
|------------------------|----------------|-----------|------------|
|
|
45
|
-
| Imports | **1** | 5–10 | 5–10 |
|
|
46
|
-
| Lines to scrape a site | **~20** | 80–200 | 80–200 |
|
|
47
|
-
| Fingerprint spoofing | ✅ built in | ❌ plugin | ❌ plugin |
|
|
48
|
-
| Network capture | ✅ built in | ❌ manual | ❌ manual |
|
|
49
|
-
| Built-in API server | ✅ | ❌ | ❌ |
|
|
50
|
-
| Cloudflare bypass | ✅ passes | ⚠️ often blocked | ⚠️ often blocked |
|
|
51
|
-
| **Browser → Node.js RPC** | ✅ **`exposeFunction`** | ✅ `page.exposeFunction` | ✅ `page.exposeFunction` |
|
|
52
|
-
|
|
53
|
-
One import. No 47 plugins to avoid detection. Just write your scraper and go.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Requirements
|
|
58
|
-
|
|
59
|
-
- **[Bun](https://bun.sh) ≥ 1.0**
|
|
60
|
-
- A **Nothing Browser binary** placed in your **project root** (see [Binaries](#binaries))
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Binaries
|
|
65
|
-
|
|
66
|
-
Download the correct binary from **[GitHub Releases](https://github.com/BunElysiaReact/nothing-browser/releases)**.
|
|
67
|
-
|
|
68
|
-
| Binary | What it is | Where it goes |
|
|
69
|
-
|--------|-----------|---------------|
|
|
70
|
-
| `nothing-browser` | Full UI browser app (DevTools, YouTube, Plugins) | Install system-wide |
|
|
71
|
-
| `nothing-browser-headless` | No window, no GPU – for automated scraping | **Your project root** |
|
|
72
|
-
| `nothing-browser-headful` | Visible window, script-controlled – for debugging | **Your project root** |
|
|
73
|
-
|
|
74
|
-
The library communicates with the binary in your project root over a local socket.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Install
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
bun add nothing-browser
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Then download the binary and place it in your project root.
|
|
85
|
-
|
|
86
|
-
<details>
|
|
87
|
-
<summary><strong>Linux</strong></summary>
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
# Headless (most common for scraping)
|
|
91
|
-
tar -xzf nothing-browser-headless-*-linux-x86_64.tar.gz
|
|
92
|
-
chmod +x nothing-browser-headless
|
|
93
|
-
|
|
94
|
-
# Headful (visible window)
|
|
95
|
-
tar -xzf nothing-browser-headful-*-linux-x86_64.tar.gz
|
|
96
|
-
chmod +x nothing-browser-headful
|
|
97
|
-
|
|
98
|
-
# Full browser (system-wide)
|
|
99
|
-
sudo dpkg -i nothing-browser_*_amd64.deb
|
|
100
|
-
```
|
|
101
|
-
</details>
|
|
102
|
-
|
|
103
|
-
<details>
|
|
104
|
-
<summary><strong>Windows</strong></summary>
|
|
105
|
-
|
|
106
|
-
Download the `.zip` → extract → place `.exe` in your project root.
|
|
107
|
-
</details>
|
|
108
|
-
|
|
109
|
-
<details>
|
|
110
|
-
<summary><strong>macOS</strong></summary>
|
|
111
|
-
|
|
112
|
-
Download the `.tar.gz` → extract → place binary in your project root.
|
|
113
|
-
</details>
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## Headless vs Headful
|
|
118
|
-
|
|
119
|
-
```ts
|
|
120
|
-
// Headless – no display, runs anywhere (default)
|
|
121
|
-
await piggy.launch({ mode: "tab", binary: "headless" });
|
|
122
|
-
|
|
123
|
-
// Headful – visible window for debugging
|
|
124
|
-
await piggy.launch({ mode: "tab", binary: "headful" });
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Switching is just changing one word.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Key Features (with Examples)
|
|
132
|
-
|
|
133
|
-
### 🔥 Browser → Node.js RPC (`exposeFunction`)
|
|
134
|
-
|
|
135
|
-
Call Node.js functions directly from browser JavaScript.
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
await piggy.whatsapp.exposeFunction("onNewMessage", async (message) => {
|
|
139
|
-
await db.messages.insert(message);
|
|
140
|
-
return { saved: true, id: crypto.randomUUID() };
|
|
141
|
-
});
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### 📡 Request Interception
|
|
145
|
-
|
|
146
|
-
Block, redirect, or serve custom responses.
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
await piggy.app.intercept.respond("*/api/users*", async () => ({
|
|
150
|
-
status: 200,
|
|
151
|
-
body: JSON.stringify([{ id: 1, name: "Cached User" }])
|
|
152
|
-
}));
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### 🧠 Human Mode
|
|
156
|
-
|
|
157
|
-
Add random delays, typos, and natural scrolling.
|
|
158
|
-
|
|
159
|
-
```ts
|
|
160
|
-
piggy.actHuman(true);
|
|
161
|
-
await piggy.books.click(".product_pod h3 a");
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### 💾 Session Persistence
|
|
165
|
-
|
|
166
|
-
Save and restore cookies, storage, and state.
|
|
167
|
-
|
|
168
|
-
```ts
|
|
169
|
-
await piggy.site.session.export(); // save
|
|
170
|
-
await piggy.site.session.import(data); // restore
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### 🚀 Built‑in API Server
|
|
174
|
-
|
|
175
|
-
Turn your scraper into a REST API.
|
|
176
|
-
|
|
177
|
-
```ts
|
|
178
|
-
piggy.books.api("/list", async () => ({ books }));
|
|
179
|
-
await piggy.serve(3000);
|
|
180
|
-
// GET http://localhost:3000/books/list
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
> **For many more examples** (WebSocket capture, multi‑site scraping, PDF/screenshot, middleware, etc.), see the **[full documentation](https://nothing-browser-docs.pages.dev/guide/piggy/quickstart)**.
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## API Reference (Quick)
|
|
188
|
-
|
|
189
|
-
### Core
|
|
190
|
-
|
|
191
|
-
| Method | Description |
|
|
192
|
-
|--------|-------------|
|
|
193
|
-
| `piggy.launch(opts?)` | Start browser (`mode`, `binary`) |
|
|
194
|
-
| `piggy.register(name, url)` | Register a site → `piggy.<name>` |
|
|
195
|
-
| `piggy.actHuman(enable)` | Enable human‑like timing |
|
|
196
|
-
| `piggy.expose(name, handler)` | Global RPC function |
|
|
197
|
-
| `piggy.serve(port)` | Start API server |
|
|
198
|
-
| `piggy.close(opts?)` | Close gracefully or force |
|
|
199
|
-
|
|
200
|
-
### Site Methods
|
|
201
|
-
|
|
202
|
-
| Category | Methods |
|
|
203
|
-
|----------|---------|
|
|
204
|
-
| **Navigation** | `navigate()`, `reload()`, `goBack()`, `goForward()`, `waitForSelector()` |
|
|
205
|
-
| **Interactions** | `click()`, `type()`, `hover()`, `select()`, `keyboard.press()`, `scroll.to()` |
|
|
206
|
-
| **Data** | `evaluate()`, `fetchText()`, `fetchLinks()`, `fetchImages()` |
|
|
207
|
-
| **RPC** | `exposeFunction()`, `unexposeFunction()`, `exposeAndInject()` |
|
|
208
|
-
| **Network** | `capture.start()`, `intercept.respond()`, `intercept.modifyResponse()`, `blockImages()` |
|
|
209
|
-
| **Session** | `cookies.set()`, `session.export()`, `session.import()` |
|
|
210
|
-
| **Output** | `screenshot()`, `pdf()` |
|
|
211
|
-
|
|
212
|
-
> **Full API reference:** [https://nothing-browser-docs.pages.dev/guide/piggy/api-reference](https://nothing-browser-docs.pages.dev/guide/piggy/api-reference)
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## How `exposeFunction` Works
|
|
217
|
-
|
|
218
|
-
1. Browser injects a Promise‑returning stub into `window.fnName`.
|
|
219
|
-
2. Calls are queued to `__NOTHING_QUEUE__`.
|
|
220
|
-
3. C++ polls the queue (every 250ms) and sends the call via socket.
|
|
221
|
-
4. Your Node.js handler runs.
|
|
222
|
-
5. The result is sent back and the browser’s Promise resolves.
|
|
223
|
-
|
|
224
|
-
The function survives page navigations (injected at `DocumentCreation`) and works in both tab and process modes.
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Binary Download Links
|
|
229
|
-
|
|
230
|
-
| Platform | Headless | Headful | Full Browser |
|
|
231
|
-
|----------|----------|---------|--------------|
|
|
232
|
-
| Linux x86_64 (deb) | `nothing-browser-headless_*_amd64.deb` | `nothing-browser-headful_*_amd64.deb` | `nothing-browser_*_amd64.deb` |
|
|
233
|
-
| Linux x86_64 (tar.gz) | `nothing-browser-headless-*-linux-x86_64.tar.gz` | `nothing-browser-headful-*-linux-x86_64.tar.gz` | `nothing-browser-*-linux-x86_64.tar.gz` |
|
|
234
|
-
| Windows x64 | `nothing-browser-headless-*-windows-x64.zip` | `nothing-browser-headful-*-windows-x64.zip` | `nothing-browser-*-windows-x64.zip` |
|
|
235
|
-
| macOS | `nothing-browser-headless-*-macos.tar.gz` | `nothing-browser-headful-*-macos.tar.gz` | `nothing-browser-*-macos.dmg` |
|
|
236
|
-
|
|
237
|
-
➡️ **[All releases on GitHub](https://github.com/BunElysiaReact/nothing-browser/releases)**
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## Contributing & Security
|
|
242
|
-
|
|
243
|
-
- **Contributing:** See the [Contributing Guide](https://nothing-browser-docs.pages.dev/guide/community/contributing)
|
|
244
|
-
- **Security issues:** Email `ernesttechhouse@gmail.com` (not a public issue)
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## License
|
|
249
|
-
|
|
250
|
-
MIT © [Ernest Tech House](https://github.com/BunElysiaReact/nothing-browser)
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
1
|
+
# `nothing-browser`
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="nothing_browser_pig_pink.svg" width="160" alt="Nothing Browser logo"/>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">nothing-browser</h1>
|
|
8
|
+
<p align="center"><em>Does nothing... except everything that matters.</em></p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://www.npmjs.com/package/nothing-browser"><img src="https://img.shields.io/npm/v/nothing-browser" alt="npm version"/></a>
|
|
12
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/BunElysiaReact/nothing-browser" alt="license"/></a>
|
|
13
|
+
<a href="https://github.com/BunElysiaReact/nothing-browser/releases"><img src="https://img.shields.io/github/v/release/BunElysiaReact/nothing-browser" alt="releases"/></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
**A scraper-first headless browser library** powered by the Nothing Browser Qt6/Chromium engine. Control real browser tabs, intercept network traffic, spoof fingerprints, capture WebSockets — all from Bun + TypeScript.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import piggy from "nothing-browser";
|
|
20
|
+
|
|
21
|
+
await piggy.launch();
|
|
22
|
+
await piggy.register("books", "https://books.toscrape.com");
|
|
23
|
+
await piggy.books.navigate();
|
|
24
|
+
|
|
25
|
+
const books = await piggy.books.evaluate(() =>
|
|
26
|
+
Array.from(document.querySelectorAll(".product_pod")).map(el => ({
|
|
27
|
+
title: el.querySelector("h3 a")?.getAttribute("title") ?? "",
|
|
28
|
+
price: el.querySelector(".price_color")?.textContent?.trim() ?? "",
|
|
29
|
+
}))
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
console.log(books);
|
|
33
|
+
await piggy.close();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
> **📚 Full documentation is available here:**
|
|
37
|
+
> [https://nothing-browser-docs.pages.dev/guide/piggy/quickstart](https://nothing-browser-docs.pages.dev/guide/piggy/quickstart)
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Why nothing-browser?
|
|
42
|
+
|
|
43
|
+
| | nothing-browser | Puppeteer | Playwright |
|
|
44
|
+
|------------------------|----------------|-----------|------------|
|
|
45
|
+
| Imports | **1** | 5–10 | 5–10 |
|
|
46
|
+
| Lines to scrape a site | **~20** | 80–200 | 80–200 |
|
|
47
|
+
| Fingerprint spoofing | ✅ built in | ❌ plugin | ❌ plugin |
|
|
48
|
+
| Network capture | ✅ built in | ❌ manual | ❌ manual |
|
|
49
|
+
| Built-in API server | ✅ | ❌ | ❌ |
|
|
50
|
+
| Cloudflare bypass | ✅ passes | ⚠️ often blocked | ⚠️ often blocked |
|
|
51
|
+
| **Browser → Node.js RPC** | ✅ **`exposeFunction`** | ✅ `page.exposeFunction` | ✅ `page.exposeFunction` |
|
|
52
|
+
|
|
53
|
+
One import. No 47 plugins to avoid detection. Just write your scraper and go.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- **[Bun](https://bun.sh) ≥ 1.0**
|
|
60
|
+
- A **Nothing Browser binary** placed in your **project root** (see [Binaries](#binaries))
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Binaries
|
|
65
|
+
|
|
66
|
+
Download the correct binary from **[GitHub Releases](https://github.com/BunElysiaReact/nothing-browser/releases)**.
|
|
67
|
+
|
|
68
|
+
| Binary | What it is | Where it goes |
|
|
69
|
+
|--------|-----------|---------------|
|
|
70
|
+
| `nothing-browser` | Full UI browser app (DevTools, YouTube, Plugins) | Install system-wide |
|
|
71
|
+
| `nothing-browser-headless` | No window, no GPU – for automated scraping | **Your project root** |
|
|
72
|
+
| `nothing-browser-headful` | Visible window, script-controlled – for debugging | **Your project root** |
|
|
73
|
+
|
|
74
|
+
The library communicates with the binary in your project root over a local socket.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bun add nothing-browser
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then download the binary and place it in your project root.
|
|
85
|
+
|
|
86
|
+
<details>
|
|
87
|
+
<summary><strong>Linux</strong></summary>
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Headless (most common for scraping)
|
|
91
|
+
tar -xzf nothing-browser-headless-*-linux-x86_64.tar.gz
|
|
92
|
+
chmod +x nothing-browser-headless
|
|
93
|
+
|
|
94
|
+
# Headful (visible window)
|
|
95
|
+
tar -xzf nothing-browser-headful-*-linux-x86_64.tar.gz
|
|
96
|
+
chmod +x nothing-browser-headful
|
|
97
|
+
|
|
98
|
+
# Full browser (system-wide)
|
|
99
|
+
sudo dpkg -i nothing-browser_*_amd64.deb
|
|
100
|
+
```
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary><strong>Windows</strong></summary>
|
|
105
|
+
|
|
106
|
+
Download the `.zip` → extract → place `.exe` in your project root.
|
|
107
|
+
</details>
|
|
108
|
+
|
|
109
|
+
<details>
|
|
110
|
+
<summary><strong>macOS</strong></summary>
|
|
111
|
+
|
|
112
|
+
Download the `.tar.gz` → extract → place binary in your project root.
|
|
113
|
+
</details>
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Headless vs Headful
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// Headless – no display, runs anywhere (default)
|
|
121
|
+
await piggy.launch({ mode: "tab", binary: "headless" });
|
|
122
|
+
|
|
123
|
+
// Headful – visible window for debugging
|
|
124
|
+
await piggy.launch({ mode: "tab", binary: "headful" });
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Switching is just changing one word.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Key Features (with Examples)
|
|
132
|
+
|
|
133
|
+
### 🔥 Browser → Node.js RPC (`exposeFunction`)
|
|
134
|
+
|
|
135
|
+
Call Node.js functions directly from browser JavaScript.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
await piggy.whatsapp.exposeFunction("onNewMessage", async (message) => {
|
|
139
|
+
await db.messages.insert(message);
|
|
140
|
+
return { saved: true, id: crypto.randomUUID() };
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 📡 Request Interception
|
|
145
|
+
|
|
146
|
+
Block, redirect, or serve custom responses.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
await piggy.app.intercept.respond("*/api/users*", async () => ({
|
|
150
|
+
status: 200,
|
|
151
|
+
body: JSON.stringify([{ id: 1, name: "Cached User" }])
|
|
152
|
+
}));
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 🧠 Human Mode
|
|
156
|
+
|
|
157
|
+
Add random delays, typos, and natural scrolling.
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
piggy.actHuman(true);
|
|
161
|
+
await piggy.books.click(".product_pod h3 a");
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 💾 Session Persistence
|
|
165
|
+
|
|
166
|
+
Save and restore cookies, storage, and state.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
await piggy.site.session.export(); // save
|
|
170
|
+
await piggy.site.session.import(data); // restore
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 🚀 Built‑in API Server
|
|
174
|
+
|
|
175
|
+
Turn your scraper into a REST API.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
piggy.books.api("/list", async () => ({ books }));
|
|
179
|
+
await piggy.serve(3000);
|
|
180
|
+
// GET http://localhost:3000/books/list
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> **For many more examples** (WebSocket capture, multi‑site scraping, PDF/screenshot, middleware, etc.), see the **[full documentation](https://nothing-browser-docs.pages.dev/guide/piggy/quickstart)**.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## API Reference (Quick)
|
|
188
|
+
|
|
189
|
+
### Core
|
|
190
|
+
|
|
191
|
+
| Method | Description |
|
|
192
|
+
|--------|-------------|
|
|
193
|
+
| `piggy.launch(opts?)` | Start browser (`mode`, `binary`) |
|
|
194
|
+
| `piggy.register(name, url)` | Register a site → `piggy.<name>` |
|
|
195
|
+
| `piggy.actHuman(enable)` | Enable human‑like timing |
|
|
196
|
+
| `piggy.expose(name, handler)` | Global RPC function |
|
|
197
|
+
| `piggy.serve(port)` | Start API server |
|
|
198
|
+
| `piggy.close(opts?)` | Close gracefully or force |
|
|
199
|
+
|
|
200
|
+
### Site Methods
|
|
201
|
+
|
|
202
|
+
| Category | Methods |
|
|
203
|
+
|----------|---------|
|
|
204
|
+
| **Navigation** | `navigate()`, `reload()`, `goBack()`, `goForward()`, `waitForSelector()` |
|
|
205
|
+
| **Interactions** | `click()`, `type()`, `hover()`, `select()`, `keyboard.press()`, `scroll.to()` |
|
|
206
|
+
| **Data** | `evaluate()`, `fetchText()`, `fetchLinks()`, `fetchImages()` |
|
|
207
|
+
| **RPC** | `exposeFunction()`, `unexposeFunction()`, `exposeAndInject()` |
|
|
208
|
+
| **Network** | `capture.start()`, `intercept.respond()`, `intercept.modifyResponse()`, `blockImages()` |
|
|
209
|
+
| **Session** | `cookies.set()`, `session.export()`, `session.import()` |
|
|
210
|
+
| **Output** | `screenshot()`, `pdf()` |
|
|
211
|
+
|
|
212
|
+
> **Full API reference:** [https://nothing-browser-docs.pages.dev/guide/piggy/api-reference](https://nothing-browser-docs.pages.dev/guide/piggy/api-reference)
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## How `exposeFunction` Works
|
|
217
|
+
|
|
218
|
+
1. Browser injects a Promise‑returning stub into `window.fnName`.
|
|
219
|
+
2. Calls are queued to `__NOTHING_QUEUE__`.
|
|
220
|
+
3. C++ polls the queue (every 250ms) and sends the call via socket.
|
|
221
|
+
4. Your Node.js handler runs.
|
|
222
|
+
5. The result is sent back and the browser’s Promise resolves.
|
|
223
|
+
|
|
224
|
+
The function survives page navigations (injected at `DocumentCreation`) and works in both tab and process modes.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Binary Download Links
|
|
229
|
+
|
|
230
|
+
| Platform | Headless | Headful | Full Browser |
|
|
231
|
+
|----------|----------|---------|--------------|
|
|
232
|
+
| Linux x86_64 (deb) | `nothing-browser-headless_*_amd64.deb` | `nothing-browser-headful_*_amd64.deb` | `nothing-browser_*_amd64.deb` |
|
|
233
|
+
| Linux x86_64 (tar.gz) | `nothing-browser-headless-*-linux-x86_64.tar.gz` | `nothing-browser-headful-*-linux-x86_64.tar.gz` | `nothing-browser-*-linux-x86_64.tar.gz` |
|
|
234
|
+
| Windows x64 | `nothing-browser-headless-*-windows-x64.zip` | `nothing-browser-headful-*-windows-x64.zip` | `nothing-browser-*-windows-x64.zip` |
|
|
235
|
+
| macOS | `nothing-browser-headless-*-macos.tar.gz` | `nothing-browser-headful-*-macos.tar.gz` | `nothing-browser-*-macos.dmg` |
|
|
236
|
+
|
|
237
|
+
➡️ **[All releases on GitHub](https://github.com/BunElysiaReact/nothing-browser/releases)**
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Contributing & Security
|
|
242
|
+
|
|
243
|
+
- **Contributing:** See the [Contributing Guide](https://nothing-browser-docs.pages.dev/guide/community/contributing)
|
|
244
|
+
- **Security issues:** Email `ernesttechhouse@gmail.com` (not a public issue)
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT © [Ernest Tech House](https://github.com/BunElysiaReact/nothing-browser)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
254
|
*Part of the [Nothing Ecosystem](https://nothing-browser-docs.pages.dev). Built in Kenya 🇰🇪*
|
package/dist/launch/detect.js
CHANGED
|
@@ -739,14 +739,6 @@ var BINARY_NAMES = {
|
|
|
739
739
|
headful: "nothing-browser-headful"
|
|
740
740
|
};
|
|
741
741
|
function detectBinary(mode = "headless") {
|
|
742
|
-
if (mode !== "headless" && mode !== "headful") {
|
|
743
|
-
if (existsSync(mode)) {
|
|
744
|
-
logger_default.success(`Binary found (custom path): ${mode}`);
|
|
745
|
-
return mode;
|
|
746
|
-
}
|
|
747
|
-
logger_default.error(`❌ Binary not found at custom path: ${mode}`);
|
|
748
|
-
return null;
|
|
749
|
-
}
|
|
750
742
|
const cwd = process.cwd();
|
|
751
743
|
const name = BINARY_NAMES[mode];
|
|
752
744
|
if (process.platform === "win32") {
|
package/dist/launch/spawn.js
CHANGED
|
@@ -744,14 +744,6 @@ var BINARY_NAMES = {
|
|
|
744
744
|
headful: "nothing-browser-headful"
|
|
745
745
|
};
|
|
746
746
|
function detectBinary(mode = "headless") {
|
|
747
|
-
if (mode !== "headless" && mode !== "headful") {
|
|
748
|
-
if (existsSync(mode)) {
|
|
749
|
-
logger_default.success(`Binary found (custom path): ${mode}`);
|
|
750
|
-
return mode;
|
|
751
|
-
}
|
|
752
|
-
logger_default.error(`❌ Binary not found at custom path: ${mode}`);
|
|
753
|
-
return null;
|
|
754
|
-
}
|
|
755
747
|
const cwd = process.cwd();
|
|
756
748
|
const name = BINARY_NAMES[mode];
|
|
757
749
|
if (process.platform === "win32") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../piggy/launch/detect.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../piggy/launch/detect.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAOhD,wBAAgB,YAAY,CAAC,IAAI,GAAE,UAAuB,GAAG,MAAM,GAAG,IAAI,CA+BzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../piggy/register/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAMxC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,eAAO,IAAI,SAAS,SAAQ,CAAC;AAE7B,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,QAAuB;AACtE,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,QAAoB;AAgB3D,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../piggy/register/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAMxC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,eAAO,IAAI,SAAS,SAAQ,CAAC;AAE7B,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,QAAuB;AACtE,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,QAAoB;AAgB3D,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,OAAO,OAkdf;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC,EAC3E,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,GACV,OAAO,CAAC,IAAI,CAAC,CASf"}
|
package/dist/piggy.d.ts
CHANGED
package/dist/piggy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"piggy.d.ts","sourceRoot":"","sources":["../piggy.ts"],"names":[],"mappings":"AAIA,OAAO,EAA6C,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"piggy.d.ts","sourceRoot":"","sources":["../piggy.ts"],"names":[],"mappings":"AAIA,OAAO,EAA6C,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY9F,QAAA,MAAM,KAAK,EAAE,GAwLZ,CAAC;AAMF,KAAK,UAAU,CAAC,KAAK,SAAS,MAAM,IAAI,OAAO,KAAK,GAAG;KACpD,CAAC,IAAI,KAAK,GAAG,UAAU;CACzB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,SAAS,MAAM,KAAK,UAAU,CAAC,KAAK,CAAC,CAElE;AAED,YAAY,EAAE,UAAU,EAAE,CAAC;AAC3B,eAAe,KAAK,CAAC;AACrB,OAAO,EAAE,KAAK,EAAE,CAAC"}
|