@bytecodealliance/preview2-shim 0.0.16 → 0.0.18

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.
@@ -12,12 +12,13 @@ export namespace WasiSocketsTcp {
12
12
  * Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.
13
13
  *
14
14
  * # Typical `start` errors
15
- * - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL)
16
- * - `already-bound`: The socket is already bound. (EINVAL)
17
- * - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
15
+ * - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
16
+ * - `invalid-argument`: `local-address` is not a unicast address. (EINVAL)
17
+ * - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL)
18
+ * - `invalid-state`: The socket is already bound. (EINVAL)
18
19
  *
19
20
  * # Typical `finish` errors
20
- * - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
21
+ * - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
21
22
  * - `address-in-use`: Address is already in use. (EADDRINUSE)
22
23
  * - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
23
24
  * - `not-in-progress`: A `bind` operation is not in progress.
@@ -29,8 +30,7 @@ export namespace WasiSocketsTcp {
29
30
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind>
30
31
  * - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html>
31
32
  */
32
- export function startBind(this_: TcpSocket, network: Network, localAddress: IpSocketAddress): void;
33
- export function finishBind(this_: TcpSocket): void;
33
+ export { TcpSocket };
34
34
  /**
35
35
  * Connect to a remote endpoint.
36
36
  *
@@ -38,21 +38,33 @@ export namespace WasiSocketsTcp {
38
38
  * - the socket is transitioned into the Connection state
39
39
  * - a pair of streams is returned that can be used to read & write to the connection
40
40
  *
41
+ * POSIX mentions:
42
+ * > If connect() fails, the state of the socket is unspecified. Conforming applications should
43
+ * > close the file descriptor and create a new socket before attempting to reconnect.
44
+ *
45
+ * WASI prescribes the following behavior:
46
+ * - If `connect` fails because an input/state validation error, the socket should remain usable.
47
+ * - If a connection was actually attempted but failed, the socket should become unusable for further network communication.
48
+ * Besides `drop`, any method after such a failure may return an error.
49
+ *
41
50
  * # Typical `start` errors
42
- * - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
43
- * - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows)
44
- * - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows)
45
- * - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`.
46
- * - `already-connected`: The socket is already in the Connection state. (EISCONN)
47
- * - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
48
- * - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
51
+ * - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
52
+ * - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
53
+ * - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
54
+ * - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
55
+ * - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows)
56
+ * - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows)
57
+ * - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`.
58
+ * - `invalid-state`: The socket is already in the Connection state. (EISCONN)
59
+ * - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
49
60
  *
50
61
  * # Typical `finish` errors
51
62
  * - `timeout`: Connection timed out. (ETIMEDOUT)
52
63
  * - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED)
53
64
  * - `connection-reset`: The connection was reset. (ECONNRESET)
65
+ * - `connection-aborted`: The connection was aborted. (ECONNABORTED)
54
66
  * - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
55
- * - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
67
+ * - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
56
68
  * - `not-in-progress`: A `connect` operation is not in progress.
57
69
  * - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
58
70
  *
@@ -62,13 +74,6 @@ export namespace WasiSocketsTcp {
62
74
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect>
63
75
  * - <https://man.freebsd.org/cgi/man.cgi?connect>
64
76
  */
65
- export function startConnect(this_: TcpSocket, network: Network, remoteAddress: IpSocketAddress): void;
66
- /**
67
- * Note: the returned `input-stream` and `output-stream` are child
68
- * resources of the `tcp-socket`. Implementations may trap if the
69
- * `tcp-socket` is dropped before both of these streams are dropped.
70
- */
71
- export function finishConnect(this_: TcpSocket): [InputStream, OutputStream];
72
77
  /**
73
78
  * Start listening for new connections.
74
79
  *
@@ -79,13 +84,12 @@ export namespace WasiSocketsTcp {
79
84
  * - the socket must already be explicitly bound.
80
85
  *
81
86
  * # Typical `start` errors
82
- * - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ)
83
- * - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
84
- * - `already-listening`: The socket is already in the Listener state.
85
- * - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD)
87
+ * - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ)
88
+ * - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
89
+ * - `invalid-state`: The socket is already in the Listener state.
86
90
  *
87
91
  * # Typical `finish` errors
88
- * - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
92
+ * - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
89
93
  * - `not-in-progress`: A `listen` operation is not in progress.
90
94
  * - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
91
95
  *
@@ -95,25 +99,26 @@ export namespace WasiSocketsTcp {
95
99
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen>
96
100
  * - <https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2>
97
101
  */
98
- export function startListen(this_: TcpSocket): void;
99
- export function finishListen(this_: TcpSocket): void;
100
102
  /**
101
103
  * Accept a new client socket.
102
104
  *
103
- * The returned socket is bound and in the Connection state.
105
+ * The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:
106
+ * - `address-family`
107
+ * - `ipv6-only`
108
+ * - `keep-alive`
109
+ * - `no-delay`
110
+ * - `unicast-hop-limit`
111
+ * - `receive-buffer-size`
112
+ * - `send-buffer-size`
104
113
  *
105
114
  * On success, this function returns the newly accepted client socket along with
106
115
  * a pair of streams that can be used to read & write to the connection.
107
116
  *
108
- * Note: the returned `input-stream` and `output-stream` are child
109
- * resources of the returned `tcp-socket`. Implementations may trap if the
110
- * `tcp-socket` is dropped before its child streams are dropped.
111
- *
112
117
  * # Typical errors
113
- * - `not-listening`: Socket is not in the Listener state. (EINVAL)
114
- * - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
115
- *
116
- * Host implementations must skip over transient errors returned by the native accept syscall.
118
+ * - `invalid-state`: Socket is not in the Listener state. (EINVAL)
119
+ * - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
120
+ * - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
121
+ * - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
117
122
  *
118
123
  * # References
119
124
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html>
@@ -121,12 +126,17 @@ export namespace WasiSocketsTcp {
121
126
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept>
122
127
  * - <https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2>
123
128
  */
124
- export function accept(this_: TcpSocket): [TcpSocket, InputStream, OutputStream];
125
129
  /**
126
130
  * Get the bound local address.
127
131
  *
132
+ * POSIX mentions:
133
+ * > If the socket has not been bound to a local name, the value
134
+ * > stored in the object pointed to by `address` is unspecified.
135
+ *
136
+ * WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet.
137
+ *
128
138
  * # Typical errors
129
- * - `not-bound`: The socket is not bound to any local address.
139
+ * - `invalid-state`: The socket is not bound to any local address.
130
140
  *
131
141
  * # References
132
142
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html>
@@ -134,12 +144,11 @@ export namespace WasiSocketsTcp {
134
144
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname>
135
145
  * - <https://man.freebsd.org/cgi/man.cgi?getsockname>
136
146
  */
137
- export function localAddress(this_: TcpSocket): IpSocketAddress;
138
147
  /**
139
- * Get the bound remote address.
148
+ * Get the remote address.
140
149
  *
141
150
  * # Typical errors
142
- * - `not-connected`: The socket is not connected to a remote address. (ENOTCONN)
151
+ * - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN)
143
152
  *
144
153
  * # References
145
154
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html>
@@ -147,60 +156,44 @@ export namespace WasiSocketsTcp {
147
156
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername>
148
157
  * - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1>
149
158
  */
150
- export function remoteAddress(this_: TcpSocket): IpSocketAddress;
151
159
  /**
152
160
  * Whether this is a IPv4 or IPv6 socket.
153
161
  *
154
162
  * Equivalent to the SO_DOMAIN socket option.
155
163
  */
156
- export function addressFamily(this_: TcpSocket): IpAddressFamily;
157
164
  /**
158
165
  * Whether IPv4 compatibility (dual-stack) mode is disabled or not.
159
166
  *
160
167
  * Equivalent to the IPV6_V6ONLY socket option.
161
168
  *
162
169
  * # Typical errors
163
- * - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket.
164
- * - `already-bound`: (set) The socket is already bound.
170
+ * - `invalid-state`: (set) The socket is already bound.
171
+ * - `not-supported`: (get/set) `this` socket is an IPv4 socket.
165
172
  * - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
166
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
167
173
  */
168
- export function ipv6Only(this_: TcpSocket): boolean;
169
- export function setIpv6Only(this_: TcpSocket, value: boolean): void;
170
174
  /**
171
175
  * Hints the desired listen queue size. Implementations are free to ignore this.
172
176
  *
173
177
  * # Typical errors
174
- * - `already-connected`: (set) The socket is already in the Connection state.
175
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
178
+ * - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen.
179
+ * - `invalid-state`: (set) The socket is already in the Connection state.
176
180
  */
177
- export function setListenBacklogSize(this_: TcpSocket, value: bigint): void;
178
181
  /**
179
182
  * Equivalent to the SO_KEEPALIVE socket option.
180
- *
181
- * # Typical errors
182
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
183
183
  */
184
- export function keepAlive(this_: TcpSocket): boolean;
185
- export function setKeepAlive(this_: TcpSocket, value: boolean): void;
186
184
  /**
187
185
  * Equivalent to the TCP_NODELAY socket option.
188
186
  *
189
- * # Typical errors
190
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
187
+ * The default value is `false`.
191
188
  */
192
- export function noDelay(this_: TcpSocket): boolean;
193
- export function setNoDelay(this_: TcpSocket, value: boolean): void;
194
189
  /**
195
190
  * Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
196
191
  *
197
192
  * # Typical errors
198
- * - `already-connected`: (set) The socket is already in the Connection state.
199
- * - `already-listening`: (set) The socket is already in the Listener state.
200
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
193
+ * - `invalid-argument`: (set) The TTL value must be 1 or higher.
194
+ * - `invalid-state`: (set) The socket is already in the Connection state.
195
+ * - `invalid-state`: (set) The socket is already in the Listener state.
201
196
  */
202
- export function unicastHopLimit(this_: TcpSocket): number;
203
- export function setUnicastHopLimit(this_: TcpSocket, value: number): void;
204
197
  /**
205
198
  * The kernel buffer space reserved for sends/receives on this socket.
206
199
  *
@@ -214,25 +207,15 @@ export namespace WasiSocketsTcp {
214
207
  * Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.
215
208
  *
216
209
  * # Typical errors
217
- * - `already-connected`: (set) The socket is already in the Connection state.
218
- * - `already-listening`: (set) The socket is already in the Listener state.
219
- * - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
210
+ * - `invalid-state`: (set) The socket is already in the Connection state.
211
+ * - `invalid-state`: (set) The socket is already in the Listener state.
220
212
  */
221
- export function receiveBufferSize(this_: TcpSocket): bigint;
222
- export function setReceiveBufferSize(this_: TcpSocket, value: bigint): void;
223
- export function sendBufferSize(this_: TcpSocket): bigint;
224
- export function setSendBufferSize(this_: TcpSocket, value: bigint): void;
225
213
  /**
226
214
  * Create a `pollable` which will resolve once the socket is ready for I/O.
227
215
  *
228
- * The created `pollable` is a child resource of the `tcp-socket`.
229
- * Implementations may trap if the `tcp-socket` is dropped before all
230
- * derived `pollable`s created with this function are dropped.
231
- *
232
216
  * Note: this function is here for WASI Preview2 only.
233
217
  * It's planned to be removed when `future` is natively supported in Preview3.
234
218
  */
235
- export function subscribe(this_: TcpSocket): Pollable;
236
219
  /**
237
220
  * Initiate a graceful shutdown.
238
221
  *
@@ -246,7 +229,7 @@ export namespace WasiSocketsTcp {
246
229
  * The shutdown function does not close (drop) the socket.
247
230
  *
248
231
  * # Typical errors
249
- * - `not-connected`: The socket is not in the Connection state. (ENOTCONN)
232
+ * - `invalid-state`: The socket is not in the Connection state. (ENOTCONN)
250
233
  *
251
234
  * # References
252
235
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html>
@@ -254,21 +237,12 @@ export namespace WasiSocketsTcp {
254
237
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown>
255
238
  * - <https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2>
256
239
  */
257
- export function shutdown(this_: TcpSocket, shutdownType: ShutdownType): void;
258
- /**
259
- * Dispose of the specified `tcp-socket`, after which it may no longer be used.
260
- *
261
- * Similar to the POSIX `close` function.
262
- *
263
- * Note: this function is scheduled to be removed when Resources are natively supported in Wit.
264
- */
265
- export function dropTcpSocket(this_: TcpSocket): void;
266
240
  }
