@bytecodealliance/preview2-shim 0.17.2 → 0.17.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.
@@ -1,15 +1,15 @@
1
- import { createReadableStream, getStreamOrThrow } from "./worker-thread.js";
1
+ import { createReadableStream, getStreamOrThrow } from './worker-thread.js';
2
2
  import {
3
- createServer,
4
- request as httpRequest,
5
- Agent as HttpAgent,
6
- } from "node:http";
7
- import { request as httpsRequest, Agent as HttpsAgent } from "node:https";
8
- import { parentPort } from "node:worker_threads";
9
- import { HTTP_SERVER_INCOMING_HANDLER } from "./calls.js";
3
+ createServer,
4
+ request as httpRequest,
5
+ Agent as HttpAgent,
6
+ } from 'node:http';
7
+ import { request as httpsRequest, Agent as HttpsAgent } from 'node:https';
8
+ import { parentPort } from 'node:worker_threads';
9
+ import { HTTP_SERVER_INCOMING_HANDLER } from './calls.js';
10
10
 
11
11
  const agentOptions = {
12
- keepAlive: true,
12
+ keepAlive: true,
13
13
  };
14
14
  const httpAgent = new HttpAgent(agentOptions);
15
15
  const httpsAgent = new HttpsAgent(agentOptions);
@@ -20,176 +20,194 @@ let responseCnt = 0;
20
20
  const responses = new Map();
21
21
 
22
22
  export async function stopHttpServer(id) {
23
- await new Promise((resolve) => servers.get(id).close(resolve));
23
+ await new Promise((resolve) => servers.get(id).close(resolve));
24
24
  }
25
25
 
26
26
  export function clearOutgoingResponse(id) {
27
- responses.delete(id);
27
+ responses.delete(id);
28
28
  }
29
29
 
30
30
  export async function setOutgoingResponse(
31
- id,
32
- { statusCode, headers, streamId }
31
+ id,
32
+ { statusCode, headers, streamId }
33
33
  ) {
34
- const response = responses.get(id);
35
- const textDecoder = new TextDecoder();
36
- response.writeHead(
37
- statusCode,
38
- Object.fromEntries(
39
- headers.map(([key, val]) => [key, textDecoder.decode(val)])
40
- )
41
- );
42
- response.flushHeaders();
43
- const { stream } = getStreamOrThrow(streamId);
44
- stream.pipe(response);
45
- responses.delete(id);
34
+ const response = responses.get(id);
35
+ const textDecoder = new TextDecoder();
36
+ response.writeHead(
37
+ statusCode,
38
+ Object.fromEntries(
39
+ headers.map(([key, val]) => [key, textDecoder.decode(val)])
40
+ )
41
+ );
42
+ response.flushHeaders();
43
+ const { stream } = getStreamOrThrow(streamId);
44
+ stream.pipe(response);
45
+ responses.delete(id);
46
46
  }
47
47
 
