@bytecodealliance/preview2-shim 0.15.0 → 0.15.1
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/package.json +1 -1
- package/types/cli.d.ts +23 -0
- package/types/clocks.d.ts +5 -0
- package/types/filesystem.d.ts +5 -0
- package/types/http.d.ts +7 -0
- package/types/index.d.ts +15 -0
- package/types/interfaces/wasi-http-types.d.ts +29 -29
- package/types/interfaces/wasi-io-streams.d.ts +16 -5
- package/types/interfaces/wasi-sockets-network.d.ts +23 -3
- package/types/interfaces/wasi-sockets-tcp-create-socket.d.ts +2 -1
- package/types/interfaces/wasi-sockets-tcp.d.ts +73 -66
- package/types/interfaces/wasi-sockets-udp-create-socket.d.ts +1 -0
- package/types/interfaces/wasi-sockets-udp.d.ts +18 -30
- package/types/io.d.ts +7 -0
- package/types/random.d.ts +7 -0
- package/types/sockets.d.ts +15 -0
package/package.json
CHANGED
package/types/cli.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WasiCliEnvironment } from './interfaces/wasi-cli-environment.d.ts';
|
|
2
|
+
import type { WasiCliExit } from './interfaces/wasi-cli-exit.d.ts';
|
|
3
|
+
import type { WasiCliRun } from './interfaces/wasi-cli-run.d.ts';
|
|
4
|
+
import type { WasiCliStderr } from './interfaces/wasi-cli-stderr.d.ts';
|
|
5
|
+
import type { WasiCliStdin } from './interfaces/wasi-cli-stdin.d.ts';
|
|
6
|
+
import type { WasiCliStdout } from './interfaces/wasi-cli-stdout.d.ts';
|
|
7
|
+
import type { WasiCliTerminalInput } from './interfaces/wasi-cli-terminal-input.d.ts';
|
|
8
|
+
import type { WasiCliTerminalOutput } from './interfaces/wasi-cli-terminal-output.d.ts';
|
|
9
|
+
import type { WasiCliTerminalStderr } from './interfaces/wasi-cli-terminal-stderr.d.ts';
|
|
10
|
+
import type { WasiCliTerminalStdin } from './interfaces/wasi-cli-terminal-stdin.d.ts';
|
|
11
|
+
import type { WasiCliTerminalStdout } from './interfaces/wasi-cli-terminal-stdout.d.ts';
|
|
12
|
+
|
|
13
|
+
export const environment: typeof WasiCliEnvironment;
|
|
14
|
+
export const exit: typeof WasiCliExit;
|
|
15
|
+
export const run: typeof WasiCliRun;
|
|
16
|
+
export const stderr: typeof WasiCliStderr;
|
|
17
|
+
export const stdin: typeof WasiCliStdin;
|
|
18
|
+
export const stdout: typeof WasiCliStdout;
|
|
19
|
+
export const terminalInput: typeof WasiCliTerminalInput;
|
|
20
|
+
export const terminalOutput: typeof WasiCliTerminalOutput;
|
|
21
|
+
export const terminalStderr: typeof WasiCliTerminalStderr;
|
|
22
|
+
export const terminalStdin: typeof WasiCliTerminalStdin;
|
|
23
|
+
export const terminalStdout: typeof WasiCliTerminalStdout;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WasiClocksMonotonicClock } from './interfaces/wasi-clocks-monotonic-clock.d.ts';
|
|
2
|
+
import type { WasiClocksWallClock } from './interfaces/wasi-clocks-wall-clock.d.ts';
|
|
3
|
+
|
|
4
|
+
export const wallClock: typeof WasiClocksMonotonicClock;
|
|
5
|
+
export const monotonicClock: typeof WasiClocksWallClock;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WasiFilesystemPreopens } from './interfaces/wasi-filesystem-preopens.d.ts';
|
|
2
|
+
import type { WasiFilesystemTypes } from './interfaces/wasi-filesystem-types.d.ts';
|
|
3
|
+
|
|
4
|
+
export const preopens: typeof WasiFilesystemPreopens;
|
|
5
|
+
export const types: typeof WasiFilesystemTypes;
|
package/types/http.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WasiHttpIncomingHandler } from './interfaces/wasi-http-incoming-handler.d.ts';
|
|
2
|
+
import type { WasiHttpOutgoingHandler } from './interfaces/wasi-http-outgoing-handler.d.ts';
|
|
3
|
+
import type { WasiHttpTypes } from './interfaces/wasi-http-types.d.ts';
|
|
4
|
+
|
|
5
|
+
export const incomingHandler: typeof WasiHttpIncomingHandler;
|
|
6
|
+
export const outgoingHandler: typeof WasiHttpOutgoingHandler;
|
|
7
|
+
export const types: typeof WasiHttpTypes;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type * as WasiCli from "./cli.d.ts";
|
|
2
|
+
import type * as WasiClocks from './clocks.d.ts';
|
|
3
|
+
import type * as WasiFilesystem from './filesystem.d.ts';
|
|
4
|
+
import type * as WasiHttp from "./http.d.ts";
|
|
5
|
+
import type * as WasiIo from "./io.d.ts";
|
|
6
|
+
import type * as WasiRandom from "./random.d.ts";
|
|
7
|
+
import type * as WasiSockets from "./sockets.d.ts";
|
|
8
|
+
|
|
9
|
+
export const cli: typeof WasiCli;
|
|
10
|
+
export const clocks: typeof WasiClocks;
|
|
11
|
+
export const filesystem: typeof WasiFilesystem;
|
|
12
|
+
export const http: typeof WasiHttp;
|
|
13
|
+
export const io: typeof WasiIo;
|
|
14
|
+
export const random: typeof WasiRandom;
|
|
15
|
+
export const sockets: typeof WasiSockets;
|
|
@@ -629,6 +629,18 @@ export type Trailers = Fields;
|
|
|
629
629
|
export type StatusCode = number;
|
|
630
630
|
export type Result<T, E> = { tag: 'ok', val: T } | { tag: 'err', val: E };
|
|
631
631
|
|
|
632
|
+
export class ResponseOutparam {
|
|
633
|
+
static set(param: ResponseOutparam, response: Result<OutgoingResponse, ErrorCode>): void;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export class OutgoingResponse {
|
|
637
|
+
constructor(headers: Headers)
|
|
638
|
+
statusCode(): StatusCode;
|
|
639
|
+
setStatusCode(statusCode: StatusCode): void;
|
|
640
|
+
headers(): Headers;
|
|
641
|
+
body(): OutgoingBody;
|
|
642
|
+
}
|
|
643
|
+
|
|
632
644
|
export class OutgoingBody {
|
|
633
645
|
write(): OutputStream;
|
|
634
646
|
static finish(this_: OutgoingBody, trailers: Trailers | undefined): void;
|
|
@@ -640,50 +652,36 @@ export class Fields {
|
|
|
640
652
|
get(name: FieldKey): FieldValue[];
|
|
641
653
|
has(name: FieldKey): boolean;
|
|
642
654
|
set(name: FieldKey, value: FieldValue[]): void;
|
|
643
|
-
delete(name: FieldKey): void;
|
|
655
|
+
'delete'(name: FieldKey): void;
|
|
644
656
|
append(name: FieldKey, value: FieldValue): void;
|
|
645
657
|
entries(): [FieldKey, FieldValue][];
|
|
646
658
|
clone(): Fields;
|
|
647
659
|
}
|
|
648
660
|
|
|
649
|
-
export class FutureIncomingResponse {
|
|
650
|
-
subscribe(): Pollable;
|
|
651
|
-
get(): Result<Result<IncomingResponse, ErrorCode>, void> | undefined;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
export class IncomingRequest {
|
|
655
|
-
method(): Method;
|
|
656
|
-
pathWithQuery(): string | undefined;
|
|
657
|
-
scheme(): Scheme | undefined;
|
|
658
|
-
authority(): string | undefined;
|
|
659
|
-
headers(): Headers;
|
|
660
|
-
consume(): IncomingBody;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
661
|
export class IncomingBody {
|
|
664
662
|
stream(): InputStream;
|
|
665
663
|
static finish(this_: IncomingBody): FutureTrailers;
|
|
666
664
|
}
|
|
667
665
|
|
|
666
|
+
export class FutureIncomingResponse {
|
|
667
|
+
subscribe(): Pollable;
|
|
668
|
+
get(): Result<Result<IncomingResponse, ErrorCode>, void> | undefined;
|
|
669
|
+
}
|
|
670
|
+
|
|
668
671
|
export class FutureTrailers {
|
|
669
672
|
subscribe(): Pollable;
|
|
670
673
|
get(): Result<Result<Trailers | undefined, ErrorCode>, void> | undefined;
|
|
671
674
|
}
|
|
672
675
|
|
|
673
|
-
export class
|
|
674
|
-
|
|
676
|
+
export class IncomingRequest {
|
|
677
|
+
method(): Method;
|
|
678
|
+
pathWithQuery(): string | undefined;
|
|
679
|
+
scheme(): Scheme | undefined;
|
|
680
|
+
authority(): string | undefined;
|
|
675
681
|
headers(): Headers;
|
|
676
682
|
consume(): IncomingBody;
|
|
677
683
|
}
|
|
678
684
|
|
|
679
|
-
export class OutgoingResponse {
|
|
680
|
-
constructor(headers: Headers)
|
|
681
|
-
statusCode(): StatusCode;
|
|
682
|
-
setStatusCode(statusCode: StatusCode): void;
|
|
683
|
-
headers(): Headers;
|
|
684
|
-
body(): OutgoingBody;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
685
|
export class OutgoingRequest {
|
|
688
686
|
constructor(headers: Headers)
|
|
689
687
|
body(): OutgoingBody;
|
|
@@ -698,6 +696,12 @@ export class OutgoingRequest {
|
|
|
698
696
|
headers(): Headers;
|
|
699
697
|
}
|
|
700
698
|
|
|
699
|
+
export class IncomingResponse {
|
|
700
|
+
status(): StatusCode;
|
|
701
|
+
headers(): Headers;
|
|
702
|
+
consume(): IncomingBody;
|
|
703
|
+
}
|
|
704
|
+
|
|
701
705
|
export class RequestOptions {
|
|
702
706
|
constructor()
|
|
703
707
|
connectTimeout(): Duration | undefined;
|
|
@@ -707,7 +711,3 @@ export class RequestOptions {
|
|
|
707
711
|
betweenBytesTimeout(): Duration | undefined;
|
|
708
712
|
setBetweenBytesTimeout(duration: Duration | undefined): void;
|
|
709
713
|
}
|
|
710
|
-
|
|
711
|
-
export class ResponseOutparam {
|
|
712
|
-
static set(param: ResponseOutparam, response: Result<OutgoingResponse, ErrorCode>): void;
|
|
713
|
-
}
|
|
@@ -2,6 +2,11 @@ export namespace WasiIoStreams {
|
|
|
2
2
|
/**
|
|
3
3
|
* Perform a non-blocking read from the stream.
|
|
4
4
|
*
|
|
5
|
+
* When the source of a `read` is binary data, the bytes from the source
|
|
6
|
+
* are returned verbatim. When the source of a `read` is known to the
|
|
7
|
+
* implementation to be text, bytes containing the UTF-8 encoding of the
|
|
8
|
+
* text are returned.
|
|
9
|
+
*
|
|
5
10
|
* This function returns a list of bytes containing the read data,
|
|
6
11
|
* when successful. The returned list will contain up to `len` bytes;
|
|
7
12
|
* it may return fewer than requested, but not more. The list is
|
|
@@ -60,6 +65,12 @@ export namespace WasiIoStreams {
|
|
|
60
65
|
/**
|
|
61
66
|
* Perform a write. This function never blocks.
|
|
62
67
|
*
|
|
68
|
+
* When the destination of a `write` is binary data, the bytes from
|
|
69
|
+
* `contents` are written verbatim. When the destination of a `write` is
|
|
70
|
+
* known to the implementation to be text, the bytes of `contents` are
|
|
71
|
+
* transcoded from UTF-8 into the encoding of the destination and then
|
|
72
|
+
* written.
|
|
73
|
+
*
|
|
63
74
|
* Precondition: check-write gave permit of Ok(n) and contents has a
|
|
64
75
|
* length of less than or equal to n. Otherwise, this function will trap.
|
|
65
76
|
*
|
|
@@ -78,7 +89,7 @@ export namespace WasiIoStreams {
|
|
|
78
89
|
* let pollable = this.subscribe();
|
|
79
90
|
* while !contents.is_empty() {
|
|
80
91
|
* // Wait for the stream to become writable
|
|
81
|
-
*
|
|
92
|
+
* pollable.block();
|
|
82
93
|
* let Ok(n) = this.check-write(); // eliding error handling
|
|
83
94
|
* let len = min(n, contents.len());
|
|
84
95
|
* let (chunk, rest) = contents.split_at(len);
|
|
@@ -87,7 +98,7 @@ export namespace WasiIoStreams {
|
|
|
87
98
|
* }
|
|
88
99
|
* this.flush();
|
|
89
100
|
* // Wait for completion of `flush`
|
|
90
|
-
*
|
|
101
|
+
* pollable.block();
|
|
91
102
|
* // Check for any errors that arose during `flush`
|
|
92
103
|
* let _ = this.check-write(); // eliding error handling
|
|
93
104
|
* ```
|
|
@@ -123,7 +134,7 @@ export namespace WasiIoStreams {
|
|
|
123
134
|
/**
|
|
124
135
|
* Write zeroes to a stream.
|
|
125
136
|
*
|
|
126
|
-
*
|
|
137
|
+
* This should be used precisely like `write` with the exact same
|
|
127
138
|
* preconditions (must use check-write first), but instead of
|
|
128
139
|
* passing a list of bytes, you simply pass the number of zero-bytes
|
|
129
140
|
* that should be written.
|
|
@@ -141,7 +152,7 @@ export namespace WasiIoStreams {
|
|
|
141
152
|
* let pollable = this.subscribe();
|
|
142
153
|
* while num_zeroes != 0 {
|
|
143
154
|
* // Wait for the stream to become writable
|
|
144
|
-
*
|
|
155
|
+
* pollable.block();
|
|
145
156
|
* let Ok(n) = this.check-write(); // eliding error handling
|
|
146
157
|
* let len = min(n, num_zeroes);
|
|
147
158
|
* this.write-zeroes(len); // eliding error handling
|
|
@@ -149,7 +160,7 @@ export namespace WasiIoStreams {
|
|
|
149
160
|
* }
|
|
150
161
|
* this.flush();
|
|
151
162
|
* // Wait for completion of `flush`
|
|
152
|
-
*
|
|
163
|
+
* pollable.block();
|
|
153
164
|
* // Check for any errors that arose during `flush`
|
|
154
165
|
* let _ = this.check-write(); // eliding error handling
|
|
155
166
|
* ```
|
|
@@ -76,15 +76,17 @@ export namespace WasiSocketsNetwork {
|
|
|
76
76
|
* The remote address is not reachable
|
|
77
77
|
* ## `"connection-refused"`
|
|
78
78
|
*
|
|
79
|
-
* The connection was forcefully rejected
|
|
79
|
+
* The TCP connection was forcefully rejected
|
|
80
80
|
* ## `"connection-reset"`
|
|
81
81
|
*
|
|
82
|
-
* The connection was reset.
|
|
82
|
+
* The TCP connection was reset.
|
|
83
83
|
* ## `"connection-aborted"`
|
|
84
84
|
*
|
|
85
|
-
* A connection was aborted.
|
|
85
|
+
* A TCP connection was aborted.
|
|
86
86
|
* ## `"datagram-too-large"`
|
|
87
87
|
*
|
|
88
|
+
* The size of a datagram sent to a UDP socket exceeded the maximum
|
|
89
|
+
* supported size.
|
|
88
90
|
* ## `"name-unresolvable"`
|
|
89
91
|
*
|
|
90
92
|
* Name does not exist or has no suitable associated IP addresses.
|
|
@@ -119,13 +121,31 @@ export interface IpAddressIpv6 {
|
|
|
119
121
|
val: Ipv6Address,
|
|
120
122
|
}
|
|
121
123
|
export interface Ipv4SocketAddress {
|
|
124
|
+
/**
|
|
125
|
+
* sin_port
|
|
126
|
+
*/
|
|
122
127
|
port: number,
|
|
128
|
+
/**
|
|
129
|
+
* sin_addr
|
|
130
|
+
*/
|
|
123
131
|
address: Ipv4Address,
|
|
124
132
|
}
|
|
125
133
|
export interface Ipv6SocketAddress {
|
|
134
|
+
/**
|
|
135
|
+
* sin6_port
|
|
136
|
+
*/
|
|
126
137
|
port: number,
|
|
138
|
+
/**
|
|
139
|
+
* sin6_flowinfo
|
|
140
|
+
*/
|
|
127
141
|
flowInfo: number,
|
|
142
|
+
/**
|
|
143
|
+
* sin6_addr
|
|
144
|
+
*/
|
|
128
145
|
address: Ipv6Address,
|
|
146
|
+
/**
|
|
147
|
+
* sin6_scope_id
|
|
148
|
+
*/
|
|
129
149
|
scopeId: number,
|
|
130
150
|
}
|
|
131
151
|
export type IpSocketAddress = IpSocketAddressIpv4 | IpSocketAddressIpv6;
|
|
@@ -3,9 +3,10 @@ export namespace WasiSocketsTcpCreateSocket {
|
|
|
3
3
|
* Create a new TCP socket.
|
|
4
4
|
*
|
|
5
5
|
* Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX.
|
|
6
|
+
* On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.
|
|
6
7
|
*
|
|
7
8
|
* This function does not require a network capability handle. This is considered to be safe because
|
|
8
|
-
* at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`
|
|
9
|
+
* at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect`
|
|
9
10
|
* is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.
|
|
10
11
|
*
|
|
11
12
|
* All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.
|
|
@@ -6,18 +6,16 @@ export namespace WasiSocketsTcp {
|
|
|
6
6
|
* network interface(s) to bind to.
|
|
7
7
|
* If the TCP/UDP port is zero, the socket will be bound to a random free port.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Bind can be attempted multiple times on the same socket, even with
|
|
10
|
+
* different arguments on each iteration. But never concurrently and
|
|
11
|
+
* only as long as the previous bind failed. Once a bind succeeds, the
|
|
12
|
+
* binding can't be changed anymore.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* # Typical `start` errors
|
|
14
|
+
* # Typical errors
|
|
15
15
|
* - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
|
|
16
16
|
* - `invalid-argument`: `local-address` is not a unicast address. (EINVAL)
|
|
17
|
-
* - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address
|
|
17
|
+
* - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL)
|
|
18
18
|
* - `invalid-state`: The socket is already bound. (EINVAL)
|
|
19
|
-
*
|
|
20
|
-
* # Typical `finish` errors
|
|
21
19
|
* - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
|
|
22
20
|
* - `address-in-use`: Address is already in use. (EADDRINUSE)
|
|
23
21
|
* - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
|
|
@@ -26,8 +24,14 @@ export namespace WasiSocketsTcp {
|
|
|
26
24
|
*
|
|
27
25
|
* # Implementors note
|
|
28
26
|
* When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT
|
|
29
|
-
* state of a recently closed socket on the same local address
|
|
30
|
-
* option should be set implicitly on platforms
|
|
27
|
+
* state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR
|
|
28
|
+
* socket option should be set implicitly on all platforms, except on Windows where this is the default behavior
|
|
29
|
+
* and SO_REUSEADDR performs something different entirely.
|
|
30
|
+
*
|
|
31
|
+
* Unlike in POSIX, in WASI the bind operation is async. This enables
|
|
32
|
+
* interactive WASI hosts to inject permission prompts. Runtimes that
|
|
33
|
+
* don't want to make use of this ability can simply call the native
|
|
34
|
+
* `bind` as part of either `start-bind` or `finish-bind`.
|
|
31
35
|
*
|
|
32
36
|
* # References
|
|
33
37
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html>
|
|
@@ -40,39 +44,40 @@ export namespace WasiSocketsTcp {
|
|
|
40
44
|
* Connect to a remote endpoint.
|
|
41
45
|
*
|
|
42
46
|
* On success:
|
|
43
|
-
* - the socket is transitioned into the
|
|
47
|
+
* - the socket is transitioned into the `connection` state.
|
|
44
48
|
* - a pair of streams is returned that can be used to read & write to the connection
|
|
45
49
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* WASI prescribes the following behavior:
|
|
51
|
-
* - If `connect` fails because an input/state validation error, the socket should remain usable.
|
|
52
|
-
* - If a connection was actually attempted but failed, the socket should become unusable for further network communication.
|
|
53
|
-
* Besides `drop`, any method after such a failure may return an error.
|
|
50
|
+
* After a failed connection attempt, the socket will be in the `closed`
|
|
51
|
+
* state and the only valid action left is to `drop` the socket. A single
|
|
52
|
+
* socket can not be used to connect more than once.
|
|
54
53
|
*
|
|
55
|
-
* # Typical
|
|
54
|
+
* # Typical errors
|
|
56
55
|
* - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
|
|
57
56
|
* - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
|
|
58
|
-
* - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address
|
|
59
|
-
* - `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)
|
|
57
|
+
* - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos)
|
|
60
58
|
* - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows)
|
|
61
59
|
* - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows)
|
|
62
60
|
* - `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`.
|
|
63
|
-
* - `invalid-state`: The socket is already in the
|
|
64
|
-
* - `invalid-state`: The socket is already in the
|
|
65
|
-
*
|
|
66
|
-
* # Typical `finish` errors
|
|
61
|
+
* - `invalid-state`: The socket is already in the `connected` state. (EISCONN)
|
|
62
|
+
* - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows)
|
|
67
63
|
* - `timeout`: Connection timed out. (ETIMEDOUT)
|
|
68
64
|
* - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED)
|
|
69
65
|
* - `connection-reset`: The connection was reset. (ECONNRESET)
|
|
70
66
|
* - `connection-aborted`: The connection was aborted. (ECONNABORTED)
|
|
71
67
|
* - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
|
|
72
68
|
* - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
|
|
73
|
-
* - `not-in-progress`: A
|
|
69
|
+
* - `not-in-progress`: A connect operation is not in progress.
|
|
74
70
|
* - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
|
|
75
71
|
*
|
|
72
|
+
* # Implementors note
|
|
73
|
+
* The POSIX equivalent of `start-connect` is the regular `connect` syscall.
|
|
74
|
+
* Because all WASI sockets are non-blocking this is expected to return
|
|
75
|
+
* EINPROGRESS, which should be translated to `ok()` in WASI.
|
|
76
|
+
*
|
|
77
|
+
* The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT`
|
|
78
|
+
* with a timeout of 0 on the socket descriptor. Followed by a check for
|
|
79
|
+
* the `SO_ERROR` socket option, in case the poll signaled readiness.
|
|
80
|
+
*
|
|
76
81
|
* # References
|
|
77
82
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html>
|
|
78
83
|
* - <https://man7.org/linux/man-pages/man2/connect.2.html>
|
|
@@ -82,22 +87,24 @@ export namespace WasiSocketsTcp {
|
|
|
82
87
|
/**
|
|
83
88
|
* Start listening for new connections.
|
|
84
89
|
*
|
|
85
|
-
* Transitions the socket into the
|
|
90
|
+
* Transitions the socket into the `listening` state.
|
|
86
91
|
*
|
|
87
|
-
* Unlike POSIX
|
|
88
|
-
* - this function is async. This enables interactive WASI hosts to inject permission prompts.
|
|
89
|
-
* - the socket must already be explicitly bound.
|
|
92
|
+
* Unlike POSIX, the socket must already be explicitly bound.
|
|
90
93
|
*
|
|
91
|
-
* # Typical
|
|
94
|
+
* # Typical errors
|
|
92
95
|
* - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ)
|
|
93
|
-
* - `invalid-state`: The socket is already in the
|
|
94
|
-
* - `invalid-state`: The socket is already in the
|
|
95
|
-
*
|
|
96
|
-
* # Typical `finish` errors
|
|
96
|
+
* - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD)
|
|
97
|
+
* - `invalid-state`: The socket is already in the `listening` state.
|
|
97
98
|
* - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
|
|
98
|
-
* - `not-in-progress`: A
|
|
99
|
+
* - `not-in-progress`: A listen operation is not in progress.
|
|
99
100
|
* - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
|
|
100
101
|
*
|
|
102
|
+
* # Implementors note
|
|
103
|
+
* Unlike in POSIX, in WASI the listen operation is async. This enables
|
|
104
|
+
* interactive WASI hosts to inject permission prompts. Runtimes that
|
|
105
|
+
* don't want to make use of this ability can simply call the native
|
|
106
|
+
* `listen` as part of either `start-listen` or `finish-listen`.
|
|
107
|
+
*
|
|
101
108
|
* # References
|
|
102
109
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html>
|
|
103
110
|
* - <https://man7.org/linux/man-pages/man2/listen.2.html>
|
|
@@ -107,9 +114,8 @@ export namespace WasiSocketsTcp {
|
|
|
107
114
|
/**
|
|
108
115
|
* Accept a new client socket.
|
|
109
116
|
*
|
|
110
|
-
* The returned socket is bound and in the
|
|
117
|
+
* The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket:
|
|
111
118
|
* - `address-family`
|
|
112
|
-
* - `ipv6-only`
|
|
113
119
|
* - `keep-alive-enabled`
|
|
114
120
|
* - `keep-alive-idle-time`
|
|
115
121
|
* - `keep-alive-interval`
|
|
@@ -122,7 +128,7 @@ export namespace WasiSocketsTcp {
|
|
|
122
128
|
* a pair of streams that can be used to read & write to the connection.
|
|
123
129
|
*
|
|
124
130
|
* # Typical errors
|
|
125
|
-
* - `invalid-state`: Socket is not in the
|
|
131
|
+
* - `invalid-state`: Socket is not in the `listening` state. (EINVAL)
|
|
126
132
|
* - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
|
|
127
133
|
* - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
|
|
128
134
|
* - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
|
|
@@ -164,7 +170,7 @@ export namespace WasiSocketsTcp {
|
|
|
164
170
|
* - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1>
|
|
165
171
|
*/
|
|
166
172
|
/**
|
|
167
|
-
* Whether the socket is
|
|
173
|
+
* Whether the socket is in the `listening` state.
|
|
168
174
|
*
|
|
169
175
|
* Equivalent to the SO_ACCEPTCONN socket option.
|
|
170
176
|
*/
|
|
@@ -173,16 +179,6 @@ export namespace WasiSocketsTcp {
|
|
|
173
179
|
*
|
|
174
180
|
* Equivalent to the SO_DOMAIN socket option.
|
|
175
181
|
*/
|
|
176
|
-
/**
|
|
177
|
-
* Whether IPv4 compatibility (dual-stack) mode is disabled or not.
|
|
178
|
-
*
|
|
179
|
-
* Equivalent to the IPV6_V6ONLY socket option.
|
|
180
|
-
*
|
|
181
|
-
* # Typical errors
|
|
182
|
-
* - `invalid-state`: (set) The socket is already bound.
|
|
183
|
-
* - `not-supported`: (get/set) `this` socket is an IPv4 socket.
|
|
184
|
-
* - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
|
|
185
|
-
*/
|
|
186
182
|
/**
|
|
187
183
|
* Hints the desired listen queue size. Implementations are free to ignore this.
|
|
188
184
|
*
|
|
@@ -192,7 +188,7 @@ export namespace WasiSocketsTcp {
|
|
|
192
188
|
* # Typical errors
|
|
193
189
|
* - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen.
|
|
194
190
|
* - `invalid-argument`: (set) The provided value was 0.
|
|
195
|
-
* - `invalid-state`: (set) The socket is
|
|
191
|
+
* - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state.
|
|
196
192
|
*/
|
|
197
193
|
/**
|
|
198
194
|
* Enables or disables keepalive.
|
|
@@ -248,8 +244,6 @@ export namespace WasiSocketsTcp {
|
|
|
248
244
|
*
|
|
249
245
|
* # Typical errors
|
|
250
246
|
* - `invalid-argument`: (set) The TTL value must be 1 or higher.
|
|
251
|
-
* - `invalid-state`: (set) The socket is already in the Connection state.
|
|
252
|
-
* - `invalid-state`: (set) The socket is already in the Listener state.
|
|
253
247
|
*/
|
|
254
248
|
/**
|
|
255
249
|
* The kernel buffer space reserved for sends/receives on this socket.
|
|
@@ -262,11 +256,22 @@ export namespace WasiSocketsTcp {
|
|
|
262
256
|
*
|
|
263
257
|
* # Typical errors
|
|
264
258
|
* - `invalid-argument`: (set) The provided value was 0.
|
|
265
|
-
* - `invalid-state`: (set) The socket is already in the Connection state.
|
|
266
|
-
* - `invalid-state`: (set) The socket is already in the Listener state.
|
|
267
259
|
*/
|
|
268
260
|
/**
|
|
269
|
-
* Create a `pollable` which
|
|
261
|
+
* Create a `pollable` which can be used to poll for, or block on,
|
|
262
|
+
* completion of any of the asynchronous operations of this socket.
|
|
263
|
+
*
|
|
264
|
+
* When `finish-bind`, `finish-listen`, `finish-connect` or `accept`
|
|
265
|
+
* return `error(would-block)`, this pollable can be used to wait for
|
|
266
|
+
* their success or failure, after which the method can be retried.
|
|
267
|
+
*
|
|
268
|
+
* The pollable is not limited to the async operation that happens to be
|
|
269
|
+
* in progress at the time of calling `subscribe` (if any). Theoretically,
|
|
270
|
+
* `subscribe` only has to be called once per socket and can then be
|
|
271
|
+
* (re)used for the remainder of the socket's lifetime.
|
|
272
|
+
*
|
|
273
|
+
* See <https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness>
|
|
274
|
+
* for a more information.
|
|
270
275
|
*
|
|
271
276
|
* Note: this function is here for WASI Preview2 only.
|
|
272
277
|
* It's planned to be removed when `future` is natively supported in Preview3.
|
|
@@ -274,17 +279,21 @@ export namespace WasiSocketsTcp {
|
|
|
274
279
|
/**
|
|
275
280
|
* Initiate a graceful shutdown.
|
|
276
281
|
*
|
|
277
|
-
* - receive
|
|
278
|
-
*
|
|
279
|
-
* Any data still in the receive queue at time of calling
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
282
|
+
* - `receive`: The socket is not expecting to receive any data from
|
|
283
|
+
* the peer. The `input-stream` associated with this socket will be
|
|
284
|
+
* closed. Any data still in the receive queue at time of calling
|
|
285
|
+
* this method will be discarded.
|
|
286
|
+
* - `send`: The socket has no more data to send to the peer. The `output-stream`
|
|
287
|
+
* associated with this socket will be closed and a FIN packet will be sent.
|
|
288
|
+
* - `both`: Same effect as `receive` & `send` combined.
|
|
289
|
+
*
|
|
290
|
+
* This function is idempotent. Shutting a down a direction more than once
|
|
291
|
+
* has no effect and returns `ok`.
|
|
283
292
|
*
|
|
284
293
|
* The shutdown function does not close (drop) the socket.
|
|
285
294
|
*
|
|
286
295
|
* # Typical errors
|
|
287
|
-
* - `invalid-state`: The socket is not in the
|
|
296
|
+
* - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN)
|
|
288
297
|
*
|
|
289
298
|
* # References
|
|
290
299
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html>
|
|
@@ -336,8 +345,6 @@ export class TcpSocket {
|
|
|
336
345
|
remoteAddress(): IpSocketAddress;
|
|
337
346
|
isListening(): boolean;
|
|
338
347
|
addressFamily(): IpAddressFamily;
|
|
339
|
-
ipv6Only(): boolean;
|
|
340
|
-
setIpv6Only(value: boolean): void;
|
|
341
348
|
setListenBacklogSize(value: bigint): void;
|
|
342
349
|
keepAliveEnabled(): boolean;
|
|
343
350
|
setKeepAliveEnabled(value: boolean): void;
|
|
@@ -3,6 +3,7 @@ export namespace WasiSocketsUdpCreateSocket {
|
|
|
3
3
|
* Create a new UDP socket.
|
|
4
4
|
*
|
|
5
5
|
* Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX.
|
|
6
|
+
* On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.
|
|
6
7
|
*
|
|
7
8
|
* This function does not require a network capability handle. This is considered to be safe because
|
|
8
9
|
* at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called,
|
|
@@ -6,19 +6,21 @@ export namespace WasiSocketsUdp {
|
|
|
6
6
|
* network interface(s) to bind to.
|
|
7
7
|
* If the port is zero, the socket will be bound to a random free port.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* # Typical `start` errors
|
|
9
|
+
* # Typical errors
|
|
12
10
|
* - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
|
|
13
11
|
* - `invalid-state`: The socket is already bound. (EINVAL)
|
|
14
|
-
*
|
|
15
|
-
* # Typical `finish` errors
|
|
16
12
|
* - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
|
|
17
13
|
* - `address-in-use`: Address is already in use. (EADDRINUSE)
|
|
18
14
|
* - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
|
|
19
15
|
* - `not-in-progress`: A `bind` operation is not in progress.
|
|
20
16
|
* - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
|
|
21
17
|
*
|
|
18
|
+
* # Implementors note
|
|
19
|
+
* Unlike in POSIX, in WASI the bind operation is async. This enables
|
|
20
|
+
* interactive WASI hosts to inject permission prompts. Runtimes that
|
|
21
|
+
* don't want to make use of this ability can simply call the native
|
|
22
|
+
* `bind` as part of either `start-bind` or `finish-bind`.
|
|
23
|
+
*
|
|
22
24
|
* # References
|
|
23
25
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html>
|
|
24
26
|
* - <https://man7.org/linux/man-pages/man2/bind.2.html>
|
|
@@ -55,7 +57,6 @@ export namespace WasiSocketsUdp {
|
|
|
55
57
|
*
|
|
56
58
|
* # Typical errors
|
|
57
59
|
* - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
|
|
58
|
-
* - `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)
|
|
59
60
|
* - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
|
|
60
61
|
* - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
|
|
61
62
|
* - `invalid-state`: The socket is not bound.
|
|
@@ -104,16 +105,6 @@ export namespace WasiSocketsUdp {
|
|
|
104
105
|
*
|
|
105
106
|
* Equivalent to the SO_DOMAIN socket option.
|
|
106
107
|
*/
|
|
107
|
-
/**
|
|
108
|
-
* Whether IPv4 compatibility (dual-stack) mode is disabled or not.
|
|
109
|
-
*
|
|
110
|
-
* Equivalent to the IPV6_V6ONLY socket option.
|
|
111
|
-
*
|
|
112
|
-
* # Typical errors
|
|
113
|
-
* - `not-supported`: (get/set) `this` socket is an IPv4 socket.
|
|
114
|
-
* - `invalid-state`: (set) The socket is already bound.
|
|
115
|
-
* - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
|
|
116
|
-
*/
|
|
117
108
|
/**
|
|
118
109
|
* Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
|
|
119
110
|
*
|
|
@@ -204,7 +195,6 @@ export namespace WasiSocketsUdp {
|
|
|
204
195
|
*
|
|
205
196
|
* # Typical errors
|
|
206
197
|
* - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
|
|
207
|
-
* - `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)
|
|
208
198
|
* - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL)
|
|
209
199
|
* - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
|
|
210
200
|
* - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN)
|
|
@@ -279,6 +269,17 @@ export namespace WasiSocketsUdp {
|
|
|
279
269
|
remoteAddress?: IpSocketAddress,
|
|
280
270
|
}
|
|
281
271
|
|
|
272
|
+
export class IncomingDatagramStream {
|
|
273
|
+
receive(maxResults: bigint): IncomingDatagram[];
|
|
274
|
+
subscribe(): Pollable;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export class OutgoingDatagramStream {
|
|
278
|
+
checkSend(): bigint;
|
|
279
|
+
send(datagrams: OutgoingDatagram[]): bigint;
|
|
280
|
+
subscribe(): Pollable;
|
|
281
|
+
}
|
|
282
|
+
|
|
282
283
|
export class UdpSocket {
|
|
283
284
|
startBind(network: Network, localAddress: IpSocketAddress): void;
|
|
284
285
|
finishBind(): void;
|
|
@@ -286,8 +287,6 @@ export namespace WasiSocketsUdp {
|
|
|
286
287
|
localAddress(): IpSocketAddress;
|
|
287
288
|
remoteAddress(): IpSocketAddress;
|
|
288
289
|
addressFamily(): IpAddressFamily;
|
|
289
|
-
ipv6Only(): boolean;
|
|
290
|
-
setIpv6Only(value: boolean): void;
|
|
291
290
|
unicastHopLimit(): number;
|
|
292
291
|
setUnicastHopLimit(value: number): void;
|
|
293
292
|
receiveBufferSize(): bigint;
|
|
@@ -296,15 +295,4 @@ export namespace WasiSocketsUdp {
|
|
|
296
295
|
setSendBufferSize(value: bigint): void;
|
|
297
296
|
subscribe(): Pollable;
|
|
298
297
|
}
|
|
299
|
-
|
|
300
|
-
export class IncomingDatagramStream {
|
|
301
|
-
receive(maxResults: bigint): IncomingDatagram[];
|
|
302
|
-
subscribe(): Pollable;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export class OutgoingDatagramStream {
|
|
306
|
-
checkSend(): bigint;
|
|
307
|
-
send(datagrams: OutgoingDatagram[]): bigint;
|
|
308
|
-
subscribe(): Pollable;
|
|
309
|
-
}
|
|
310
298
|
|
package/types/io.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WasiIoError } from './interfaces/wasi-io-error.d.ts';
|
|
2
|
+
import type { WasiIoPoll } from './interfaces/wasi-io-poll.d.ts';
|
|
3
|
+
import type { WasiIoStreams } from './interfaces/wasi-io-streams.d.ts';
|
|
4
|
+
|
|
5
|
+
export const error: typeof WasiIoError;
|
|
6
|
+
export const poll: typeof WasiIoPoll;
|
|
7
|
+
export const streams: typeof WasiIoStreams;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WasiRandomInsecureSeed } from './interfaces/wasi-random-insecure-seed.d.ts';
|
|
2
|
+
import type { WasiRandomInsecure } from './interfaces/wasi-random-insecure.d.ts';
|
|
3
|
+
import type { WasiRandomRandom } from './interfaces/wasi-random-random.d.ts';
|
|
4
|
+
|
|
5
|
+
export const insecureSeed: typeof WasiRandomInsecureSeed;
|
|
6
|
+
export const insecure: typeof WasiRandomInsecure;
|
|
7
|
+
export const random: typeof WasiRandomRandom;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { WasiSocketsInstanceNetwork } from './interfaces/wasi-sockets-instance-network.d.ts';
|
|
2
|
+
import type { WasiSocketsIpNameLookup } from './interfaces/wasi-sockets-ip-name-lookup.d.ts';
|
|
3
|
+
import type { WasiSocketsNetwork } from './interfaces/wasi-sockets-network.d.ts';
|
|
4
|
+
import type { WasiSocketsTcpCreateSocket } from './interfaces/wasi-sockets-tcp-create-socket.d.ts';
|
|
5
|
+
import type { WasiSocketsTcp } from './interfaces/wasi-sockets-tcp.d.ts';
|
|
6
|
+
import type { WasiSocketsUdpCreateSocket } from './interfaces/wasi-sockets-udp-create-socket.d.ts';
|
|
7
|
+
import type { WasiSocketsUdp } from './interfaces/wasi-sockets-udp.d.ts';
|
|
8
|
+
|
|
9
|
+
export const instanceNetwork: typeof WasiSocketsInstanceNetwork;
|
|
10
|
+
export const ipNameLookup: typeof WasiSocketsIpNameLookup;
|
|
11
|
+
export const network: typeof WasiSocketsNetwork;
|
|
12
|
+
export const tcpCreateSocket: typeof WasiSocketsTcpCreateSocket;
|
|
13
|
+
export const tcp: typeof WasiSocketsTcp;
|
|
14
|
+
export const udpCreateSocket: typeof WasiSocketsUdpCreateSocket;
|
|
15
|
+
export const udp: typeof WasiSocketsUdp;
|