| 16 | } |
| 17 | |
| 18 | public async start(data: { |
| 19 | browserWSEndpoint: string; |
| 20 | code: codeHandler; |
| 21 | context: unknown; |
| 22 | options: { |
| 23 | downloadPath?: string; |
| 24 | protocolTimeout?: number; |
| 25 | }; |
| 26 | }) { |
| 27 | console.log(`/function.js: Got endpoint: "${data.browserWSEndpoint}"`); |
| 28 | const { browserWSEndpoint, code, context, options } = data; |
| 29 | const connectionTransport = |
| 30 | await BrowserWebSocketTransport.create(browserWSEndpoint); |
| 31 | const cdpOptions = { |
| 32 | headers: { |
| 33 | Host: '127.0.0.1', |
| 34 | }, |
| 35 | protocolTimeout: options.protocolTimeout, |
| 36 | }; |
| 37 | |
| 38 | this.browser = (await connect( |
| 39 | connectionTransport, |
| 40 | browserWSEndpoint, |
| 41 | cdpOptions, |
| 42 | )) as unknown as Browser; |
| 43 | this.browser.once('disconnected', () => this.stop()); |
| 44 | this.page = await this.browser.newPage(); |
| 45 | |
| 46 | if (options.downloadPath) { |
| 47 | console.debug( |
| 48 | `_browserless_function_client_: Setting downloads for page to "${options.downloadPath}"`, |
| 49 | ); |
| 50 | // @ts-ignore |
| 51 | const client = this.page._client.call(this.page); |
| 52 | await client.send('Page.setDownloadBehavior', { |
| 53 | behavior: 'allow', |
| 54 | downloadPath: options.downloadPath, |
| 55 | }); |
| 56 | } |
| 57 | |
| 58 | const response = await code({ context, page: this.page }).catch((e) => { |
| 59 | console.error(`Error running code: ${e}`); |
| 60 | this.browser?.disconnect(); |
| 61 | throw e; |
| 62 | }); |
| 63 | console.debug( |
| 64 | `_browserless_function_client_: Code is finished executing, closing page.`, |
| 65 | ); |
| 66 | this.page.close().catch(this.log); |
| 67 | |
| 68 | if (response instanceof Uint8Array) { |
| 69 | return { |
| 70 | contentType: 'uint8array', |
| 71 | payload: Array.from(response), |
| 72 | }; |
| 73 | } |
| 74 | |
| 75 | if (typeof response === 'string') { |