@bytecodealliance/preview2-shim 0.17.2 → 0.17.4

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,35 +1,35 @@
1
1
  import {
2
- createFuture,
3
- createReadableStream,
4
- createReadableStreamPollState,
5
- createWritableStream,
6
- futureDispose,
7
- futureTakeValue,
8
- pollStateReady,
9
- verifyPollsDroppedForDrop,
10
- } from "./worker-thread.js";
11
- import process from "node:process";
12
- const { TCP, constants: TCPConstants } = process.binding("tcp_wrap");
2
+ createFuture,
3
+ createReadableStream,
4
+ createReadableStreamPollState,
5
+ createWritableStream,
6
+ futureDispose,
7
+ futureTakeValue,
8
+ pollStateReady,
9
+ verifyPollsDroppedForDrop,
10
+ } from './worker-thread.js';
11
+ import process from 'node:process';
12
+ const { TCP, constants: TCPConstants } = process.binding('tcp_wrap');
13
13
  import {
14
- convertSocketError,
15
- convertSocketErrorCode,
16
- ipSocketAddress,
17
- isIPv4MappedAddress,
18
- isMulticastIpAddress,
19
- isUnicastIpAddress,
20
- isWildcardAddress,
21
- noLookup,
22
- serializeIpAddress,
23
- SOCKET_STATE_BIND,
24
- SOCKET_STATE_BOUND,
25
- SOCKET_STATE_CLOSED,
26
- SOCKET_STATE_CONNECT,
27
- SOCKET_STATE_CONNECTION,
28
- SOCKET_STATE_INIT,
29
- SOCKET_STATE_LISTEN,
30
- SOCKET_STATE_LISTENER,
31
- } from "./worker-sockets.js";
32
- import { Socket, Server } from "node:net";
14
+ convertSocketError,
15
+ convertSocketErrorCode,
16
+ ipSocketAddress,
17
+ isIPv4MappedAddress,
18
+ isMulticastIpAddress,
19
+ isUnicastIpAddress,
20
+ isWildcardAddress,
21
+ noLookup,
22
+ serializeIpAddress,
23
+ SOCKET_STATE_BIND,
24
+ SOCKET_STATE_BOUND,
25
+ SOCKET_STATE_CLOSED,
26
+ SOCKET_STATE_CONNECT,
27
+ SOCKET_STATE_CONNECTION,
28
+ SOCKET_STATE_INIT,
29
+ SOCKET_STATE_LISTEN,
30
+ SOCKET_STATE_LISTENER,
31
+ } from './worker-sockets.js';
32
+ import { Socket, Server } from 'node:net';
33
33
 
34
34
  const win = process.platform === 'win32';
35
35
 
@@ -66,226 +66,278 @@ let tcpSocketCnt = 0;
66
66
  * @param {IpAddressFamily} addressFamily
67
67
  */
68
68
  export function createTcpSocket() {
69
- const handle = new TCP(TCPConstants.SOCKET);
70
- tcpSockets.set(++tcpSocketCnt, {
71
- state: SOCKET_STATE_INIT,
72
- future: null,
73
- tcpSocket: null,
74
- listenBacklogSize: 128,
75
- handle,
76
- pendingAccepts: [],
77
- pollState: { ready: true, listener: null, polls: [], parentStream: null },
78
- });
79
- return tcpSocketCnt;
69
+ const handle = new TCP(TCPConstants.SOCKET);
70
+ tcpSockets.set(++tcpSocketCnt, {
71
+ state: SOCKET_STATE_INIT,
72
+ future: null,
73
+ tcpSocket: null,
74
+ listenBacklogSize: 128,
75
+ handle,
76
+ pendingAccepts: [],
77
+ pollState: {
78
+ ready: true,
79
+ listener: null,
80
+ polls: [],
81
+ parentStream: null,
82
+ },
83
+ });
84
+ return tcpSocketCnt;
80
85
  }
81
86
 