267
241
  import type { InputStream } from '../interfaces/wasi-io-streams';
268
242
  export { InputStream };
269
243
  import type { OutputStream } from '../interfaces/wasi-io-streams';
270
244
  export { OutputStream };
271
- import type { Pollable } from '../interfaces/wasi-poll-poll';
245
+ import type { Pollable } from '../interfaces/wasi-io-poll';
272
246
  export { Pollable };
273
247
  import type { Network } from '../interfaces/wasi-sockets-network';
274
248
  export { Network };
@@ -278,10 +252,6 @@ import type { IpSocketAddress } from '../interfaces/wasi-sockets-network';
278
252
  export { IpSocketAddress };
279
253
  import type { IpAddressFamily } from '../interfaces/wasi-sockets-network';
280
254
  export { IpAddressFamily };
281
- /**
282
- * A TCP socket handle.
283
- */
284
- export type TcpSocket = number;
285
255
  /**
286
256
  * # Variants
287
257
  *
@@ -296,3 +266,31 @@ export type TcpSocket = number;
296
266
  * Similar to `SHUT_RDWR` in POSIX.
297
267
  */
298
268
  export type ShutdownType = 'receive' | 'send' | 'both';
269
+
270
+ export class TcpSocket {
271
+ startBind(network: Network, localAddress: IpSocketAddress): void;
272
+ finishBind(): void;
273
+ startConnect(network: Network, remoteAddress: IpSocketAddress): void;
274
+ finishConnect(): [InputStream, OutputStream];
275
+ startListen(): void;
276
+ finishListen(): void;
277
+ accept(): [TcpSocket, InputStream, OutputStream];
278
+ localAddress(): IpSocketAddress;
279
+ remoteAddress(): IpSocketAddress;
280
+ addressFamily(): IpAddressFamily;
281
+ ipv6Only(): boolean;
282
+ setIpv6Only(value: boolean): void;
283
+ setListenBacklogSize(value: bigint): void;
284
+ keepAlive(): boolean;
285
+ setKeepAlive(value: boolean): void;
286
+ noDelay(): boolean;
287
+ setNoDelay(value: boolean): void;
288
+ unicastHopLimit(): number;
289
+ setUnicastHopLimit(value: number): void;
290
+ receiveBufferSize(): bigint;
291
+ setReceiveBufferSize(value: bigint): void;
292
+ sendBufferSize(): bigint;
293
+ setSendBufferSize(value: bigint): void;
294
+ subscribe(): Pollable;
295
+ shutdown(shutdownType: ShutdownType): void;
296
+ }
@@ -11,9 +11,8 @@ export namespace WasiSocketsUdpCreateSocket {
11
11
  * All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.
12
12
  *
13
13
  * # Typical errors
14
- * - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP)
15
- * - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT)
16
- * - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
14
+ * - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT)
15
+ * - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
17
16
  *
