@browserless.io/browserless 2.3.0 → 2.4.0-beta-3
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/CHANGELOG.md +6 -0
- package/bin/browserless.js +2 -0
- package/bin/scaffold/README.md +26 -1
- package/build/browserless.d.ts +6 -2
- package/build/browserless.js +23 -4
- package/build/browsers/chromium.cdp.d.ts +1 -5
- package/build/browsers/chromium.cdp.js +5 -115
- package/build/browsers/chromium.playwright.d.ts +1 -3
- package/build/browsers/chromium.playwright.js +1 -6
- package/build/browsers/firefox.playwright.d.ts +1 -3
- package/build/browsers/firefox.playwright.js +1 -6
- package/build/browsers/index.d.ts +5 -1
- package/build/browsers/index.js +6 -5
- package/build/browsers/webkit.playwright.d.ts +1 -3
- package/build/browsers/webkit.playwright.js +1 -6
- package/build/config.d.ts +9 -0
- package/build/config.js +11 -0
- package/build/constants.d.ts +0 -1
- package/build/constants.js +0 -1
- package/build/data/selectors.json +1 -1
- package/build/file-system.d.ts +12 -1
- package/build/file-system.js +14 -1
- package/build/http.d.ts +0 -7
- package/build/limiter.d.ts +9 -0
- package/build/limiter.js +11 -0
- package/build/metrics.d.ts +12 -1
- package/build/metrics.js +13 -1
- package/build/monitoring.d.ts +12 -1
- package/build/monitoring.js +14 -1
- package/build/router.d.ts +12 -2
- package/build/router.js +16 -6
- package/build/routes/chrome/http/content.post.body.json +8 -8
- package/build/routes/chrome/http/content.post.query.json +0 -4
- package/build/routes/chrome/http/download.post.query.json +0 -4
- package/build/routes/chrome/http/function.post.query.json +0 -4
- package/build/routes/chrome/http/pdf.post.body.json +8 -8
- package/build/routes/chrome/http/pdf.post.query.json +0 -4
- package/build/routes/chrome/http/performance.post.query.json +0 -4
- package/build/routes/chrome/http/scrape.post.body.json +8 -8
- package/build/routes/chrome/http/scrape.post.query.json +0 -4
- package/build/routes/chrome/http/screenshot.post.body.json +8 -8
- package/build/routes/chrome/http/screenshot.post.query.json +0 -4
- package/build/routes/chrome/tests/function.spec.js +32 -0
- package/build/routes/chrome/ws/browser.query.json +0 -4
- package/build/routes/chrome/ws/cdp.query.json +0 -4
- package/build/routes/chrome/ws/page.query.json +0 -4
- package/build/routes/chrome/ws/playwright.query.json +0 -4
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.query.json +0 -4
- package/build/routes/chromium/http/download.post.query.json +0 -4
- package/build/routes/chromium/http/function.post.query.json +0 -4
- package/build/routes/chromium/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.query.json +0 -4
- package/build/routes/chromium/http/performance.post.query.json +0 -4
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.query.json +0 -4
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.query.json +0 -4
- package/build/routes/chromium/ws/browser.query.json +0 -4
- package/build/routes/chromium/ws/cdp.query.json +0 -4
- package/build/routes/chromium/ws/page.query.json +0 -4
- package/build/routes/chromium/ws/playwright.query.json +0 -4
- package/build/routes/firefox/ws/playwright.query.json +0 -4
- package/build/routes/management/http/static.get.js +17 -11
- package/build/routes/webkit/ws/playwright.query.json +0 -4
- package/build/server.d.ts +8 -3
- package/build/server.js +15 -13
- package/build/token.d.ts +12 -1
- package/build/token.js +14 -1
- package/build/types.d.ts +9 -12
- package/build/types.js +10 -1
- package/build/webhooks.d.ts +12 -1
- package/build/webhooks.js +14 -1
- package/extensions/.gitkeep +0 -0
- package/package.json +5 -5
- package/src/browserless.ts +24 -2
- package/src/browsers/chromium.cdp.ts +10 -157
- package/src/browsers/chromium.playwright.ts +0 -8
- package/src/browsers/firefox.playwright.ts +0 -8
- package/src/browsers/index.ts +7 -6
- package/src/browsers/webkit.playwright.ts +0 -8
- package/src/config.ts +13 -0
- package/src/constants.ts +0 -1
- package/src/file-system.ts +16 -1
- package/src/http.ts +0 -8
- package/src/limiter.ts +13 -0
- package/src/metrics.ts +16 -1
- package/src/monitoring.ts +18 -2
- package/src/router.ts +20 -9
- package/src/routes/chrome/tests/function.spec.ts +35 -0
- package/src/routes/management/http/static.get.ts +25 -15
- package/src/server.ts +18 -16
- package/src/token.ts +18 -2
- package/src/types.ts +9 -13
- package/src/webhooks.ts +18 -2
- package/static/docs/swagger.json +10 -186
- package/static/docs/swagger.min.json +9 -185
- package/extensions/screencast/background.js +0 -143
- package/extensions/screencast/content_script.js +0 -18
- package/extensions/screencast/manifest.json +0 -19
package/src/limiter.ts
CHANGED
|
@@ -226,4 +226,17 @@ export class Limiter extends q {
|
|
|
226
226
|
return bound;
|
|
227
227
|
});
|
|
228
228
|
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
232
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
233
|
+
*/
|
|
234
|
+
public shutdown = async () => {
|
|
235
|
+
await this.stop();
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
240
|
+
*/
|
|
241
|
+
public stop = () => {};
|
|
229
242
|
}
|
package/src/metrics.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { IBrowserlessStats } from '@browserless.io/browserless';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
|
|
5
|
+
export class Metrics extends EventEmitter {
|
|
4
6
|
protected sessionTimes: number[] = [];
|
|
5
7
|
protected successful = 0;
|
|
6
8
|
protected queued = 0;
|
|
@@ -105,4 +107,17 @@ export class Metrics {
|
|
|
105
107
|
),
|
|
106
108
|
};
|
|
107
109
|
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
113
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
114
|
+
*/
|
|
115
|
+
public shutdown = async () => {
|
|
116
|
+
await this.stop();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
121
|
+
*/
|
|
122
|
+
public stop = () => {};
|
|
108
123
|
}
|
package/src/monitoring.ts
CHANGED
|
@@ -3,11 +3,14 @@ import {
|
|
|
3
3
|
IResourceLoad,
|
|
4
4
|
createLogger,
|
|
5
5
|
} from '@browserless.io/browserless';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
6
7
|
import si from 'systeminformation';
|
|
7
8
|
|
|
8
|
-
export class Monitoring {
|
|
9
|
+
export class Monitoring extends EventEmitter {
|
|
9
10
|
protected log = createLogger('hardware');
|
|
10
|
-
constructor(protected config: Config) {
|
|
11
|
+
constructor(protected config: Config) {
|
|
12
|
+
super();
|
|
13
|
+
}
|
|
11
14
|
|
|
12
15
|
public getMachineStats = async (): Promise<IResourceLoad> => {
|
|
13
16
|
const [cpuLoad, memLoad] = await Promise.all([
|
|
@@ -50,4 +53,17 @@ export class Monitoring {
|
|
|
50
53
|
memoryOverloaded,
|
|
51
54
|
};
|
|
52
55
|
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
59
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
60
|
+
*/
|
|
61
|
+
public shutdown = async () => {
|
|
62
|
+
await this.stop();
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
67
|
+
*/
|
|
68
|
+
public stop = () => {};
|
|
53
69
|
}
|
package/src/router.ts
CHANGED
|
@@ -16,10 +16,11 @@ import {
|
|
|
16
16
|
isConnected,
|
|
17
17
|
writeResponse,
|
|
18
18
|
} from '@browserless.io/browserless';
|
|
19
|
+
import { EventEmitter } from 'events';
|
|
19
20
|
import micromatch from 'micromatch';
|
|
20
21
|
import stream from 'stream';
|
|
21
22
|
|
|
22
|
-
export class Router {
|
|
23
|
+
export class Router extends EventEmitter {
|
|
23
24
|
protected log = createLogger('router');
|
|
24
25
|
protected verbose = createLogger('router:verbose');
|
|
25
26
|
protected httpRoutes: Array<HTTPRoute | BrowserHTTPRoute> = [];
|
|
@@ -29,7 +30,9 @@ export class Router {
|
|
|
29
30
|
protected config: Config,
|
|
30
31
|
protected browserManager: BrowserManager,
|
|
31
32
|
protected limiter: Limiter,
|
|
32
|
-
) {
|
|
33
|
+
) {
|
|
34
|
+
super();
|
|
35
|
+
}
|
|
33
36
|
|
|
34
37
|
protected getTimeout(req: Request) {
|
|
35
38
|
const timer = req.parsed.searchParams.get('timeout');
|
|
@@ -207,13 +210,6 @@ export class Router {
|
|
|
207
210
|
return route;
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
public teardown() {
|
|
211
|
-
this.httpRoutes = [];
|
|
212
|
-
this.webSocketRoutes = [];
|
|
213
|
-
|
|
214
|
-
return this.browserManager.stop();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
213
|
public getStaticHandler() {
|
|
218
214
|
return this.httpRoutes.find((route) =>
|
|
219
215
|
route.path.includes(HTTPManagementRoutes.static),
|
|
@@ -253,4 +249,19 @@ export class Router {
|
|
|
253
249
|
(r.path as Array<PathTypes>).some((p) => micromatch.isMatch(pathname, p)),
|
|
254
250
|
);
|
|
255
251
|
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
255
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
256
|
+
*/
|
|
257
|
+
public shutdown = async () => {
|
|
258
|
+
this.httpRoutes = [];
|
|
259
|
+
this.webSocketRoutes = [];
|
|
260
|
+
await this.stop();
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
265
|
+
*/
|
|
266
|
+
public stop = () => {};
|
|
256
267
|
}
|
|
@@ -46,6 +46,41 @@ describe('/chrome/function API', function () {
|
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
it('runs functions with "context"', async () => {
|
|
50
|
+
const config = new Config();
|
|
51
|
+
config.setToken('browserless');
|
|
52
|
+
const metrics = new Metrics();
|
|
53
|
+
await start({ config, metrics });
|
|
54
|
+
const body = {
|
|
55
|
+
code: `export default async function ({ page, context }) {
|
|
56
|
+
if (!!context.ok) {
|
|
57
|
+
return Promise.resolve({
|
|
58
|
+
data: "ok",
|
|
59
|
+
type: "application/text",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return Promise.reject(new Error('Bad context!'));
|
|
63
|
+
}`,
|
|
64
|
+
context: {
|
|
65
|
+
ok: true,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
await fetch('http://localhost:3000/chrome/function?token=browserless', {
|
|
70
|
+
body: JSON.stringify(body),
|
|
71
|
+
headers: {
|
|
72
|
+
'content-type': 'application/json',
|
|
73
|
+
},
|
|
74
|
+
method: 'POST',
|
|
75
|
+
}).then(async (res) => {
|
|
76
|
+
const json = await res.json();
|
|
77
|
+
|
|
78
|
+
expect(json).to.have.property('data');
|
|
79
|
+
expect(json.data).to.equal('ok');
|
|
80
|
+
expect(res.status).to.equal(200);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
49
84
|
it('runs "application/javascript" functions', async () => {
|
|
50
85
|
const config = new Config();
|
|
51
86
|
config.setToken('browserless');
|
|
@@ -70,39 +70,49 @@ export default class StaticGetRoute extends HTTPRoute {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const config = this.config();
|
|
73
|
+
const sdkDir = this.staticSDKDir();
|
|
73
74
|
const file = path.join(config.getStatic(), pathname);
|
|
74
75
|
const indexFile = path.join(file, 'index.html');
|
|
76
|
+
const locations = [file, indexFile];
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
if (sdkDir) {
|
|
79
|
+
const sdkPath = path.join(sdkDir, pathname);
|
|
80
|
+
locations.push(...[sdkPath, path.join(sdkPath, 'index.html')]);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const foundFilePaths = (
|
|
84
|
+
await Promise.all(
|
|
85
|
+
locations.map((l) => fileExists(l).then((e) => (e ? l : undefined))),
|
|
86
|
+
)
|
|
87
|
+
).filter((_) => !!_) as string[];
|
|
84
88
|
|
|
85
|
-
if (!
|
|
89
|
+
if (!foundFilePaths.length) {
|
|
86
90
|
throw new NotFound(
|
|
87
91
|
`No route or file found for resource ${req.method}: ${pathname}`,
|
|
88
92
|
);
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
if (foundFilePaths.length > 1) {
|
|
96
|
+
debug(
|
|
97
|
+
`Multiple files found for request to "${pathname}". Only the first file is served, so please name your files uniquely.`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const [foundFilePath] = foundFilePaths;
|
|
102
|
+
verbose(`Found new file "${foundFilePath}", caching path and serving`);
|
|
92
103
|
|
|
93
|
-
const contentType = mimeTypes.get(path.extname(
|
|
104
|
+
const contentType = mimeTypes.get(path.extname(foundFilePath));
|
|
94
105
|
|
|
95
106
|
if (contentType) {
|
|
96
107
|
res.setHeader('Content-Type', contentType);
|
|
97
108
|
}
|
|
98
109
|
|
|
99
|
-
// Cache the
|
|
100
|
-
// do stat checks again when requests come back
|
|
110
|
+
// Cache the file as being found so we don't have to call 'stat'
|
|
101
111
|
pathMap.set(pathname, {
|
|
102
112
|
contentType,
|
|
103
|
-
path:
|
|
113
|
+
path: foundFilePath,
|
|
104
114
|
});
|
|
105
115
|
|
|
106
|
-
return streamFile(verbose, res,
|
|
116
|
+
return streamFile(verbose, res, foundFilePath, contentType);
|
|
107
117
|
};
|
|
108
118
|
}
|
package/src/server.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
shimLegacyRequests,
|
|
24
24
|
writeResponse,
|
|
25
25
|
} from '@browserless.io/browserless';
|
|
26
|
+
import { EventEmitter } from 'events';
|
|
26
27
|
|
|
27
28
|
// @ts-ignore
|
|
28
29
|
import Enjoi from 'enjoi';
|
|
@@ -35,7 +36,7 @@ export interface HTTPServerOptions {
|
|
|
35
36
|
timeout: number;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
export class HTTPServer {
|
|
39
|
+
export class HTTPServer extends EventEmitter {
|
|
39
40
|
protected server: http.Server = http.createServer();
|
|
40
41
|
protected port: number;
|
|
41
42
|
protected host?: string;
|
|
@@ -48,6 +49,7 @@ export class HTTPServer {
|
|
|
48
49
|
protected token: Token,
|
|
49
50
|
protected router: Router,
|
|
50
51
|
) {
|
|
52
|
+
super();
|
|
51
53
|
this.host = config.getHost();
|
|
52
54
|
this.port = config.getPort();
|
|
53
55
|
|
|
@@ -100,21 +102,6 @@ export class HTTPServer {
|
|
|
100
102
|
});
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
public async stop(): Promise<void> {
|
|
104
|
-
this.log(`HTTP Server is shutting down`);
|
|
105
|
-
await new Promise((r) => this.server.close(r));
|
|
106
|
-
await Promise.all([this.tearDown(), this.router.teardown()]);
|
|
107
|
-
this.log(`HTTP Server shutdown complete`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
protected tearDown() {
|
|
111
|
-
this.log(`Tearing down all listeners and internal routes`);
|
|
112
|
-
this.server && this.server.removeAllListeners();
|
|
113
|
-
|
|
114
|
-
// @ts-ignore garbage collect this reference
|
|
115
|
-
this.server = null;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
105
|
protected handleRequest = async (
|
|
119
106
|
request: http.IncomingMessage,
|
|
120
107
|
res: http.ServerResponse,
|
|
@@ -410,4 +397,19 @@ export class HTTPServer {
|
|
|
410
397
|
this.log(`No matching WebSocket route handler for "${req.parsed.href}"`);
|
|
411
398
|
return writeResponse(socket, 404, 'Not Found');
|
|
412
399
|
};
|
|
400
|
+
|
|
401
|
+
public async shutdown(): Promise<void> {
|
|
402
|
+
this.log(`HTTP Server is shutting down`);
|
|
403
|
+
await new Promise((r) => this.server.close(r));
|
|
404
|
+
this.server && this.server.removeAllListeners();
|
|
405
|
+
|
|
406
|
+
// @ts-ignore garbage collect this reference
|
|
407
|
+
this.server = null;
|
|
408
|
+
this.log(`HTTP Server shutdown complete`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
413
|
+
*/
|
|
414
|
+
public stop = () => {};
|
|
413
415
|
}
|
package/src/token.ts
CHANGED
|
@@ -7,9 +7,12 @@ import {
|
|
|
7
7
|
WebSocketRoute,
|
|
8
8
|
getTokenFromRequest,
|
|
9
9
|
} from '@browserless.io/browserless';
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
10
11
|
|
|
11
|
-
export class Token {
|
|
12
|
-
constructor(protected config: Config) {
|
|
12
|
+
export class Token extends EventEmitter {
|
|
13
|
+
constructor(protected config: Config) {
|
|
14
|
+
super();
|
|
15
|
+
}
|
|
13
16
|
|
|
14
17
|
public isAuthorized = async (
|
|
15
18
|
req: Request,
|
|
@@ -37,4 +40,17 @@ export class Token {
|
|
|
37
40
|
|
|
38
41
|
return (Array.isArray(token) ? token : [token]).includes(requestToken);
|
|
39
42
|
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
46
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
47
|
+
*/
|
|
48
|
+
public shutdown = async () => {
|
|
49
|
+
await this.stop();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
54
|
+
*/
|
|
55
|
+
public stop = () => {};
|
|
40
56
|
}
|
package/src/types.ts
CHANGED
|
@@ -102,6 +102,7 @@ abstract class Route {
|
|
|
102
102
|
protected _debug: Browserless['debug'],
|
|
103
103
|
protected _metrics: Browserless['metrics'],
|
|
104
104
|
protected _monitoring: Browserless['monitoring'],
|
|
105
|
+
protected _staticSDKDir: Browserless['staticSDKDir'],
|
|
105
106
|
) {}
|
|
106
107
|
|
|
107
108
|
/**
|
|
@@ -195,6 +196,14 @@ abstract class Route {
|
|
|
195
196
|
*/
|
|
196
197
|
monitoring = () => this._monitoring;
|
|
197
198
|
|
|
199
|
+
/**
|
|
200
|
+
* When running in an SDK environment, this returns the fully-qualified
|
|
201
|
+
* directory of that static directory. When "null" then no SDK directory
|
|
202
|
+
* has been set.
|
|
203
|
+
* @returns {string | null} The full path location of the SDK's static directory
|
|
204
|
+
*/
|
|
205
|
+
staticSDKDir = () => this._staticSDKDir;
|
|
206
|
+
|
|
198
207
|
/**
|
|
199
208
|
* The HTTP path that this route handles, eg '/my-route' OR an
|
|
200
209
|
* array of paths that this route can handle.
|
|
@@ -469,19 +478,6 @@ export const debugScreenshotOpts: ScreenshotOptions = {
|
|
|
469
478
|
type: 'jpeg',
|
|
470
479
|
};
|
|
471
480
|
|
|
472
|
-
declare global {
|
|
473
|
-
interface Window {
|
|
474
|
-
browserless: BrowserlessEmbeddedAPI;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
export interface BrowserlessEmbeddedAPI {
|
|
479
|
-
getRecording: () => Promise<string>;
|
|
480
|
-
liveUrl: () => string;
|
|
481
|
-
saveRecording: () => Promise<boolean>;
|
|
482
|
-
startRecording: () => void;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
481
|
/**
|
|
486
482
|
* When bestAttempt is set to true, browserless attempt to proceed
|
|
487
483
|
* when "awaited" events fail or timeout. This includes things like
|
package/src/webhooks.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Config, fetchTimeout, noop } from '@browserless.io/browserless';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
2
3
|
|
|
3
|
-
export class WebHooks {
|
|
4
|
-
constructor(protected config: Config) {
|
|
4
|
+
export class WebHooks extends EventEmitter {
|
|
5
|
+
constructor(protected config: Config) {
|
|
6
|
+
super();
|
|
7
|
+
}
|
|
5
8
|
|
|
6
9
|
protected callURL(url: string | null) {
|
|
7
10
|
if (url) {
|
|
@@ -47,4 +50,17 @@ export class WebHooks {
|
|
|
47
50
|
);
|
|
48
51
|
}
|
|
49
52
|
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Implement any browserless-core-specific shutdown logic here.
|
|
56
|
+
* Calls the empty-SDK stop method for downstream implementations.
|
|
57
|
+
*/
|
|
58
|
+
public shutdown = async () => {
|
|
59
|
+
await this.stop();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Left blank for downstream SDK modules to optionally implement.
|
|
64
|
+
*/
|
|
65
|
+
public stop = () => {};
|
|
50
66
|
}
|