82
87
  export function socketTcpFinish(id, fromState, toState) {
83
- const socket = tcpSockets.get(id);
84
- if (socket.state !== fromState) throw "not-in-progress";
85
- if (!socket.pollState.ready) throw "would-block";
86
- const { tag, val } = futureTakeValue(socket.future).val;
87
- futureDispose(socket.future, false);
88
- socket.future = null;
89
- if (tag === "err") {
90
- socket.state = SOCKET_STATE_CLOSED;
91
- throw val;
92
- } else {
93
- socket.state = toState;
94
- // for the listener, we must immediately transition back to unresolved
95
- if (toState === SOCKET_STATE_LISTENER) socket.pollState.ready = false;
96
- return val;
97
- }
88
+ const socket = tcpSockets.get(id);
89
+ if (socket.state !== fromState) {
90
+ throw 'not-in-progress';
91
+ }
92
+ if (!socket.pollState.ready) {
93
+ throw 'would-block';
94
+ }
95
+ const { tag, val } = futureTakeValue(socket.future).val;
96
+ futureDispose(socket.future, false);
97
+ socket.future = null;
98
+ if (tag === 'err') {
99
+ socket.state = SOCKET_STATE_CLOSED;
100
+ throw val;
101
+ } else {
102
+ socket.state = toState;
103
+ // for the listener, we must immediately transition back to unresolved
104
+ if (toState === SOCKET_STATE_LISTENER) {
105
+ socket.pollState.ready = false;
106
+ }
107
+ return val;
108
+ }
98
109
  }
99
110
 
100
111
  export function socketTcpBindStart(id, localAddress, family) {
101
- const socket = tcpSockets.get(id);
102
- if (socket.state !== SOCKET_STATE_INIT) throw "invalid-state";
103
- if (
104
- family !== localAddress.tag ||
105
- !isUnicastIpAddress(localAddress) ||
106
- isIPv4MappedAddress(localAddress)
107
- )
108
- throw "invalid-argument";
109
- socket.state = SOCKET_STATE_BIND;
110
- const { handle } = socket;
111
- socket.future = createFuture(
112
- (async () => {
113
- const address = serializeIpAddress(localAddress);
114
- const port = localAddress.val.port;
115
- const code =
116
- localAddress.tag === "ipv6"
117
- ? handle.bind6(address, port, TCPConstants.UV_TCP_IPV6ONLY)
118
- : handle.bind(address, port);
119
- if (code !== 0) throw convertSocketErrorCode(-code);
120
- // This is a Node.js / libuv quirk to force the bind error to be thrown
121
- // (specifically address-in-use).
122
- {
123
- const out = {};
124
- const code = handle.getsockname(out);
125
- if (code !== 0) throw convertSocketErrorCode(-code);
126
- }
127
- })(),
128
- socket.pollState
129
- );
112
+ const socket = tcpSockets.get(id);
113
+ if (socket.state !== SOCKET_STATE_INIT) {
114
+ throw 'invalid-state';
115
+ }
116
+ if (
117
+ family !== localAddress.tag ||
118
+ !isUnicastIpAddress(localAddress) ||
119
+ isIPv4MappedAddress(localAddress)
120
+ ) {
121
+ throw 'invalid-argument';
122
+ }
123
+ socket.state = SOCKET_STATE_BIND;
124
+ const { handle } = socket;
125
+ socket.future = createFuture(
126
+ (async () => {
127
+ const address = serializeIpAddress(localAddress);
128
+ const port = localAddress.val.port;
129
+ const code =
130
+ localAddress.tag === 'ipv6'
131
+ ? handle.bind6(address, port, TCPConstants.UV_TCP_IPV6ONLY)
132
+ : handle.bind(address, port);
133
+ if (code !== 0) {
134
+ throw convertSocketErrorCode(-code);
135
+ }
136
+ // This is a Node.js / libuv quirk to force the bind error to be thrown
137
+ // (specifically address-in-use).
138
+ {
139
+ const out = {};
140
+ const code = handle.getsockname(out);
141
+ if (code !== 0) {
142
+ throw convertSocketErrorCode(-code);
143
+ }
144
+ }
145
+ })(),
146
+ socket.pollState
147
+ );
130
148
  }
131
149
 