18
17
  * # References:
19
18
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html>
@@ -11,12 +11,11 @@ export namespace WasiSocketsUdp {
11
11
  * Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.
12
12
  *
13
13
  * # Typical `start` errors
14
- * - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL)
15
- * - `already-bound`: The socket is already bound. (EINVAL)
16
- * - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY)
14
+ * - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
15
+ * - `invalid-state`: The socket is already bound. (EINVAL)
17
16
  *
18
17
  * # Typical `finish` errors
19
- * - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
18
+ * - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
20
19
  * - `address-in-use`: Address is already in use. (EADDRINUSE)
21
20
  * - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
22
21
  * - `not-in-progress`: A `bind` operation is not in progress.
@@ -28,8 +27,7 @@ export namespace WasiSocketsUdp {
28
27
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind>
29
28
  * - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html>
30
29
  */
31
- export function startBind(this_: UdpSocket, network: Network, localAddress: IpSocketAddress): void;
32
- export function finishBind(this_: UdpSocket): void;
30
+ export { UdpSocket };
33
31
  /**
34
32
  * Set the destination address.
35
33
  *
@@ -44,14 +42,14 @@ export namespace WasiSocketsUdp {
44
42
  * Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.
45
43
  *
46
44
  * # Typical `start` errors
47
- * - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
48
- * - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
49
- * - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
50
- * - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`.
51
- * - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY)
45
+ * - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
46
+ * - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
47
+ * - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
48
+ * - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
49
+ * - `invalid-argument`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`.
52
50
  *
53
51
  * # Typical `finish` errors
54
- * - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
52
+ * - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
55
53
  * - `not-in-progress`: A `connect` operation is not in progress.
56
54
  * - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
57
55
  *
@@ -61,8 +59,6 @@ export namespace WasiSocketsUdp {
61
59
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect>
62
60
  * - <https://man.freebsd.org/cgi/man.cgi?connect>
63
61
  */
64
- export function startConnect(this_: UdpSocket, network: Network, remoteAddress: IpSocketAddress): void;
65
- export function finishConnect(this_: UdpSocket): void;
66
62
  /**
67
63
  * Receive messages on the socket.
68
64
  *
@@ -71,7 +67,7 @@ export namespace WasiSocketsUdp {
71
67
  * If `max-results` is 0, this function returns successfully with an empty list.
72
68
  *
73
69
  * # Typical errors
74
- * - `not-bound`: The socket is not bound to any local address. (EINVAL)
70
+ * - `invalid-state`: The socket is not bound to any local address. (EINVAL)
75
71
  * - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
76
72
  * - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
77
73
  *
@@ -85,7 +81,6 @@ export namespace WasiSocketsUdp {
85
81
  * - <https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85)>
86
82
  * - <https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2>
87
83
  */
88
- export function receive(this_: UdpSocket, maxResults: bigint): Datagram[];
89
84
  /**
90
85
  * Send messages on the socket.
91
86
  *
@@ -102,11 +97,12 @@ export namespace WasiSocketsUdp {
102
97
  * call `remote-address` to get their address.
103
98
  *
104
99
  * # Typical errors
105
- * - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
106
- * - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
107
- * - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
108
- * - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN)
109
- * - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
100
+ * - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
101
+ * - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
102
+ * - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
103
+ * - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
104
+ * - `invalid-argument`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN)
105
+ * - `invalid-state`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
110
106
  * - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
111
107
  * - `datagram-too-large`: The datagram is too large. (EMSGSIZE)
112
108
  * - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
@@ -121,12 +117,17 @@ export namespace WasiSocketsUdp {
121
117
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg>
122
118
  * - <https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2>
123
119
  */
124
- export function send(this_: UdpSocket, datagrams: Datagram[]): bigint;
125
120
  /**
126
121
  * Get the current bound address.
127
122
  *
123
+ * POSIX mentions:
124
+ * > If the socket has not been bound to a local name, the value
125
+ * > stored in the object pointed to by `address` is unspecified.
126
+ *
127
+ * WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet.
128
+ *
128
129
  * # Typical errors
129
- * - `not-bound`: The socket is not bound to any local address.
130
+ * - `invalid-state`: The socket is not bound to any local address.
130
131
  *
131
132
  * # References
132
133
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html>
@@ -134,12 +135,11 @@ export namespace WasiSocketsUdp {
134
135
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname>
135
136
  * - <https://man.freebsd.org/cgi/man.cgi?getsockname>
136
137
  */
137
- export function localAddress(this_: UdpSocket): IpSocketAddress;
138
138
  /**
139
139
  * Get the address set with `connect`.
140
140
  *
141
141
  * # Typical errors
142
- * - `not-connected`: The socket is not connected to a remote address. (ENOTCONN)
142
+ * - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN)
143
143
  *
144
144
  * # References
145
145
  * - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html>
@@ -147,34 +147,24 @@ export namespace WasiSocketsUdp {
147
147
  * - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername>
148
148
  * - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1>
149
149
  */
150
- export function remoteAddress(this_: UdpSocket): IpSocketAddress;
151
150
  /**
152
151
  * Whether this is a IPv4 or IPv6 socket.
153
152
  *
154
153
  * Equivalent to the SO_DOMAIN socket option.
155
154
  */
156
- export function addressFamily(this_: UdpSocket): IpAddressFamily;
157
155
  /**
158
156
  * Whether IPv4 compatibility (dual-stack) mode is disabled or not.
159
157
  *
160
158
  * Equivalent to the IPV6_V6ONLY socket option.
161
159
  *
162
160
  * # Typical errors
163
- * - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket.
164
- * - `already-bound`: (set) The socket is already bound.
161
+ * - `not-supported`: (get/set) `this` socket is an IPv4 socket.
162
+ * - `invalid-state`: (set) The socket is already bound.
165
163
  * - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
166
- * - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY)
167
164
  */
168
- export function ipv6Only(this_: UdpSocket): boolean;
169
- export function setIpv6Only(this_: UdpSocket, value: boolean): void;
170
165
  /**
171
166
  * Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
172
- *
173
- * # Typical errors
174
- * - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY)
175
167
  */
176
- export function unicastHopLimit(this_: UdpSocket): number;
177
- export function setUnicastHopLimit(this_: UdpSocket, value: number): void;
178
168
  /**
179
169
  * The kernel buffer space reserved for sends/receives on this socket.
180
170
  *
@@ -186,29 +176,15 @@ export namespace WasiSocketsUdp {
186
176
  * for internal metadata structures.
187
177
  *
188
178
  * Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.
189
- *
190
- * # Typical errors
191
- * - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY)
192
179
  */
193
- export function receiveBufferSize(this_: UdpSocket): bigint;
194
- export function setReceiveBufferSize(this_: UdpSocket, value: bigint): void;
195
- export function sendBufferSize(this_: UdpSocket): bigint;
196
- export function setSendBufferSize(this_: UdpSocket, value: bigint): void;
197
180
  /**
198
181
  * Create a `pollable` which will resolve once the socket is ready for I/O.
199
182
  *
200
183
  * Note: this function is here for WASI Preview2 only.
201
184
  * It's planned to be removed when `future` is natively supported in Preview3.
202
185
  */
203
- export function subscribe(this_: UdpSocket): Pollable;
204
- /**
205
- * Dispose of the specified `udp-socket`, after which it may no longer be used.
206
- *
207
- * Note: this function is scheduled to be removed when Resources are natively supported in Wit.
208
- */
209
- export function dropUdpSocket(this_: UdpSocket): void;
210
186
  }