48
48
  export async function startHttpServer(id, { port, host }) {
49
- const server = createServer((req, res) => {
50
- // create the streams and their ids
51
- const streamId = createReadableStream(req);
52
- const responseId = ++responseCnt;
53
- parentPort.postMessage({
54
- type: HTTP_SERVER_INCOMING_HANDLER,
55
- id,
56
- payload: {
57
- responseId,
58
- method: req.method,
59
- host: req.headers.host || host || "localhost",
60
- pathWithQuery: req.url,
61
- headers: Object.entries(req.headersDistinct).flatMap(([key, val]) =>
62
- val.map((val) => [key, val])
63
- ),
64
- streamId,
65
- },
49
+ const server = createServer((req, res) => {
50
+ // create the streams and their ids
51
+ const streamId = createReadableStream(req);
52
+ const responseId = ++responseCnt;
53
+ parentPort.postMessage({
54
+ type: HTTP_SERVER_INCOMING_HANDLER,
55
+ id,
56
+ payload: {
57
+ responseId,
58
+ method: req.method,
59
+ host: req.headers.host || host || 'localhost',
60
+ pathWithQuery: req.url,
61
+ headers: Object.entries(req.headersDistinct).flatMap(
62
+ ([key, val]) => val.map((val) => [key, val])
63
+ ),
64
+ streamId,
65
+ },
66
+ });
67
+ responses.set(responseId, res);
68
+ });
69
+ await new Promise((resolve, reject) => {
70
+ server.listen(port, host, resolve);
71
+ server.on('error', reject);
66
72
  });
67
- responses.set(responseId, res);
68
- });
69
- await new Promise((resolve, reject) => {
70
- server.listen(port, host, resolve);
71
- server.on("error", reject);
72
- });
73
- servers.set(id, server);
73
+ servers.set(id, server);
74
74
  }
75
75
 
76
76
  export async function createHttpRequest(
77
- method,
78
- scheme,
79
- authority,
80
- pathWithQuery,
81
- headers,
82
- bodyId,
83
- connectTimeout,
84
- betweenBytesTimeout,
85
- firstByteTimeout
77
+ method,
78
+ scheme,
79
+ authority,
80
+ pathWithQuery,
81
+ headers,
82
+ bodyId,
83
+ connectTimeout,
84
+ betweenBytesTimeout,
85
+ firstByteTimeout
86
86
  ) {
87
- let stream = null;
88
- if (bodyId) {
89
- try {
90
- ({ stream } = getStreamOrThrow(bodyId));
91
- } catch (e) {
92
- if (e.tag === "closed")
93
- throw { tag: "internal-error", val: "Unexpected closed body stream" };
94
- // it should never be possible for the body stream to already
95
- // be closed, or for there to be a write error
96
- // we therefore just throw internal error here
97
- if (e.tag === "last-operation-failed")
98
- throw {
99
- tag: "internal-error",
100
- val: e.val,
101
- };
102
- // entirely unknown error -> trap
103
- throw e;
104
- }
105
- }
106
- try {
107
- // Make a request
108
- let req;
109
- switch (scheme) {
110
- case "http:":
111
- req = httpRequest({
112
- agent: httpAgent,
113
- method,
114
- host: authority.split(":")[0],
115
- port: authority.split(":")[1],
116
- path: pathWithQuery,
117
- timeout: connectTimeout && Number(connectTimeout / 1_000_000n),
118
- });
119
- break;
120
- case "https:":
121
- req = httpsRequest({
122
- agent: httpsAgent,
123
- method,
124
- host: authority.split(":")[0],
125
- port: authority.split(":")[1],
126
- path: pathWithQuery,
127
- timeout: connectTimeout && Number(connectTimeout / 1_000_000n),
128
- });
129
- break;
130
- default:
131
- throw { tag: "HTTP-protocol-error" };
87
+ let stream = null;
88
+ if (bodyId) {
89
+ try {
90
+ ({ stream } = getStreamOrThrow(bodyId));
91
+ } catch (e) {
92
+ if (e.tag === 'closed') {
93
+ throw {
94
+ tag: 'internal-error',
95
+ val: 'Unexpected closed body stream',
96
+ };
97
+ }
98
+ // it should never be possible for the body stream to already
99
+ // be closed, or for there to be a write error
100
+ // we therefore just throw internal error here
101
+ if (e.tag === 'last-operation-failed') {
102
+ throw {
103
+ tag: 'internal-error',
104
+ val: e.val,
105
+ };
106
+ }
107
+ // entirely unknown error -> trap
108
+ throw e;
109
+ }
132
110
  }
133
- for (const [key, value] of headers) {
134
- req.appendHeader(key, value);
135
- }
136
- req.flushHeaders();
137
- if (stream) {
138
- stream.pipe(req);
139
- } else {
140
- req.end();
141
- }
142
- const res = await new Promise((resolve, reject) => {
143
- req.once('timeout', () => {
144
- reject({
145
- tag: "connection-timeout"
111
+ try {
112
+ // Make a request
113
+ let req;
114
+ switch (scheme) {
115
+ case 'http:':
116
+ req = httpRequest({
117
+ agent: httpAgent,
118
+ method,
119
+ host: authority.split(':')[0],
120
+ port: authority.split(':')[1],
121
+ path: pathWithQuery,
122
+ timeout:
123
+ connectTimeout && Number(connectTimeout / 1_000_000n),
124
+ });
125
+ break;
126
+ case 'https:':
127
+ req = httpsRequest({
128
+ agent: httpsAgent,
129
+ method,
130
+ host: authority.split(':')[0],
131
+ port: authority.split(':')[1],
132
+ path: pathWithQuery,
133
+ timeout:
134
+ connectTimeout && Number(connectTimeout / 1_000_000n),
135
+ });
136
+ break;
137
+ default:
138
+ throw { tag: 'HTTP-protocol-error' };
139
+ }
140
+ for (const [key, value] of headers) {
141
+ req.appendHeader(key, value);
142
+ }
143
+ req.flushHeaders();
144
+ if (stream) {
145
+ stream.pipe(req);
146
+ } else {
147
+ req.end();
148
+ }
149
+ const res = await new Promise((resolve, reject) => {
150
+ req.once('timeout', () => {
151
+ reject({
152
+ tag: 'connection-timeout',
153
+ });
154
+ req.destroy();
155
+ });
156
+ req.once('response', resolve);
157
+ req.once('close', () => reject);
158
+ req.once('error', reject);
146
159
  });
147
- req.destroy();
148
- });
149
- req.once("response", resolve);
150
- req.once("close", () => reject);
151
- req.once("error", reject);
152
- });
153
- if (firstByteTimeout) res.setTimeout(Number(firstByteTimeout / 1_000_000n));
154
- if (betweenBytesTimeout)
155
- res.once("readable", () => {
156
- res.setTimeout(Number(betweenBytesTimeout / 1_000_000n));
157
- });
158
- const bodyStreamId = createReadableStream(res);
159
- return {
160
- status: res.statusCode,
161
- headers: Array.from(Object.entries(res.headers)),
162
- bodyStreamId,
163
- };
164
- } catch (e) {
165
- if (e?.tag) throw e;
166
- const err = getFirstError(e);
167
- switch (err.code) {
168
- case "ECONNRESET":
169
- throw { tag: "HTTP-protocol-error" };
170
- case "ENOTFOUND":
171
- throw {
172
- tag: "DNS-error",
173
- val: {
174
- rcode: err.code,
175
- infoCode: err.errno < 0 ? -err.errno : err.errno,
176
- },
160
+ if (firstByteTimeout) {
161
+ res.setTimeout(Number(firstByteTimeout / 1_000_000n));
162
+ }
163
+ if (betweenBytesTimeout) {
164
+ res.once('readable', () => {
165
+ res.setTimeout(Number(betweenBytesTimeout / 1_000_000n));
166
+ });
167
+ }
168
+ const bodyStreamId = createReadableStream(res);
169
+ return {
170
+ status: res.statusCode,
171
+ headers: Array.from(Object.entries(res.headers)),
172
+ bodyStreamId,
177
173
  };
178
- case "ECONNREFUSED":
174
+ } catch (e) {
175
+ if (e?.tag) {
176
+ throw e;
177
+ }
178
+ const err = getFirstError(e);
179
+ switch (err.code) {
180
+ case 'ECONNRESET':
181
+ throw { tag: 'HTTP-protocol-error' };
182
+ case 'ENOTFOUND':
183
+ throw {
184
+ tag: 'DNS-error',
185
+ val: {
186
+ rcode: err.code,
187
+ infoCode: err.errno < 0 ? -err.errno : err.errno,
188
+ },
189
+ };
190
+ case 'ECONNREFUSED':
191
+ throw {
192
+ tag: 'connection-refused',
193
+ };
194
+ }
179
195
  throw {
180
- tag: "connection-refused",
196
+ tag: 'internal-error',
197
+ val: err.toString(),
181
198
  };
182
199
  }
183
- throw {
184
- tag: "internal-error",
185
- val: err.toString(),
186
- };
187
- }
188
200
  }
189
201
 
190
202
  function getFirstError(e) {
191
- if (typeof e !== "object" || e === null) return e;
192
- if (e.cause) return getFirstError(e.cause);
193
- if (e instanceof AggregateError) return getFirstError(e.errors[0]);
194
- return e;
203
+ if (typeof e !== 'object' || e === null) {
204
+ return e;
205
+ }
206
+ if (e.cause) {
207
+ return getFirstError(e.cause);
208
+ }
209
+ if (e instanceof AggregateError) {
210
+ return getFirstError(e.errors[0]);
211
+ }
212
+ return e;
195
213
  }