132
150
  export function socketTcpConnectStart(id, remoteAddress, family) {
133
- const socket = tcpSockets.get(id);
134
- if (socket.state !== SOCKET_STATE_INIT && socket.state !== SOCKET_STATE_BOUND)
135
- throw "invalid-state";
136
- if (
137
- isWildcardAddress(remoteAddress) ||
138
- family !== remoteAddress.tag ||
139
- !isUnicastIpAddress(remoteAddress) ||
140
- isMulticastIpAddress(remoteAddress) ||
141
- remoteAddress.val.port === 0 ||
142
- isIPv4MappedAddress(remoteAddress)
143
- ) {
144
- throw "invalid-argument";
145
- }
146
- socket.state = SOCKET_STATE_CONNECT;
147
- socket.future = createFuture(
148
- new Promise((resolve, reject) => {
149
- const tcpSocket = (socket.tcpSocket = new Socket({
150
- handle: socket.handle,
151
- pauseOnCreate: true,
152
- allowHalfOpen: true,
153
- }));
154
- function handleErr(err) {
155
- tcpSocket.off("connect", handleConnect);
156
- reject(convertSocketError(err));
157
- }
158
- function handleConnect() {
159
- tcpSocket.off("error", handleErr);
160
- resolve([
161
- createReadableStream(tcpSocket),
162
- createWritableStream(tcpSocket),
163
- ]);
164
- }
165
- tcpSocket.once("connect", handleConnect);
166
- tcpSocket.once("error", handleErr);
167
- tcpSocket.connect({
168
- port: remoteAddress.val.port,
169
- host: serializeIpAddress(remoteAddress),
170
- lookup: noLookup,
171
- });
172
- }),
173
- socket.pollState
174
- );
151
+ const socket = tcpSockets.get(id);
152
+ if (
153
+ socket.state !== SOCKET_STATE_INIT &&
154
+ socket.state !== SOCKET_STATE_BOUND
155
+ ) {
156
+ throw 'invalid-state';
157
+ }
158
+ if (
159
+ isWildcardAddress(remoteAddress) ||
160
+ family !== remoteAddress.tag ||
161
+ !isUnicastIpAddress(remoteAddress) ||
162
+ isMulticastIpAddress(remoteAddress) ||
163
+ remoteAddress.val.port === 0 ||
164
+ isIPv4MappedAddress(remoteAddress)
165
+ ) {
166
+ throw 'invalid-argument';
167
+ }
168
+ socket.state = SOCKET_STATE_CONNECT;
169
+ socket.future = createFuture(
170
+ new Promise((resolve, reject) => {
171
+ const tcpSocket = (socket.tcpSocket = new Socket({
172
+ handle: socket.handle,
173
+ pauseOnCreate: true,
174
+ allowHalfOpen: true,
175
+ }));
176
+ function handleErr(err) {
177
+ tcpSocket.off('connect', handleConnect);
178
+ reject(convertSocketError(err));
179
+ }
180
+ function handleConnect() {
181
+ tcpSocket.off('error', handleErr);
182
+ resolve([
183
+ createReadableStream(tcpSocket),
184
+ createWritableStream(tcpSocket),
185
+ ]);
186
+ }
187
+ tcpSocket.once('connect', handleConnect);
188
+ tcpSocket.once('error', handleErr);
189
+ tcpSocket.connect({
190
+ port: remoteAddress.val.port,
191
+ host: serializeIpAddress(remoteAddress),
192
+ lookup: noLookup,
193
+ });
194
+ }),
195
+ socket.pollState
196
+ );
175
197
  }
176
198
 
