@blitzbrowser/blitzbrowser 1.1.3 β 1.1.5
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/.github/workflows/cicd.yml +11 -1
- package/README.md +61 -1
- package/assets/logo-white.png +0 -0
- package/assets/logo.png +0 -0
- package/dist/controllers/cdp.controller.d.ts +2 -0
- package/dist/controllers/cdp.controller.js +36 -4
- package/dist/controllers/cdp.controller.js.map +1 -1
- package/dist/errors/max-browser-reached.error.d.ts +2 -0
- package/dist/errors/max-browser-reached.error.js +7 -0
- package/dist/errors/max-browser-reached.error.js.map +1 -0
- package/dist/main.js +8 -0
- package/dist/main.js.map +1 -1
- package/dist/services/browser-pool.service.js +5 -1
- package/dist/services/browser-pool.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -1
- package/src/controllers/cdp.controller.ts +41 -4
- package/src/errors/max-browser-reached.error.ts +3 -0
- package/src/main.ts +10 -0
- package/src/services/browser-pool.service.ts +6 -1
|
@@ -4,7 +4,8 @@ on:
|
|
|
4
4
|
|
|
5
5
|
permissions:
|
|
6
6
|
id-token: write
|
|
7
|
-
contents:
|
|
7
|
+
contents: write
|
|
8
|
+
packages: write
|
|
8
9
|
|
|
9
10
|
jobs:
|
|
10
11
|
publish:
|
|
@@ -24,6 +25,15 @@ jobs:
|
|
|
24
25
|
- run: pnpm publish --access public --no-git-checks
|
|
25
26
|
- id: package_version
|
|
26
27
|
run: echo "VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
|
|
28
|
+
- uses: actions/github-script@v8
|
|
29
|
+
with:
|
|
30
|
+
script: |
|
|
31
|
+
github.rest.git.createRef({
|
|
32
|
+
owner: context.repo.owner,
|
|
33
|
+
repo: context.repo.repo,
|
|
34
|
+
ref: 'refs/tags/${{ steps.package_version.outputs.VERSION }}',
|
|
35
|
+
sha: context.sha
|
|
36
|
+
})
|
|
27
37
|
- uses: docker/login-action@v3
|
|
28
38
|
with:
|
|
29
39
|
registry: ghcr.io
|
package/README.md
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://blitzbrowser.com/" align="center">
|
|
3
|
+
<center align="center">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="./assets/logo-white.png" width="300">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" srcset="./assets/logo.png" width="300">
|
|
7
|
+
<img src="./assets/logo.svg" alt="BlitzBrowser logo" width="300">
|
|
8
|
+
</picture>
|
|
9
|
+
</center>
|
|
10
|
+
</a>
|
|
11
|
+
|
|
12
|
+
<h3>Deploy and manage headful browsers in docker. Run your browsers with BlitzBrowser in the cloud or self hosted.</h3>
|
|
13
|
+
|
|
14
|
+
<div>
|
|
15
|
+
<img src="https://img.shields.io/github/actions/workflow/status/blitzbrowser/blitzbrowser/cicd.yml?style=flat-square" />
|
|
16
|
+
<img src="https://img.shields.io/github/package-json/v/blitzbrowser/blitzbrowser?style=flat-square" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
## π Table of Contents
|
|
21
|
+
|
|
22
|
+
- [Features](#-features)
|
|
23
|
+
- [Quick Start](#-quick-start)
|
|
24
|
+
- [Configuration](#οΈ-configuration)
|
|
25
|
+
- [Cloud or self-hosted](#οΈ-cloud-or--self-hosted)
|
|
26
|
+
- [Support](#support)
|
|
27
|
+
|
|
28
|
+
## β¨ Features
|
|
29
|
+
|
|
30
|
+
- **Parallelism** - Run multiple browsers concurrently.
|
|
31
|
+
- **Chrome DevTools Protocol** - Connect directly from Puppeteer, Playwright and any CDP supported frameworks. No custom library needed.
|
|
32
|
+
- **User Data Storage** - Save and reuse your browsing sessions easily with S3.
|
|
33
|
+
- **Proxy** - Connect your browsers to any HTTP proxy.
|
|
34
|
+
- **Queueing** - The CDP connections are queued while the browsers are starting.
|
|
35
|
+
- **No DevOps** - Run your browsers without worrying about the infrastructure, zombie process or a script. The container manages everything for you.
|
|
2
36
|
|
|
3
37
|
## π Quick Start
|
|
4
38
|
|
|
@@ -114,3 +148,29 @@ await browser.close();
|
|
|
114
148
|
```
|
|
115
149
|
|
|
116
150
|
</details>
|
|
151
|
+
|
|
152
|
+
## βοΈ Configuration
|
|
153
|
+
|
|
154
|
+
### Environment Variables
|
|
155
|
+
|
|
156
|
+
- `PORT`: The HTTP port of the web server. The default port is `9999`.
|
|
157
|
+
- `MAX_BROWSER_INSTANCES`: The maximum number of browsers the instance can run concurrently. The default value is `99`.
|
|
158
|
+
- `S3_ENDPOINT`: The endpoint of the S3 server to use for storage.
|
|
159
|
+
- `S3_ACCESS_KEY_ID`: Access key ID to connect to the S3 server.
|
|
160
|
+
- `S3_SECRET_ACCESS_KEY`: Secret access key to connect to the S3 server.
|
|
161
|
+
- `S3_USER_DATA_BUCKET`: The S3 bucket to store the user data.
|
|
162
|
+
- `TAGS`: The tags used to identify the pool of browsers. No tags by default. The tags are in the following format `a=1,b=2,c=3`.
|
|
163
|
+
|
|
164
|
+
## βοΈ Cloud or π» self-hosted
|
|
165
|
+
|
|
166
|
+
The cloud and self-hosted versions offer the same features.
|
|
167
|
+
|
|
168
|
+
You should use the self-hosted version if you are looking to host on your own server or to test locally. It works perfectly if you are scaling vertically. 1 server to handle multiple browsers and the S3 storage for user data.
|
|
169
|
+
|
|
170
|
+
The cloud version allows you to focus on scaling your features while we handle all the infrastructure. You connect to our CDP endpoint and we will handle the scaling, the S3 storage and the proxy. No version management, no infrastructure deployment and priority support.
|
|
171
|
+
|
|
172
|
+
Our proxy is available as a standalone HTTP proxy. You don't need to use our cloud version to get access to our proxies. It works with the self-hosted version and it is really cheap!
|
|
173
|
+
|
|
174
|
+
## βSupport
|
|
175
|
+
|
|
176
|
+
To get support, you can contact us on [Discord](https://discord.com/invite/qZ3tCZJ2Ze) or at [support@blitzbrowser.com](support@blitzbrowser.com).
|
|
Binary file
|
package/assets/logo.png
ADDED
|
Binary file
|
|
@@ -9,8 +9,10 @@ export declare class CDPController implements OnModuleInit {
|
|
|
9
9
|
#private;
|
|
10
10
|
private readonly browser_pool_service;
|
|
11
11
|
private readonly http_adapter_host;
|
|
12
|
+
private static readonly WAITING_BROWSER_TIMEOUT_MS;
|
|
12
13
|
static readonly INTERNAL_SERVER_ERROR_CODE = 4000;
|
|
13
14
|
static readonly BAD_REQUEST_CODE = 4002;
|
|
15
|
+
static readonly NO_BROWSER_INSTANCE_AVAILABLE = 4003;
|
|
14
16
|
constructor(browser_pool_service: BrowserPoolService, http_adapter_host: HttpAdapterHost);
|
|
15
17
|
onModuleInit(): Promise<void>;
|
|
16
18
|
private getQueryParamValue;
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
14
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
15
|
};
|
|
16
|
-
var _CDPController_instances, _a, _CDPController_logger, _CDPController_parseConnectionOptionQueryParams;
|
|
16
|
+
var _CDPController_instances, _a, _CDPController_logger, _CDPController_getBrowserInstance, _CDPController_parseConnectionOptionQueryParams;
|
|
17
17
|
var CDPController_1;
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.CDPController = exports.USER_DATA_READ_ONLY_QUERY_PARAM = exports.USER_DATA_ID_QUERY_PARAM = exports.TIMEZONE_QUERY_PARAM = exports.PROXY_URL_QUERY_PARAM = void 0;
|
|
@@ -24,6 +24,7 @@ const browser_pool_service_1 = require("../services/browser-pool.service");
|
|
|
24
24
|
const ws_1 = require("ws");
|
|
25
25
|
const zod_1 = require("zod");
|
|
26
26
|
const tunnel_1 = require("@blitzbrowser/tunnel");
|
|
27
|
+
const max_browser_reached_error_1 = require("../errors/max-browser-reached.error");
|
|
27
28
|
exports.PROXY_URL_QUERY_PARAM = 'proxyUrl';
|
|
28
29
|
exports.TIMEZONE_QUERY_PARAM = 'timezone';
|
|
29
30
|
exports.USER_DATA_ID_QUERY_PARAM = 'userDataId';
|
|
@@ -43,7 +44,8 @@ let CDPController = CDPController_1 = _a = class CDPController {
|
|
|
43
44
|
}
|
|
44
45
|
async onModuleInit() {
|
|
45
46
|
const websocket_server = new ws_1.WebSocketServer({ server: this.http_adapter_host.httpAdapter.getHttpServer() });
|
|
46
|
-
websocket_server.on('connection', (cdp_websocket_client, req) => {
|
|
47
|
+
websocket_server.on('connection', async (cdp_websocket_client, req) => {
|
|
48
|
+
let tunnel;
|
|
47
49
|
try {
|
|
48
50
|
const url = new URL(`http://127.0.0.1${req.url}`);
|
|
49
51
|
const parsed_connection_options = __classPrivateFieldGet(this, _CDPController_instances, "m", _CDPController_parseConnectionOptionQueryParams).call(this, url);
|
|
@@ -51,8 +53,7 @@ let CDPController = CDPController_1 = _a = class CDPController {
|
|
|
51
53
|
cdp_websocket_client.close(CDPController_1.BAD_REQUEST_CODE, parsed_connection_options.error.message.trim());
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
|
-
|
|
55
|
-
const tunnel = new tunnel_1.Tunnel();
|
|
56
|
+
tunnel = new tunnel_1.Tunnel();
|
|
56
57
|
tunnel.on('message', message => {
|
|
57
58
|
if (message.channel_id === browser_instance_component_1.BrowserInstance.CDP_CHANNEL_ID) {
|
|
58
59
|
cdp_websocket_client.send(message.data.toString('utf8'), { binary: false });
|
|
@@ -64,6 +65,7 @@ let CDPController = CDPController_1 = _a = class CDPController {
|
|
|
64
65
|
cdp_websocket_client.on('message', message => {
|
|
65
66
|
tunnel.receiveMessage(tunnel_1.Message.of(browser_instance_component_1.BrowserInstance.CDP_CHANNEL_ID, message.toString('utf8')));
|
|
66
67
|
});
|
|
68
|
+
const browser_instance = await __classPrivateFieldGet(this, _CDPController_instances, "m", _CDPController_getBrowserInstance).call(this);
|
|
67
69
|
const ping_interval_id = setInterval(() => {
|
|
68
70
|
cdp_websocket_client.ping();
|
|
69
71
|
}, 3000);
|
|
@@ -84,6 +86,11 @@ let CDPController = CDPController_1 = _a = class CDPController {
|
|
|
84
86
|
__classPrivateFieldGet(this, _CDPController_logger, "f").log('Sent connection options');
|
|
85
87
|
}
|
|
86
88
|
catch (e) {
|
|
89
|
+
if (e instanceof max_browser_reached_error_1.MaxBrowserReachedError) {
|
|
90
|
+
tunnel.close();
|
|
91
|
+
cdp_websocket_client.close(CDPController_1.NO_BROWSER_INSTANCE_AVAILABLE, 'No browser instance available.');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
87
94
|
__classPrivateFieldGet(this, _CDPController_logger, "f").error(`Error while handling client websocket.`, e?.stack || e);
|
|
88
95
|
cdp_websocket_client.close(CDPController_1.INTERNAL_SERVER_ERROR_CODE, e?.stack || e);
|
|
89
96
|
return;
|
|
@@ -104,6 +111,29 @@ let CDPController = CDPController_1 = _a = class CDPController {
|
|
|
104
111
|
exports.CDPController = CDPController;
|
|
105
112
|
_CDPController_logger = new WeakMap();
|
|
106
113
|
_CDPController_instances = new WeakSet();
|
|
114
|
+
_CDPController_getBrowserInstance = async function _CDPController_getBrowserInstance() {
|
|
115
|
+
const start = Date.now();
|
|
116
|
+
while (start + CDPController_1.WAITING_BROWSER_TIMEOUT_MS > Date.now()) {
|
|
117
|
+
try {
|
|
118
|
+
const browser_instance = this.browser_pool_service.createBrowserInstance();
|
|
119
|
+
if (browser_instance) {
|
|
120
|
+
return browser_instance;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
if (e instanceof max_browser_reached_error_1.MaxBrowserReachedError) {
|
|
125
|
+
await new Promise((resolve) => {
|
|
126
|
+
setTimeout(resolve, 100);
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
throw e;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
throw new max_browser_reached_error_1.MaxBrowserReachedError();
|
|
136
|
+
};
|
|
107
137
|
_CDPController_parseConnectionOptionQueryParams = function _CDPController_parseConnectionOptionQueryParams(url) {
|
|
108
138
|
return ConnectionOptionQueryParams.safeParse({
|
|
109
139
|
timezone: this.getQueryParamValue(exports.TIMEZONE_QUERY_PARAM, url),
|
|
@@ -112,8 +142,10 @@ _CDPController_parseConnectionOptionQueryParams = function _CDPController_parseC
|
|
|
112
142
|
user_data_read_only: this.getQueryParamValue(exports.USER_DATA_READ_ONLY_QUERY_PARAM, url)?.toLowerCase() === 'true',
|
|
113
143
|
});
|
|
114
144
|
};
|
|
145
|
+
CDPController.WAITING_BROWSER_TIMEOUT_MS = 10_000;
|
|
115
146
|
CDPController.INTERNAL_SERVER_ERROR_CODE = 4000;
|
|
116
147
|
CDPController.BAD_REQUEST_CODE = 4002;
|
|
148
|
+
CDPController.NO_BROWSER_INSTANCE_AVAILABLE = 4003;
|
|
117
149
|
exports.CDPController = CDPController = CDPController_1 = __decorate([
|
|
118
150
|
(0, common_1.Controller)(),
|
|
119
151
|
__metadata("design:paramtypes", [browser_pool_service_1.BrowserPoolService,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdp.controller.js","sourceRoot":"","sources":["../../src/controllers/cdp.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,2CAAkE;AAClE,uCAA+C;AAE/C,yFAAoG;AACpG,2EAAuE;AACvE,2BAAqC;AACrC,6BAAoB;AACpB,iDAAuD;
|
|
1
|
+
{"version":3,"file":"cdp.controller.js","sourceRoot":"","sources":["../../src/controllers/cdp.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MaxBrowserReachedError = void 0;
|
|
4
|
+
class MaxBrowserReachedError extends Error {
|
|
5
|
+
}
|
|
6
|
+
exports.MaxBrowserReachedError = MaxBrowserReachedError;
|
|
7
|
+
//# sourceMappingURL=max-browser-reached.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"max-browser-reached.error.js","sourceRoot":"","sources":["../../src/errors/max-browser-reached.error.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAuB,SAAQ,KAAK;CAEhD;AAFD,wDAEC"}
|
package/dist/main.js
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@nestjs/core");
|
|
4
4
|
const app_module_1 = require("./app.module");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const logger = new common_1.Logger();
|
|
7
|
+
logger.log("| βββββββ βββ βββββββββββββββββββββββββββ βββββββ βββββββ βββ ββββββββββββββββββββββββββ ");
|
|
8
|
+
logger.log("| βββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββ");
|
|
9
|
+
logger.log("| βββββββββββ βββ βββ βββββ βββββββββββββββββββ ββββββ ββ βββββββββββββββββ ββββββββ");
|
|
10
|
+
logger.log("| βββββββββββ βββ βββ βββββ βββββββββββββββββββ βββββββββββββββββββββββββββ ββββββββ");
|
|
11
|
+
logger.log("| βββββββββββββββββββ βββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββ βββ");
|
|
12
|
+
logger.log("| βββββββ βββββββββββ βββ βββββββββββββββ βββ βββ βββββββ ββββββββ βββββββββββββββββββ βββ");
|
|
5
13
|
async function bootstrap() {
|
|
6
14
|
const app = await core_1.NestFactory.create(app_module_1.AppModule);
|
|
7
15
|
await app.listen(process.env.PORT || 9999);
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AACzC,2CAAwC;AAExC,MAAM,MAAM,GAAG,IAAI,eAAM,EAAE,CAAC;AAE5B,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAChH,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAChH,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAChH,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAChH,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAChH,MAAM,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;AAEhH,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,EAAE,CAAC"}
|
|
@@ -27,6 +27,7 @@ const common_1 = require("@nestjs/common");
|
|
|
27
27
|
const browser_instance_component_1 = require("../components/browser-instance.component");
|
|
28
28
|
const EventEmitter = require("events");
|
|
29
29
|
const core_1 = require("@nestjs/core");
|
|
30
|
+
const max_browser_reached_error_1 = require("../errors/max-browser-reached.error");
|
|
30
31
|
let BrowserPoolService = BrowserPoolService_1 = class BrowserPoolService extends EventEmitter {
|
|
31
32
|
constructor(module_ref) {
|
|
32
33
|
super();
|
|
@@ -35,7 +36,7 @@ let BrowserPoolService = BrowserPoolService_1 = class BrowserPoolService extends
|
|
|
35
36
|
_BrowserPoolService_id.set(this, crypto.randomUUID());
|
|
36
37
|
_BrowserPoolService_started_at.set(this, new Date().toISOString());
|
|
37
38
|
_BrowserPoolService_tags.set(this, {});
|
|
38
|
-
this.max_browser_instances = parseInt(process.env.MAX_BROWSER_INSTANCES);
|
|
39
|
+
this.max_browser_instances = parseInt(process.env.MAX_BROWSER_INSTANCES || '99');
|
|
39
40
|
_BrowserPoolService_browser_instances.set(this, new Map());
|
|
40
41
|
_BrowserPoolService_sigterm_received.set(this, false);
|
|
41
42
|
(process.env.TAGS || '').split(',').forEach(tag => {
|
|
@@ -83,6 +84,9 @@ let BrowserPoolService = BrowserPoolService_1 = class BrowserPoolService extends
|
|
|
83
84
|
this.logger.log(`Can't create new browser instance. Sigterm has been received.`);
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
87
|
+
if (__classPrivateFieldGet(this, _BrowserPoolService_browser_instances, "f").size === this.max_browser_instances) {
|
|
88
|
+
throw new max_browser_reached_error_1.MaxBrowserReachedError();
|
|
89
|
+
}
|
|
86
90
|
const browser_instance = new browser_instance_component_1.BrowserInstance(id, this.module_ref);
|
|
87
91
|
this.logger.log(`Created browser instance ${browser_instance.id}.`);
|
|
88
92
|
this.emit('browser_instance_created', browser_instance);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-pool.service.js","sourceRoot":"","sources":["../../src/services/browser-pool.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAkE;AAClE,yFAA4E;AAC5E,uCAAuC;AACvC,uCAAyC;
|
|
1
|
+
{"version":3,"file":"browser-pool.service.js","sourceRoot":"","sources":["../../src/services/browser-pool.service.ts"],"names":[],"mappings":"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"}
|