211
- import type { Pollable } from '../interfaces/wasi-poll-poll';
187
+ import type { Pollable } from '../interfaces/wasi-io-poll';
212
188
  export { Pollable };
213
189
  import type { Network } from '../interfaces/wasi-sockets-network';
214
190
  export { Network };
@@ -218,11 +194,28 @@ import type { IpSocketAddress } from '../interfaces/wasi-sockets-network';
218
194
  export { IpSocketAddress };
219
195
  import type { IpAddressFamily } from '../interfaces/wasi-sockets-network';
220
196
  export { IpAddressFamily };
221
- /**
222
- * A UDP socket handle.
223
- */
224
- export type UdpSocket = number;
225
197
  export interface Datagram {
226
198
  data: Uint8Array,
227
199
  remoteAddress: IpSocketAddress,
228
200
  }
201
+
202
+ export class UdpSocket {
203
+ startBind(network: Network, localAddress: IpSocketAddress): void;
204
+ finishBind(): void;
205
+ startConnect(network: Network, remoteAddress: IpSocketAddress): void;
206
+ finishConnect(): void;
207
+ receive(maxResults: bigint): Datagram[];
208
+ send(datagrams: Datagram[]): bigint;
209
+ localAddress(): IpSocketAddress;
210
+ remoteAddress(): IpSocketAddress;
211
+ addressFamily(): IpAddressFamily;
212
+ ipv6Only(): boolean;
213
+ setIpv6Only(value: boolean): void;
214
+ unicastHopLimit(): number;
215
+ setUnicastHopLimit(value: number): void;
216
+ receiveBufferSize(): bigint;
217
+ setReceiveBufferSize(value: bigint): void;
218
+ sendBufferSize(): bigint;
219
+ setSendBufferSize(value: bigint): void;
220
+ subscribe(): Pollable;
221
+ }
@@ -13,8 +13,8 @@ import { WasiClocksTimezone } from './interfaces/wasi-clocks-timezone';
13
13
  import { WasiClocksWallClock } from './interfaces/wasi-clocks-wall-clock';