177
199
  export function socketTcpListenStart(id) {
178
- const socket = tcpSockets.get(id);
179
- if (socket.state !== SOCKET_STATE_BOUND) throw "invalid-state";
180
- const { handle } = socket;
181
- socket.state = SOCKET_STATE_LISTEN;
182
- socket.future = createFuture(
183
- new Promise((resolve, reject) => {
184
- const server = new Server({ pauseOnConnect: true, allowHalfOpen: true });
185
- function handleErr(err) {
186
- server.off("listening", handleListen);
187
- reject(convertSocketError(err));
188
- }
189
- function handleListen() {
190
- server.off("error", handleErr);
191
- server.on("connection", (tcpSocket) => {
192
- pollStateReady(socket.pollState);
193
- const pollState = createReadableStreamPollState(tcpSocket);
194
- socket.pendingAccepts.push({ tcpSocket, err: null, pollState });
195
- });
196
- server.on("error", (err) => {
197
- pollStateReady(socket.pollState);
198
- socket.pendingAccepts.push({ tcpSocket: null, err, pollState: null });
199
- });
200
- resolve();
201
- }
202
- server.once("listening", handleListen);
203
- server.once("error", handleErr);
204
- server.listen(handle, socket.listenBacklogSize);
205
- }),
206
- socket.pollState
207
- );
200
+ const socket = tcpSockets.get(id);
201
+ if (socket.state !== SOCKET_STATE_BOUND) {
202
+ throw 'invalid-state';
203
+ }
204
+ const { handle } = socket;
205
+ socket.state = SOCKET_STATE_LISTEN;
206
+ socket.future = createFuture(
207
+ new Promise((resolve, reject) => {
208
+ const server = new Server({
209
+ pauseOnConnect: true,
210
+ allowHalfOpen: true,
211
+ });
212
+ function handleErr(err) {
213
+ server.off('listening', handleListen);
214
+ reject(convertSocketError(err));
215
+ }
216
+ function handleListen() {
217
+ server.off('error', handleErr);
218
+ server.on('connection', (tcpSocket) => {
219
+ pollStateReady(socket.pollState);
220
+ const pollState = createReadableStreamPollState(tcpSocket);
221
+ socket.pendingAccepts.push({
222
+ tcpSocket,
223
+ err: null,
224
+ pollState,
225
+ });
226
+ });
227
+ server.on('error', (err) => {
228
+ pollStateReady(socket.pollState);
229
+ socket.pendingAccepts.push({
230
+ tcpSocket: null,
231
+ err,
232
+ pollState: null,
233
+ });
234
+ });
235
+ resolve();
236
+ }
237
+ server.once('listening', handleListen);
238
+ server.once('error', handleErr);
239
+ server.listen(handle, socket.listenBacklogSize);
240
+ }),
241
+ socket.pollState
242
+ );
208
243
  }
209
244
 
210
245
  export function socketTcpAccept(id) {
211
- const socket = tcpSockets.get(id);
212
- if (socket.state !== SOCKET_STATE_LISTENER) throw "invalid-state";
213
- if (socket.pendingAccepts.length === 0) throw "would-block";
214
- const accept = socket.pendingAccepts.shift();
215
- if (accept.err) {
216
- socket.state = SOCKET_STATE_CLOSED;
217
- throw convertSocketError(accept.err);
218
- }
219
- if (socket.pendingAccepts.length === 0) socket.pollState.ready = false;
220
- tcpSockets.set(++tcpSocketCnt, {
221
- state: SOCKET_STATE_CONNECTION,
222
- future: null,
223
- tcpSocket: accept.tcpSocket,
224
- listenBacklogSize: 128,
225
- handle: accept.tcpSocket._handle,
226
- pendingAccepts: [],
227
- pollState: accept.pollState,
228
- });
229
- return [
230
- tcpSocketCnt,
231
- createReadableStream(accept.tcpSocket, accept.pollState),
232
- createWritableStream(accept.tcpSocket),
233
- ];
246
+ const socket = tcpSockets.get(id);
247
+ if (socket.state !== SOCKET_STATE_LISTENER) {
248
+ throw 'invalid-state';
249
+ }
250
+ if (socket.pendingAccepts.length === 0) {
251
+ throw 'would-block';
252
+ }
253
+ const accept = socket.pendingAccepts.shift();
254
+ if (accept.err) {
255
+ socket.state = SOCKET_STATE_CLOSED;
256
+ throw convertSocketError(accept.err);
257
+ }
258
+ if (socket.pendingAccepts.length === 0) {
259
+ socket.pollState.ready = false;
260
+ }
261
+ tcpSockets.set(++tcpSocketCnt, {
262
+ state: SOCKET_STATE_CONNECTION,
263
+ future: null,
264
+ tcpSocket: accept.tcpSocket,
265
+ listenBacklogSize: 128,
266
+ handle: accept.tcpSocket._handle,
267
+ pendingAccepts: [],
268
+ pollState: accept.pollState,
269
+ });
270
+ return [
271
+ tcpSocketCnt,
272
+ createReadableStream(accept.tcpSocket, accept.pollState),
273
+ createWritableStream(accept.tcpSocket),
274
+ ];
234
275
  }
235
276
 
