-
Notifications
You must be signed in to change notification settings - Fork 12
/
worker.js
97 lines (80 loc) · 2.47 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env node
const chunks = []
process.stdin.resume()
process.stdin.setEncoding('utf8')
process.stdin.on('data', function (chunk) {
chunks.push(chunk)
})
process.stdin.on('end', function () {
const [resource, init] = JSON.parse(chunks.join(''))
import('node-fetch')
.then(({ default: fetch, Headers, Request }) => {
init.body = init.body ? Buffer.from(init.body, 'base64') : undefined
init.headers = new Headers(init.headers)
if (init.timeout) {
const signal = timeoutSignal(init.timeout)
if (init.signal) {
init.signal = AbortSignal.any([init.signal, signal])
} else {
init.signal = signal
}
}
return fetch(new Request(resource, init), {})
})
.then(response => response.arrayBuffer()
.then(buffer => respond(serializeResponse(Buffer.from(buffer).toString('base64'), response)))
.catch(error => {
if (error.name === 'AbortError' && init.signal && init.signal.reason === 'timeout') {
error.type = 'body-timeout'
}
return respond(serializeResponse('', response, error))
})
)
.catch(error => {
if (error.name === 'AbortError' && init.signal && init.signal.reason === 'timeout') {
error.type = 'request-timeout'
}
return respondWithError(error)
})
})
// Adapted from https://github.com/node-fetch/timeout-signal/blob/main/index.js
function timeoutSignal (timeout) {
if (!Number.isInteger(timeout)) {
throw new TypeError('Expected an integer')
}
const controller = new AbortController()
const timeoutId = setTimeout(() => {
controller.abort('timeout')
}, timeout)
if (typeof timeoutId.unref === 'function') {
timeoutId.unref()
}
return controller.signal
}
function serializeResponse (body, response, bodyError) {
const init = {
headers: response.headers.raw(),
status: response.status,
statusText: response.statusText,
redirected: response.redirected,
type: response.type,
url: response.url
}
return [0, body, init, bodyError ? serializeError(bodyError) : null]
}
function serializeError ({ constructor, message, type, code }) {
return [
constructor.name,
[message, type, { code }]
]
}
function respond (message) {
process.stdout.write(JSON.stringify(message))
}
function respondWithError (error) {
if (error.cause && error.message === 'fetch failed') {
respondWithError(error.cause)
} else {
respond([1, serializeError(error)])
}
}