@bytecodealliance/preview2-shim 0.18.1 → 0.20.0
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 +15 -15
- package/dist/browser/cli.d.ts +16 -0
- package/dist/browser/cli.js +109 -0
- package/dist/browser/clocks.d.ts +3 -0
- package/dist/browser/clocks.js +36 -0
- package/dist/browser/config.d.ts +2 -0
- package/{lib → dist}/browser/config.js +2 -4
- package/dist/browser/environment.d.ts +5 -0
- package/dist/browser/environment.js +24 -0
- package/dist/browser/filesystem.d.ts +132 -0
- package/dist/browser/filesystem.js +488 -0
- package/dist/browser/http.d.ts +4 -0
- package/dist/browser/http.js +643 -0
- package/dist/browser/index.d.ts +7 -0
- package/dist/browser/index.js +7 -0
- package/dist/browser/io.d.ts +58 -0
- package/dist/browser/io.js +205 -0
- package/dist/browser/random.d.ts +4 -0
- package/dist/browser/random.js +49 -0
- package/dist/browser/sockets.d.ts +8 -0
- package/dist/browser/sockets.js +66 -0
- package/dist/common/instantiation.d.ts +97 -0
- package/dist/common/instantiation.js +228 -0
- package/dist/io/calls.d.ts +91 -0
- package/{lib → dist}/io/calls.js +4 -19
- package/dist/io/worker-http.d.ts +17 -0
- package/dist/io/worker-http.js +192 -0
- package/dist/io/worker-io.d.ts +84 -0
- package/dist/io/worker-io.js +381 -0
- package/dist/io/worker-socket-tcp.d.ts +34 -0
- package/dist/io/worker-socket-tcp.js +251 -0
- package/dist/io/worker-socket-udp.d.ts +54 -0
- package/dist/io/worker-socket-udp.js +493 -0
- package/dist/io/worker-sockets.d.ts +32 -0
- package/dist/io/worker-sockets.js +265 -0
- package/dist/io/worker-thread.d.ts +73 -0
- package/dist/io/worker-thread.js +794 -0
- package/dist/nodejs/cli.d.ts +30 -0
- package/dist/nodejs/cli.js +86 -0
- package/dist/nodejs/clocks.d.ts +3 -0
- package/dist/nodejs/clocks.js +61 -0
- package/dist/nodejs/filesystem.d.ts +113 -0
- package/dist/nodejs/filesystem.js +761 -0
- package/dist/nodejs/http.d.ts +82 -0
- package/dist/nodejs/http.js +674 -0
- package/dist/nodejs/index.d.ts +7 -0
- package/dist/nodejs/index.js +7 -0
- package/dist/nodejs/io.d.ts +1 -0
- package/dist/nodejs/io.js +1 -0
- package/dist/nodejs/random.d.ts +4 -0
- package/dist/nodejs/random.js +42 -0
- package/dist/nodejs/sockets.d.ts +21 -0
- package/dist/nodejs/sockets.js +482 -0
- package/dist/synckit/index.d.ts +2 -0
- package/dist/synckit/index.js +117 -0
- package/package.json +28 -15
- package/types/instantiation.d.ts +7 -7
- package/lib/browser/cli.js +0 -135
- package/lib/browser/clocks.js +0 -39
- package/lib/browser/environment.js +0 -29
- package/lib/browser/filesystem.js +0 -503
- package/lib/browser/http.js +0 -707
- package/lib/browser/index.js +0 -9
- package/lib/browser/io.js +0 -262
- package/lib/browser/random.js +0 -56
- package/lib/browser/sockets.js +0 -88
- package/lib/common/instantiation.js +0 -253
- package/lib/io/worker-http.js +0 -206
- package/lib/io/worker-io.js +0 -468
- package/lib/io/worker-socket-tcp.js +0 -331
- package/lib/io/worker-socket-udp.js +0 -587
- package/lib/io/worker-sockets.js +0 -364
- package/lib/io/worker-thread.js +0 -1051
- package/lib/nodejs/cli.js +0 -109
- package/lib/nodejs/clocks.js +0 -67
- package/lib/nodejs/filesystem.js +0 -829
- package/lib/nodejs/http.js +0 -764
- package/lib/nodejs/index.js +0 -9
- package/lib/nodejs/io.js +0 -1
- package/lib/nodejs/random.js +0 -49
- package/lib/nodejs/sockets.js +0 -565
- package/lib/synckit/index.js +0 -127
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { createFuture, createReadableStream, createReadableStreamPollState, createWritableStream, futureDispose, futureTakeValue, pollStateReady, verifyPollsDroppedForDrop, } from "./worker-thread.js";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
// TODO: tcp_wrap is no longer exposed in newer versions of Node.js
|
|
4
|
+
const { TCP, constants: TCPConstants } = process.binding("tcp_wrap");
|
|
5
|
+
import { convertSocketError, convertSocketErrorCode, ipSocketAddress, isIPv4MappedAddress, isMulticastIpAddress, isUnicastIpAddress, isWildcardAddress, noLookup, serializeIpAddress, SOCKET_STATE_BIND, SOCKET_STATE_BOUND, SOCKET_STATE_CLOSED, SOCKET_STATE_CONNECT, SOCKET_STATE_CONNECTION, SOCKET_STATE_INIT, SOCKET_STATE_LISTEN, SOCKET_STATE_LISTENER, } from "./worker-sockets.js";
|
|
6
|
+
import { Server, Socket as TcpSocket } from "node:net";
|
|
7
|
+
const win = process.platform === "win32";
|
|
8
|
+
export const tcpSockets = new Map();
|
|
9
|
+
let tcpSocketCnt = 0;
|
|
10
|
+
export function createTcpSocket() {
|
|
11
|
+
const handle = new TCP(TCPConstants.SOCKET);
|
|
12
|
+
tcpSockets.set(++tcpSocketCnt, {
|
|
13
|
+
state: SOCKET_STATE_INIT,
|
|
14
|
+
future: null,
|
|
15
|
+
tcpSocket: null,
|
|
16
|
+
listenBacklogSize: 128,
|
|
17
|
+
handle,
|
|
18
|
+
pendingAccepts: [],
|
|
19
|
+
pollState: {
|
|
20
|
+
ready: true,
|
|
21
|
+
listener: null,
|
|
22
|
+
polls: [],
|
|
23
|
+
parentStream: null,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return tcpSocketCnt;
|
|
27
|
+
}
|
|
28
|
+
export function socketTcpFinish(id, fromState, toState) {
|
|
29
|
+
const socket = tcpSockets.get(id);
|
|
30
|
+
if (socket.state !== fromState) {
|
|
31
|
+
throw "not-in-progress";
|
|
32
|
+
}
|
|
33
|
+
if (!socket.pollState?.ready) {
|
|
34
|
+
throw "would-block";
|
|
35
|
+
}
|
|
36
|
+
const { tag, val } = futureTakeValue(socket.future)?.val ?? {};
|
|
37
|
+
futureDispose(socket.future, false);
|
|
38
|
+
socket.future = null;
|
|
39
|
+
if (tag === "err") {
|
|
40
|
+
socket.state = SOCKET_STATE_CLOSED;
|
|
41
|
+
throw val;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
socket.state = toState;
|
|
45
|
+
// for the listener, we must immediately transition back to unresolved
|
|
46
|
+
if (toState === SOCKET_STATE_LISTENER) {
|
|
47
|
+
socket.pollState.ready = false;
|
|
48
|
+
}
|
|
49
|
+
return val;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function socketTcpBindStart(id, localAddress, family) {
|
|
53
|
+
const socket = tcpSockets.get(id);
|
|
54
|
+
if (socket.state !== SOCKET_STATE_INIT) {
|
|
55
|
+
throw "invalid-state";
|
|
56
|
+
}
|
|
57
|
+
if (family !== localAddress.tag ||
|
|
58
|
+
!isUnicastIpAddress(localAddress) ||
|
|
59
|
+
isIPv4MappedAddress(localAddress)) {
|
|
60
|
+
throw "invalid-argument";
|
|
61
|
+
}
|
|
62
|
+
socket.state = SOCKET_STATE_BIND;
|
|
63
|
+
const { handle } = socket;
|
|
64
|
+
socket.future = createFuture((async () => {
|
|
65
|
+
const address = serializeIpAddress(localAddress);
|
|
66
|
+
const port = localAddress.val.port;
|
|
67
|
+
const code = localAddress.tag === "ipv6"
|
|
68
|
+
? handle.bind6(address, port, TCPConstants.UV_TCP_IPV6ONLY)
|
|
69
|
+
: handle.bind(address, port);
|
|
70
|
+
if (code !== 0) {
|
|
71
|
+
throw convertSocketErrorCode(-code);
|
|
72
|
+
}
|
|
73
|
+
// This is a Node.js / libuv quirk to force the bind error to be thrown
|
|
74
|
+
// (specifically address-in-use).
|
|
75
|
+
{
|
|
76
|
+
const out = {};
|
|
77
|
+
const code = handle.getsockname(out);
|
|
78
|
+
if (code !== 0) {
|
|
79
|
+
throw convertSocketErrorCode(-code);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})(), socket.pollState);
|
|
83
|
+
}
|
|
84
|
+
export function socketTcpConnectStart(id, remoteAddress, family) {
|
|
85
|
+
const socket = tcpSockets.get(id);
|
|
86
|
+
if (socket.state !== SOCKET_STATE_INIT && socket.state !== SOCKET_STATE_BOUND) {
|
|
87
|
+
throw "invalid-state";
|
|
88
|
+
}
|
|
89
|
+
if (isWildcardAddress(remoteAddress) ||
|
|
90
|
+
family !== remoteAddress.tag ||
|
|
91
|
+
!isUnicastIpAddress(remoteAddress) ||
|
|
92
|
+
isMulticastIpAddress(remoteAddress) ||
|
|
93
|
+
remoteAddress.val.port === 0 ||
|
|
94
|
+
isIPv4MappedAddress(remoteAddress)) {
|
|
95
|
+
throw "invalid-argument";
|
|
96
|
+
}
|
|
97
|
+
socket.state = SOCKET_STATE_CONNECT;
|
|
98
|
+
socket.future = createFuture(new Promise((resolve, reject) => {
|
|
99
|
+
const tcpSocket = (socket.tcpSocket = new TcpSocket({
|
|
100
|
+
// @ts-expect-error Not present in type definition
|
|
101
|
+
handle: socket.handle,
|
|
102
|
+
pauseOnCreate: true,
|
|
103
|
+
allowHalfOpen: true,
|
|
104
|
+
}));
|
|
105
|
+
function handleErr(err) {
|
|
106
|
+
tcpSocket.off("connect", handleConnect);
|
|
107
|
+
reject(convertSocketError(err));
|
|
108
|
+
}
|
|
109
|
+
function handleConnect() {
|
|
110
|
+
tcpSocket.off("error", handleErr);
|
|
111
|
+
resolve([createReadableStream(tcpSocket), createWritableStream(tcpSocket)]);
|
|
112
|
+
}
|
|
113
|
+
tcpSocket.once("connect", handleConnect);
|
|
114
|
+
tcpSocket.once("error", handleErr);
|
|
115
|
+
tcpSocket.connect({
|
|
116
|
+
port: remoteAddress.val.port,
|
|
117
|
+
host: serializeIpAddress(remoteAddress) ?? undefined,
|
|
118
|
+
lookup: noLookup,
|
|
119
|
+
});
|
|
120
|
+
}), socket.pollState);
|
|
121
|
+
}
|
|
122
|
+
export function socketTcpListenStart(id) {
|
|
123
|
+
const socket = tcpSockets.get(id);
|
|
124
|
+
if (socket.state !== SOCKET_STATE_BOUND) {
|
|
125
|
+
throw "invalid-state";
|
|
126
|
+
}
|
|
127
|
+
const { handle } = socket;
|
|
128
|
+
socket.state = SOCKET_STATE_LISTEN;
|
|
129
|
+
socket.future = createFuture(new Promise((resolve, reject) => {
|
|
130
|
+
const server = new Server({
|
|
131
|
+
pauseOnConnect: true,
|
|
132
|
+
allowHalfOpen: true,
|
|
133
|
+
});
|
|
134
|
+
function handleErr(err) {
|
|
135
|
+
server.off("listening", handleListen);
|
|
136
|
+
reject(convertSocketError(err));
|
|
137
|
+
}
|
|
138
|
+
function handleListen() {
|
|
139
|
+
server.off("error", handleErr);
|
|
140
|
+
server.on("connection", (tcpSocket) => {
|
|
141
|
+
pollStateReady(socket.pollState);
|
|
142
|
+
const pollState = createReadableStreamPollState(tcpSocket);
|
|
143
|
+
socket.pendingAccepts.push({
|
|
144
|
+
tcpSocket,
|
|
145
|
+
err: null,
|
|
146
|
+
pollState,
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
server.on("error", (err) => {
|
|
150
|
+
pollStateReady(socket.pollState);
|
|
151
|
+
socket.pendingAccepts.push({
|
|
152
|
+
tcpSocket: null,
|
|
153
|
+
err,
|
|
154
|
+
pollState: null,
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
resolve();
|
|
158
|
+
}
|
|
159
|
+
server.once("listening", handleListen);
|
|
160
|
+
server.once("error", handleErr);
|
|
161
|
+
server.listen(handle, socket.listenBacklogSize);
|
|
162
|
+
}), socket.pollState);
|
|
163
|
+
}
|
|
164
|
+
export function socketTcpAccept(id) {
|
|
165
|
+
const socket = tcpSockets.get(id);
|
|
166
|
+
if (socket.state !== SOCKET_STATE_LISTENER) {
|
|
167
|
+
throw "invalid-state";
|
|
168
|
+
}
|
|
169
|
+
if (socket.pendingAccepts.length === 0) {
|
|
170
|
+
throw "would-block";
|
|
171
|
+
}
|
|
172
|
+
const accept = socket.pendingAccepts.shift();
|
|
173
|
+
if (!accept || accept.err) {
|
|
174
|
+
socket.state = SOCKET_STATE_CLOSED;
|
|
175
|
+
throw convertSocketError(accept?.err);
|
|
176
|
+
}
|
|
177
|
+
if (socket.pollState && socket.pendingAccepts.length === 0) {
|
|
178
|
+
socket.pollState.ready = false;
|
|
179
|
+
}
|
|
180
|
+
tcpSockets.set(++tcpSocketCnt, {
|
|
181
|
+
state: SOCKET_STATE_CONNECTION,
|
|
182
|
+
future: null,
|
|
183
|
+
tcpSocket: accept.tcpSocket,
|
|
184
|
+
listenBacklogSize: 128,
|
|
185
|
+
// @ts-expect-error
|
|
186
|
+
handle: accept.tcpSocket?._handle,
|
|
187
|
+
pendingAccepts: [],
|
|
188
|
+
pollState: accept.pollState,
|
|
189
|
+
});
|
|
190
|
+
return [
|
|
191
|
+
tcpSocketCnt,
|
|
192
|
+
// @ts-expect-error
|
|
193
|
+
createReadableStream(accept.tcpSocket, accept.pollState ?? undefined),
|
|
194
|
+
createWritableStream(accept.tcpSocket),
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
export function socketTcpSetListenBacklogSize(id, backlogSize) {
|
|
198
|
+
const socket = tcpSockets.get(id);
|
|
199
|
+
if (socket.state === SOCKET_STATE_LISTEN || socket.state === SOCKET_STATE_LISTENER) {
|
|
200
|
+
throw "not-supported";
|
|
201
|
+
}
|
|
202
|
+
if (socket.state !== SOCKET_STATE_INIT &&
|
|
203
|
+
socket.state !== SOCKET_STATE_BIND &&
|
|
204
|
+
socket.state !== SOCKET_STATE_BOUND) {
|
|
205
|
+
throw "invalid-state";
|
|
206
|
+
}
|
|
207
|
+
socket.listenBacklogSize = Number(backlogSize);
|
|
208
|
+
}
|
|
209
|
+
export function socketTcpGetLocalAddress(id) {
|
|
210
|
+
const { handle } = tcpSockets.get(id);
|
|
211
|
+
const out = {};
|
|
212
|
+
const code = handle.getsockname(out);
|
|
213
|
+
if (code !== 0) {
|
|
214
|
+
throw convertSocketErrorCode(-code);
|
|
215
|
+
}
|
|
216
|
+
return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
|
|
217
|
+
}
|
|
218
|
+
export function socketTcpGetRemoteAddress(id) {
|
|
219
|
+
const { handle } = tcpSockets.get(id);
|
|
220
|
+
const out = {};
|
|
221
|
+
const code = handle.getpeername(out);
|
|
222
|
+
if (code !== 0) {
|
|
223
|
+
throw convertSocketErrorCode(-code);
|
|
224
|
+
}
|
|
225
|
+
return ipSocketAddress(out.family.toLowerCase(), out.address, out.port);
|
|
226
|
+
}
|
|
227
|
+
export function socketTcpShutdown(id, _shutdownType) {
|
|
228
|
+
const socket = tcpSockets.get(id);
|
|
229
|
+
if (socket.state !== SOCKET_STATE_CONNECTION) {
|
|
230
|
+
throw "invalid-state";
|
|
231
|
+
}
|
|
232
|
+
if (win && socket.tcpSocket?.destroySoon) {
|
|
233
|
+
socket.tcpSocket.destroySoon();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
socket.tcpSocket?.destroy();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
export function socketTcpSetKeepAlive(id, { keepAlive, keepAliveIdleTime }) {
|
|
240
|
+
const { handle } = tcpSockets.get(id);
|
|
241
|
+
const code = handle.setKeepAlive(keepAlive, Number(keepAliveIdleTime / 1000000000n));
|
|
242
|
+
if (code !== 0) {
|
|
243
|
+
throw convertSocketErrorCode(-code);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function socketTcpDispose(id) {
|
|
247
|
+
const socket = tcpSockets.get(id);
|
|
248
|
+
verifyPollsDroppedForDrop(socket.pollState, "tcp socket");
|
|
249
|
+
socket.handle.close();
|
|
250
|
+
tcpSockets.delete(id);
|
|
251
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Socket } from "node:dgram";
|
|
2
|
+
import { PollState } from "./worker-thread.js";
|
|
3
|
+
import { IpAddressFamily, IpSocketAddress } from "../../types/interfaces/wasi-sockets-network.js";
|
|
4
|
+
import { OutgoingDatagram } from "../../types/interfaces/wasi-sockets-udp.js";
|
|
5
|
+
interface UdpSocketRecord {
|
|
6
|
+
state: number;
|
|
7
|
+
remoteAddress: string | null;
|
|
8
|
+
remotePort: number | null;
|
|
9
|
+
sendBufferSize: number | null;
|
|
10
|
+
receiveBufferSize: number | null;
|
|
11
|
+
unicastHopLimit: number;
|
|
12
|
+
udpSocket: Socket;
|
|
13
|
+
future: number | null;
|
|
14
|
+
serializedLocalAddress: string | null;
|
|
15
|
+
pollState: PollState;
|
|
16
|
+
incomingDatagramStream: DatagramStreamRecord | null;
|
|
17
|
+
outgoingDatagramStream: DatagramStreamRecord | null;
|
|
18
|
+
}
|
|
19
|
+
interface DatagramStreamRecord {
|
|
20
|
+
id: number;
|
|
21
|
+
active: boolean;
|
|
22
|
+
error: any | null;
|
|
23
|
+
socket: UdpSocketRecord;
|
|
24
|
+
pollState: PollState;
|
|
25
|
+
queue?: Buffer[];
|
|
26
|
+
cleanup: (() => void) | null;
|
|
27
|
+
}
|
|
28
|
+
export declare const udpSockets: Map<number, UdpSocketRecord>;
|
|
29
|
+
export declare const datagramStreams: Map<number, DatagramStreamRecord>;
|
|
30
|
+
export declare function createUdpSocket({ family, unicastHopLimit, }: {
|
|
31
|
+
family: IpAddressFamily;
|
|
32
|
+
unicastHopLimit: number;
|
|
33
|
+
}): number;
|
|
34
|
+
export declare function socketUdpBindStart(id: number, localAddress: any, family: any): void;
|
|
35
|
+
export declare function socketUdpBindFinish(id: number): any;
|
|
36
|
+
export declare function socketUdpGetLocalAddress(id: number): IpSocketAddress;
|
|
37
|
+
/**
|
|
38
|
+
* @param {number} id
|
|
39
|
+
* @returns {IpSocketAddress}
|
|
40
|
+
*/
|
|
41
|
+
export declare function socketUdpGetRemoteAddress(id: any): IpSocketAddress;
|
|
42
|
+
export declare function socketUdpStream(id: any, remoteAddress: any): number[] | Promise<unknown>;
|
|
43
|
+
export declare function socketUdpSetReceiveBufferSize(id: number, bufferSize: bigint): void;
|
|
44
|
+
export declare function socketUdpSetSendBufferSize(id: number, bufferSize: bigint): void;
|
|
45
|
+
export declare function socketUdpSetUnicastHopLimit(id: number, hopLimit: number): void;
|
|
46
|
+
export declare function socketUdpGetReceiveBufferSize(id: number): Promise<bigint>;
|
|
47
|
+
export declare function socketUdpGetSendBufferSize(id: number): Promise<bigint>;
|
|
48
|
+
export declare function socketUdpGetUnicastHopLimit(id: number): number;
|
|
49
|
+
export declare function socketUdpDispose(id: number): Promise<unknown>;
|
|
50
|
+
export declare function socketIncomingDatagramStreamReceive(id: number, maxResults: bigint): Buffer<ArrayBufferLike>[] | undefined;
|
|
51
|
+
export declare function socketOutgoingDatagramStreamSend(id: number, datagrams: OutgoingDatagram[]): Promise<bigint>;
|
|
52
|
+
export declare function socketOutgoingDatagramStreamCheckSend(id: number): bigint;
|
|
53
|
+
export declare function socketDatagramStreamDispose(id: any): void;
|
|
54
|
+
export {};
|