236
277
  export function socketTcpSetListenBacklogSize(id, backlogSize) {
237
- const socket = tcpSockets.get(id);
238
- if (
239
- socket.state === SOCKET_STATE_LISTEN ||
240
- socket.state === SOCKET_STATE_LISTENER
241
- )
242
- throw "not-supported";
243
- if (
244
- socket.state !== SOCKET_STATE_INIT &&
245
- socket.state !== SOCKET_STATE_BIND &&
246
- socket.state !== SOCKET_STATE_BOUND
247
- )
248
- throw "invalid-state";
249
- socket.listenBacklogSize = Number(backlogSize);
278
+ const socket = tcpSockets.get(id);
279
+ if (
280
+ socket.state === SOCKET_STATE_LISTEN ||
281
+ socket.state === SOCKET_STATE_LISTENER
282
+ ) {
283
+ throw 'not-supported';
284
+ }
285
+ if (
286
+ socket.state !== SOCKET_STATE_INIT &&
287
+ socket.state !== SOCKET_STATE_BIND &&
288
+ socket.state !== SOCKET_STATE_BOUND
289
+ ) {
290
+ throw 'invalid-state';
291
+ }
292
+ socket.listenBacklogSize = Number(backlogSize);
250
293
  }
251
294
 
252
295
  export function socketTcpGetLocalAddress(id) {
253
- const { handle } = tcpSockets.get(id);
254
- const out = {};
255
- const code = handle.getsockname(out);
256
- if (code !== 0) throw convertSocketErrorCode(-code);
257
- return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
296
+ const { handle } = tcpSockets.get(id);
297
+ const out = {};
298
+ const code = handle.getsockname(out);
299
+ if (code !== 0) {
300
+ throw convertSocketErrorCode(-code);
301
+ }
302
+ return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
258
303
  }
259
304
 
260
305
  export function socketTcpGetRemoteAddress(id) {
261
- const { handle } = tcpSockets.get(id);
262
- const out = {};
263
- const code = handle.getpeername(out);
264
- if (code !== 0) throw convertSocketErrorCode(-code);
265
- return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
306
+ const { handle } = tcpSockets.get(id);
307
+ const out = {};
308
+ const code = handle.getpeername(out);
309
+ if (code !== 0) {
310
+ throw convertSocketErrorCode(-code);
311
+ }
312
+ return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
266
313
  }
267
314
 
268
315
  export function socketTcpShutdown(id, _shutdownType) {
269
- const socket = tcpSockets.get(id);
270
- if (socket.state !== SOCKET_STATE_CONNECTION) throw "invalid-state";
271
- if (win && socket.tcpSocket.destroySoon)
272
- socket.tcpSocket.destroySoon();
273
- else
274
- socket.tcpSocket.destroy();
316
+ const socket = tcpSockets.get(id);
317
+ if (socket.state !== SOCKET_STATE_CONNECTION) {
318
+ throw 'invalid-state';
319
+ }
320
+ if (win && socket.tcpSocket.destroySoon) {
321
+ socket.tcpSocket.destroySoon();
322
+ } else {
323
+ socket.tcpSocket.destroy();
324
+ }
275
325
  }
276
326
 
277
327
  export function socketTcpSetKeepAlive(id, { keepAlive, keepAliveIdleTime }) {
278
- const { handle } = tcpSockets.get(id);
279
- const code = handle.setKeepAlive(
280
- keepAlive,
281
- Number(keepAliveIdleTime / 1_000_000_000n)
282
- );
283
- if (code !== 0) throw convertSocketErrorCode(-code);
328
+ const { handle } = tcpSockets.get(id);
329
+ const code = handle.setKeepAlive(
330
+ keepAlive,
331
+ Number(keepAliveIdleTime / 1_000_000_000n)
332
+ );
333
+ if (code !== 0) {
334
+ throw convertSocketErrorCode(-code);
335
+ }
284
336
  }
285
337
 
286
338
  export function socketTcpDispose(id) {
287
- const socket = tcpSockets.get(id);
288
- verifyPollsDroppedForDrop(socket.pollState, "tcp socket");
289
- socket.handle.close();
290
- tcpSockets.delete(id);
339
+ const socket = tcpSockets.get(id);
340
+ verifyPollsDroppedForDrop(socket.pollState, 'tcp socket');
341
+ socket.handle.close();
342
+ tcpSockets.delete(id);
291
343
  }