14
14
  import { WasiFilesystemPreopens } from './interfaces/wasi-filesystem-preopens';
15
15
  import { WasiFilesystemTypes } from './interfaces/wasi-filesystem-types';
16
+ import { WasiIoPoll } from './interfaces/wasi-io-poll';
16
17
  import { WasiIoStreams } from './interfaces/wasi-io-streams';
17
- import { WasiPollPoll } from './interfaces/wasi-poll-poll';
18
18
  import { WasiRandomInsecure } from './interfaces/wasi-random-insecure';
19
19
  import { WasiRandomInsecureSeed } from './interfaces/wasi-random-insecure-seed';
20
20
  import { WasiRandomRandom } from './interfaces/wasi-random-random';
@@ -1,14 +0,0 @@
1
- const levels = ["trace", "debug", "info", "warn", "error", "critical"];
2
-
3
- let logLevel = levels.indexOf("warn");
4
-
5
- export const logging = {
6
- log(level, context, msg) {
7
- if (logLevel > levels.indexOf(level)) return;
8
- console[level](`(${context}) ${msg}\n`);
9
- }
10
- };
11
-
12
- export function setLevel(level) {
13
- logLevel = levels.indexOf(level);
14
- }
package/lib/http/error.js DELETED
@@ -1,11 +0,0 @@
1
- export class UnexpectedError extends Error {
2
- /** @type { import("../../types/interfaces/wasi-http-types").ErrorUnexpectedError } */
3
- payload;
4
- constructor(message = "unexpected-error") {
5
- super(message);
6
- this.payload = {
7
- tag: "unexpected-error",
8
- val: message,
9
- };
10
- }
11
- }