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