@bytecodealliance/preview2-shim 0.17.7 → 0.17.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,163 +1,163 @@
1
- import { createReadStream, createWriteStream } from 'node:fs';
2
- import { hrtime, stderr, stdout } from 'node:process';
3
- import { PassThrough } from 'node:stream';
4
- import { runAsWorker } from '../synckit/index.js';
1
+ import { createReadStream, createWriteStream } from "node:fs";
2
+ import { hrtime, stderr, stdout } from "node:process";
3
+ import { PassThrough } from "node:stream";
4
+ import { runAsWorker } from "../synckit/index.js";
5
5
  import {
6
- clearOutgoingResponse,
7
- createHttpRequest,
8
- setOutgoingResponse,
9
- startHttpServer,
10
- stopHttpServer,
11
- getHttpServerAddress,
12
- } from './worker-http.js';
13
- import { Readable } from 'node:stream';
14
- import { read } from 'node:fs';
15
- import { nextTick } from 'node:process';
6
+ clearOutgoingResponse,
7
+ createHttpRequest,
8
+ setOutgoingResponse,
9
+ startHttpServer,
10
+ stopHttpServer,
11
+ getHttpServerAddress,
12
+ } from "./worker-http.js";
13
+ import { Readable } from "node:stream";
14
+ import { read } from "node:fs";
15
+ import { nextTick } from "node:process";
16
16
  import {
17
- CALL_MASK,
18
- CALL_TYPE_MASK,
19
- CLOCKS_DURATION_SUBSCRIBE,
20
- CLOCKS_INSTANT_SUBSCRIBE,
21
- FILE,
22
- FUTURE_DISPOSE,
23
- FUTURE_SUBSCRIBE,
24
- FUTURE_TAKE_VALUE,
25
- HTTP,
26
- HTTP_CREATE_REQUEST,
27
- HTTP_OUTGOING_BODY_DISPOSE,
28
- HTTP_OUTPUT_STREAM_FINISH,
29
- HTTP_SERVER_CLEAR_OUTGOING_RESPONSE,
30
- HTTP_SERVER_SET_OUTGOING_RESPONSE,
31
- HTTP_SERVER_START,
32
- HTTP_SERVER_STOP,
33
- HTTP_SERVER_GET_ADDRESS,
34
- INPUT_STREAM_BLOCKING_READ,
35
- INPUT_STREAM_BLOCKING_SKIP,
36
- INPUT_STREAM_CREATE,
37
- INPUT_STREAM_DISPOSE,
38
- INPUT_STREAM_READ,
39
- INPUT_STREAM_SKIP,
40
- INPUT_STREAM_SUBSCRIBE,
41
- OUTPUT_STREAM_BLOCKING_FLUSH,
42
- OUTPUT_STREAM_BLOCKING_SPLICE,
43
- OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH,
44
- OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH,
45
- OUTPUT_STREAM_CHECK_WRITE,
46
- OUTPUT_STREAM_CREATE,
47
- OUTPUT_STREAM_DISPOSE,
48
- OUTPUT_STREAM_FLUSH,
49
- OUTPUT_STREAM_SPLICE,
50
- OUTPUT_STREAM_SUBSCRIBE,
51
- OUTPUT_STREAM_WRITE,
52
- OUTPUT_STREAM_WRITE_ZEROES,
53
- POLL_POLLABLE_BLOCK,
54
- POLL_POLLABLE_DISPOSE,
55
- POLL_POLLABLE_READY,
56
- POLL_POLL_LIST,
57
- SOCKET_RESOLVE_ADDRESS_CREATE_REQUEST,
58
- SOCKET_RESOLVE_ADDRESS_SUBSCRIBE_REQUEST,
59
- SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST,
60
- SOCKET_RESOLVE_ADDRESS_TAKE_REQUEST,
61
- SOCKET_GET_DEFAULT_RECEIVE_BUFFER_SIZE,
62
- SOCKET_GET_DEFAULT_SEND_BUFFER_SIZE,
63
- SOCKET_TCP_ACCEPT,
64
- SOCKET_TCP_BIND_FINISH,
65
- SOCKET_TCP_BIND_START,
66
- SOCKET_TCP_CONNECT_FINISH,
67
- SOCKET_TCP_CONNECT_START,
68
- SOCKET_TCP_CREATE_HANDLE,
69
- SOCKET_TCP_DISPOSE,
70
- SOCKET_TCP_GET_LOCAL_ADDRESS,
71
- SOCKET_TCP_GET_REMOTE_ADDRESS,
72
- SOCKET_TCP_IS_LISTENING,
73
- SOCKET_TCP_LISTEN_FINISH,
74
- SOCKET_TCP_LISTEN_START,
75
- SOCKET_TCP_SET_KEEP_ALIVE,
76
- SOCKET_TCP_SET_LISTEN_BACKLOG_SIZE,
77
- SOCKET_TCP_SHUTDOWN,
78
- SOCKET_TCP_SUBSCRIBE,
79
- SOCKET_UDP_BIND_FINISH,
80
- SOCKET_UDP_BIND_START,
81
- SOCKET_UDP_CREATE_HANDLE,
82
- SOCKET_UDP_DISPOSE,
83
- SOCKET_UDP_GET_LOCAL_ADDRESS,
84
- SOCKET_UDP_GET_RECEIVE_BUFFER_SIZE,
85
- SOCKET_UDP_GET_REMOTE_ADDRESS,
86
- SOCKET_UDP_GET_SEND_BUFFER_SIZE,
87
- SOCKET_UDP_GET_UNICAST_HOP_LIMIT,
88
- SOCKET_UDP_SET_RECEIVE_BUFFER_SIZE,
89
- SOCKET_UDP_SET_SEND_BUFFER_SIZE,
90
- SOCKET_UDP_SET_UNICAST_HOP_LIMIT,
91
- SOCKET_UDP_STREAM,
92
- SOCKET_UDP_SUBSCRIBE,
93
- SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE,
94
- SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND,
95
- SOCKET_OUTGOING_DATAGRAM_STREAM_SEND,
96
- SOCKET_DATAGRAM_STREAM_SUBSCRIBE,
97
- SOCKET_DATAGRAM_STREAM_DISPOSE,
98
- STDERR,
99
- STDIN,
100
- STDOUT,
101
- reverseMap,
102
- } from './calls.js';
17
+ CALL_MASK,
18
+ CALL_TYPE_MASK,
19
+ CLOCKS_DURATION_SUBSCRIBE,
20
+ CLOCKS_INSTANT_SUBSCRIBE,
21
+ FILE,
22
+ FUTURE_DISPOSE,
23
+ FUTURE_SUBSCRIBE,
24
+ FUTURE_TAKE_VALUE,
25
+ HTTP,
26
+ HTTP_CREATE_REQUEST,
27
+ HTTP_OUTGOING_BODY_DISPOSE,
28
+ HTTP_OUTPUT_STREAM_FINISH,
29
+ HTTP_SERVER_CLEAR_OUTGOING_RESPONSE,
30
+ HTTP_SERVER_SET_OUTGOING_RESPONSE,
31
+ HTTP_SERVER_START,
32
+ HTTP_SERVER_STOP,
33
+ HTTP_SERVER_GET_ADDRESS,
34
+ INPUT_STREAM_BLOCKING_READ,
35
+ INPUT_STREAM_BLOCKING_SKIP,
36
+ INPUT_STREAM_CREATE,
37
+ INPUT_STREAM_DISPOSE,
38
+ INPUT_STREAM_READ,
39
+ INPUT_STREAM_SKIP,
40
+ INPUT_STREAM_SUBSCRIBE,
41
+ OUTPUT_STREAM_BLOCKING_FLUSH,
42
+ OUTPUT_STREAM_BLOCKING_SPLICE,
43
+ OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH,
44
+ OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH,
45
+ OUTPUT_STREAM_CHECK_WRITE,
46
+ OUTPUT_STREAM_CREATE,
47
+ OUTPUT_STREAM_DISPOSE,
48
+ OUTPUT_STREAM_FLUSH,
49
+ OUTPUT_STREAM_SPLICE,
50
+ OUTPUT_STREAM_SUBSCRIBE,
51
+ OUTPUT_STREAM_WRITE,
52
+ OUTPUT_STREAM_WRITE_ZEROES,
53
+ POLL_POLLABLE_BLOCK,
54
+ POLL_POLLABLE_DISPOSE,
55
+ POLL_POLLABLE_READY,
56
+ POLL_POLL_LIST,
57
+ SOCKET_RESOLVE_ADDRESS_CREATE_REQUEST,
58
+ SOCKET_RESOLVE_ADDRESS_SUBSCRIBE_REQUEST,
59
+ SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST,
60
+ SOCKET_RESOLVE_ADDRESS_TAKE_REQUEST,
61
+ SOCKET_GET_DEFAULT_RECEIVE_BUFFER_SIZE,
62
+ SOCKET_GET_DEFAULT_SEND_BUFFER_SIZE,
63
+ SOCKET_TCP_ACCEPT,
64
+ SOCKET_TCP_BIND_FINISH,
65
+ SOCKET_TCP_BIND_START,
66
+ SOCKET_TCP_CONNECT_FINISH,
67
+ SOCKET_TCP_CONNECT_START,
68
+ SOCKET_TCP_CREATE_HANDLE,
69
+ SOCKET_TCP_DISPOSE,
70
+ SOCKET_TCP_GET_LOCAL_ADDRESS,
71
+ SOCKET_TCP_GET_REMOTE_ADDRESS,
72
+ SOCKET_TCP_IS_LISTENING,
73
+ SOCKET_TCP_LISTEN_FINISH,
74
+ SOCKET_TCP_LISTEN_START,
75
+ SOCKET_TCP_SET_KEEP_ALIVE,
76
+ SOCKET_TCP_SET_LISTEN_BACKLOG_SIZE,
77
+ SOCKET_TCP_SHUTDOWN,
78
+ SOCKET_TCP_SUBSCRIBE,
79
+ SOCKET_UDP_BIND_FINISH,
80
+ SOCKET_UDP_BIND_START,
81
+ SOCKET_UDP_CREATE_HANDLE,
82
+ SOCKET_UDP_DISPOSE,
83
+ SOCKET_UDP_GET_LOCAL_ADDRESS,
84
+ SOCKET_UDP_GET_RECEIVE_BUFFER_SIZE,
85
+ SOCKET_UDP_GET_REMOTE_ADDRESS,
86
+ SOCKET_UDP_GET_SEND_BUFFER_SIZE,
87
+ SOCKET_UDP_GET_UNICAST_HOP_LIMIT,
88
+ SOCKET_UDP_SET_RECEIVE_BUFFER_SIZE,
89
+ SOCKET_UDP_SET_SEND_BUFFER_SIZE,
90
+ SOCKET_UDP_SET_UNICAST_HOP_LIMIT,
91
+ SOCKET_UDP_STREAM,
92
+ SOCKET_UDP_SUBSCRIBE,
93
+ SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE,
94
+ SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND,
95
+ SOCKET_OUTGOING_DATAGRAM_STREAM_SEND,
96
+ SOCKET_DATAGRAM_STREAM_SUBSCRIBE,
97
+ SOCKET_DATAGRAM_STREAM_DISPOSE,
98
+ STDERR,
99
+ STDIN,
100
+ STDOUT,
101
+ reverseMap,
102
+ } from "./calls.js";
103
103
  import {
104
- SOCKET_STATE_BIND,
105
- SOCKET_STATE_BOUND,
106
- SOCKET_STATE_CONNECT,
107
- SOCKET_STATE_CONNECTION,
108
- SOCKET_STATE_LISTEN,
109
- SOCKET_STATE_LISTENER,
110
- socketResolveAddress,
111
- getDefaultSendBufferSize,
112
- getDefaultReceiveBufferSize,
113
- } from './worker-sockets.js';
104
+ SOCKET_STATE_BIND,
105
+ SOCKET_STATE_BOUND,
106
+ SOCKET_STATE_CONNECT,
107
+ SOCKET_STATE_CONNECTION,
108
+ SOCKET_STATE_LISTEN,
109
+ SOCKET_STATE_LISTENER,
110
+ socketResolveAddress,
111
+ getDefaultSendBufferSize,
112
+ getDefaultReceiveBufferSize,
113
+ } from "./worker-sockets.js";
114
114
  import {
115
- createTcpSocket,
116
- socketTcpAccept,
117
- socketTcpBindStart,
118
- socketTcpConnectStart,
119
- socketTcpDispose,
120
- socketTcpFinish,
121
- socketTcpGetLocalAddress,
122
- socketTcpGetRemoteAddress,
123
- socketTcpListenStart,
124
- socketTcpSetKeepAlive,
125
- socketTcpSetListenBacklogSize,
126
- socketTcpShutdown,
127
- tcpSockets,
128
- } from './worker-socket-tcp.js';
115
+ createTcpSocket,
116
+ socketTcpAccept,
117
+ socketTcpBindStart,
118
+ socketTcpConnectStart,
119
+ socketTcpDispose,
120
+ socketTcpFinish,
121
+ socketTcpGetLocalAddress,
122
+ socketTcpGetRemoteAddress,
123
+ socketTcpListenStart,
124
+ socketTcpSetKeepAlive,
125
+ socketTcpSetListenBacklogSize,
126
+ socketTcpShutdown,
127
+ tcpSockets,
128
+ } from "./worker-socket-tcp.js";
129
129
  import {
130
- createUdpSocket,
131
- datagramStreams,
132
- socketDatagramStreamDispose,
133
- socketIncomingDatagramStreamReceive,
134
- socketOutgoingDatagramStreamCheckSend,
135
- socketOutgoingDatagramStreamSend,
136
- socketUdpBindFinish,
137
- socketUdpBindStart,
138
- socketUdpDispose,
139
- socketUdpGetLocalAddress,
140
- socketUdpGetReceiveBufferSize,
141
- socketUdpGetRemoteAddress,
142
- socketUdpGetSendBufferSize,
143
- socketUdpGetUnicastHopLimit,
144
- socketUdpSetReceiveBufferSize,
145
- socketUdpSetSendBufferSize,
146
- socketUdpSetUnicastHopLimit,
147
- socketUdpStream,
148
- udpSockets,
149
- } from './worker-socket-udp.js';
150
- import process from 'node:process';
130
+ createUdpSocket,
131
+ datagramStreams,
132
+ socketDatagramStreamDispose,
133
+ socketIncomingDatagramStreamReceive,
134
+ socketOutgoingDatagramStreamCheckSend,
135
+ socketOutgoingDatagramStreamSend,
136
+ socketUdpBindFinish,
137
+ socketUdpBindStart,
138
+ socketUdpDispose,
139
+ socketUdpGetLocalAddress,
140
+ socketUdpGetReceiveBufferSize,
141
+ socketUdpGetRemoteAddress,
142
+ socketUdpGetSendBufferSize,
143
+ socketUdpGetUnicastHopLimit,
144
+ socketUdpSetReceiveBufferSize,
145
+ socketUdpSetSendBufferSize,
146
+ socketUdpSetUnicastHopLimit,
147
+ socketUdpStream,
148
+ udpSockets,
149
+ } from "./worker-socket-udp.js";
150
+ import process from "node:process";
151
151
 
152
152
  export function log(msg) {
153
- if (debug) {
154
- process._rawDebug(msg);
155
- }
153
+ if (debug) {
154
+ process._rawDebug(msg);
155
+ }
156
156
  }
157
157
 
158
158
  let pollCnt = 0,
159
- streamCnt = 0,
160
- futureCnt = 0;
159
+ streamCnt = 0,
160
+ futureCnt = 0;
161
161
 
162
162
  /**
163
163
  * @typedef {{
@@ -192,68 +192,68 @@ export const streams = new Map();
192
192
  export const futures = new Map();
193
193
 
194
194
  export function createReadableStreamPollState(nodeStream) {
195
- const pollState = {
196
- ready: true,
197
- listener: null,
198
- polls: [],
199
- parentStream: nodeStream,
200
- };
201
- function pollDone() {
202
- pollStateReady(pollState);
203
- nodeStream.off('end', pollDone);
204
- nodeStream.off('close', pollDone);
205
- nodeStream.off('error', pollDone);
206
- }
207
- nodeStream.on('end', pollDone);
208
- nodeStream.on('close', pollDone);
209
- nodeStream.on('error', pollDone);
210
- return pollState;
195
+ const pollState = {
196
+ ready: true,
197
+ listener: null,
198
+ polls: [],
199
+ parentStream: nodeStream,
200
+ };
201
+ function pollDone() {
202
+ pollStateReady(pollState);
203
+ nodeStream.off("end", pollDone);
204
+ nodeStream.off("close", pollDone);
205
+ nodeStream.off("error", pollDone);
206
+ }
207
+ nodeStream.on("end", pollDone);
208
+ nodeStream.on("close", pollDone);
209
+ nodeStream.on("error", pollDone);
210
+ return pollState;
211
211
  }
212
212
 
213
213
  /**
214
214
  * @param {NodeJS.ReadableStream | NodeJS.WritableStream} stream
215
215
  */
216
216
  export function createReadableStream(
217
- nodeStream,
218
- pollState = createReadableStreamPollState(nodeStream)
217
+ nodeStream,
218
+ pollState = createReadableStreamPollState(nodeStream),
219
219
  ) {
220
- const stream = {
221
- stream: nodeStream,
222
- flushPromise: null,
223
- pollState,
224
- };
225
- streams.set(++streamCnt, stream);
226
- return streamCnt;
220
+ const stream = {
221
+ stream: nodeStream,
222
+ flushPromise: null,
223
+ pollState,
224
+ };
225
+ streams.set(++streamCnt, stream);
226
+ return streamCnt;
227
227
  }
228
228
 
229
229
  export function createWritableStream(nodeStream) {
230
- const pollState = {
231
- ready: true,
232
- listener: null,
233
- polls: [],
234
- parentStream: null,
235
- };
236
- const stream = {
237
- stream: nodeStream,
238
- flushPromise: null,
239
- pollState,
240
- };
241
- streams.set(++streamCnt, stream);
242
- function pollReady() {
243
- pollStateReady(pollState);
244
- }
245
- function pollDone() {
246
- pollStateReady(pollState);
247
- nodeStream.off('drain', pollReady);
248
- nodeStream.off('finish', pollDone);
249
- nodeStream.off('error', pollDone);
250
- nodeStream.off('close', pollDone);
251
- }
252
- nodeStream.on('drain', pollReady);
253
- nodeStream.on('finish', pollDone);
254
- nodeStream.on('error', pollDone);
255
- nodeStream.on('close', pollDone);
256
- return streamCnt;
230
+ const pollState = {
231
+ ready: true,
232
+ listener: null,
233
+ polls: [],
234
+ parentStream: null,
235
+ };
236
+ const stream = {
237
+ stream: nodeStream,
238
+ flushPromise: null,
239
+ pollState,
240
+ };
241
+ streams.set(++streamCnt, stream);
242
+ function pollReady() {
243
+ pollStateReady(pollState);
244
+ }
245
+ function pollDone() {
246
+ pollStateReady(pollState);
247
+ nodeStream.off("drain", pollReady);
248
+ nodeStream.off("finish", pollDone);
249
+ nodeStream.off("error", pollDone);
250
+ nodeStream.off("close", pollDone);
251
+ }
252
+ nodeStream.on("drain", pollReady);
253
+ nodeStream.on("finish", pollDone);
254
+ nodeStream.on("error", pollDone);
255
+ nodeStream.on("close", pollDone);
256
+ return streamCnt;
257
257
  }
258
258
 
259
259
  // Stdio
@@ -266,10 +266,10 @@ createWritableStream(stderr);
266
266
  * @param {NodeJS.ReadableStream | NodeJS.WritableStream} stream
267
267
  */
268
268
  function streamError(err) {
269
- return {
270
- tag: 'last-operation-failed',
271
- val: { code: err.code, message: err.message, stack: err.stack },
272
- };
269
+ return {
270
+ tag: "last-operation-failed",
271
+ val: { code: err.code, message: err.message, stack: err.stack },
272
+ };
273
273
  }
274
274
 
275
275
  /**
@@ -277,21 +277,21 @@ function streamError(err) {
277
277
  * @returns {{ stream: NodeJS.ReadableStream | NodeJS.WritableStream, polls: number[] }}
278
278
  */
279
279
  export function getStreamOrThrow(streamId) {
280
- if (!streamId) {
281
- throw new Error('wasi-io trap: no stream id provided');
282
- }
283
- const stream = streams.get(streamId);
284
- // not in unfinished streams <=> closed
285
- if (!stream) {
286
- throw { tag: 'closed' };
287
- }
288
- if (stream.stream.errored) {
289
- throw streamError(stream.stream.errored);
290
- }
291
- if (stream.stream.closed) {
292
- throw { tag: 'closed' };
293
- }
294
- return stream;
280
+ if (!streamId) {
281
+ throw new Error("wasi-io trap: no stream id provided");
282
+ }
283
+ const stream = streams.get(streamId);
284
+ // not in unfinished streams <=> closed
285
+ if (!stream) {
286
+ throw { tag: "closed" };
287
+ }
288
+ if (stream.stream.errored) {
289
+ throw streamError(stream.stream.errored);
290
+ }
291
+ if (stream.stream.closed) {
292
+ throw { tag: "closed" };
293
+ }
294
+ return stream;
295
295
  }
296
296
 
297
297
  /**
@@ -301,677 +301,631 @@ export function getStreamOrThrow(streamId) {
301
301
  * @returns {Promise<any>}
302
302
  */
303
303
  function handle(call, id, payload) {
304
- if (uncaughtException) {
305
- throw uncaughtException;
306
- }
307
- switch (call) {
304
+ if (uncaughtException) {
305
+ throw uncaughtException;
306
+ }
307
+ switch (call) {
308
308
  // Http
309
309
  case HTTP_CREATE_REQUEST: {
310
- const {
311
- method,
312
- scheme,
313
- authority,
314
- pathWithQuery,
315
- headers,
316
- body,
317
- connectTimeout,
318
- betweenBytesTimeout,
319
- firstByteTimeout,
320
- } = payload;
321
- return createFuture(
322
- createHttpRequest(
323
- method,
324
- scheme,
325
- authority,
326
- pathWithQuery,
327
- headers,
328
- body,
329
- connectTimeout,
330
- betweenBytesTimeout,
331
- firstByteTimeout
332
- )
333
- );
310
+ const {
311
+ method,
312
+ scheme,
313
+ authority,
314
+ pathWithQuery,
315
+ headers,
316
+ body,
317
+ connectTimeout,
318
+ betweenBytesTimeout,
319
+ firstByteTimeout,
320
+ } = payload;
321
+ return createFuture(
322
+ createHttpRequest(
323
+ method,
324
+ scheme,
325
+ authority,
326
+ pathWithQuery,
327
+ headers,
328
+ body,
329
+ connectTimeout,
330
+ betweenBytesTimeout,
331
+ firstByteTimeout,
332
+ ),
333
+ );
334
334
  }
335
335
  case OUTPUT_STREAM_CREATE | HTTP: {
336
- const stream = new PassThrough();
337
- // content length is passed as payload
338
- stream.contentLength = payload;
339
- stream.bytesRemaining = payload;
340
- return createWritableStream(stream);
336
+ const stream = new PassThrough();
337
+ // content length is passed as payload
338
+ stream.contentLength = payload;
339
+ stream.bytesRemaining = payload;
340
+ return createWritableStream(stream);
341
341
  }
342
342
  case OUTPUT_STREAM_SUBSCRIBE | HTTP:
343
343
  case OUTPUT_STREAM_FLUSH | HTTP:
344
344
  case OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | HTTP: {
345
- // http flush is a noop
346
- const { stream } = getStreamOrThrow(id);
347
- if (call === (OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | HTTP)) {
348
- stream.bytesRemaining -= payload.byteLength;
349
- if (stream.bytesRemaining < 0) {
350
- throw {
351
- tag: 'last-operation-failed',
352
- val: {
353
- tag: 'HTTP-request-body-size',
354
- val: stream.contentLength - stream.bytesRemaining,
355
- },
356
- };
357
- }
358
- }
359
- // otherwise fall through to generic implementation
360
- return handle(call & ~HTTP, id, payload);
361
- }
362
- case OUTPUT_STREAM_WRITE | HTTP: {
363
- const { stream } = getStreamOrThrow(id);
345
+ // http flush is a noop
346
+ const { stream } = getStreamOrThrow(id);
347
+ if (call === (OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | HTTP)) {
364
348
  stream.bytesRemaining -= payload.byteLength;
365
349
  if (stream.bytesRemaining < 0) {
366
- throw {
367
- tag: 'last-operation-failed',
368
- val: {
369
- tag: 'HTTP-request-body-size',
370
- val: stream.contentLength - stream.bytesRemaining,
371
- },
372
- };
350
+ throw {
351
+ tag: "last-operation-failed",
352
+ val: {
353
+ tag: "HTTP-request-body-size",
354
+ val: stream.contentLength - stream.bytesRemaining,
355
+ },
356
+ };
373
357
  }
374
- const output = handle(OUTPUT_STREAM_WRITE, id, payload);
375
- return output;
358
+ }
359
+ // otherwise fall through to generic implementation
360
+ return handle(call & ~HTTP, id, payload);
361
+ }
362
+ case OUTPUT_STREAM_WRITE | HTTP: {
363
+ const { stream } = getStreamOrThrow(id);
364
+ stream.bytesRemaining -= payload.byteLength;
365
+ if (stream.bytesRemaining < 0) {
366
+ throw {
367
+ tag: "last-operation-failed",
368
+ val: {
369
+ tag: "HTTP-request-body-size",
370
+ val: stream.contentLength - stream.bytesRemaining,
371
+ },
372
+ };
373
+ }
374
+ const output = handle(OUTPUT_STREAM_WRITE, id, payload);
375
+ return output;
376
376
  }
377
377
  case OUTPUT_STREAM_DISPOSE | HTTP:
378
- throw new Error(
379
- 'wasi-io trap: Output stream dispose not implemented as an IO-call for HTTP'
380
- );
378
+ throw new Error("wasi-io trap: Output stream dispose not implemented as an IO-call for HTTP");
381
379
  case HTTP_OUTPUT_STREAM_FINISH: {
382
- let stream;
383
- try {
384
- ({ stream } = getStreamOrThrow(id));
385
- } catch (e) {
386
- if (e.tag === 'closed') {
387
- throw { tag: 'internal-error', val: 'stream closed' };
388
- }
389
- if (e.tag === 'last-operation-failed') {
390
- throw { tag: 'internal-error', val: e.val.message };
391
- }
380
+ let stream;
381
+ try {
382
+ ({ stream } = getStreamOrThrow(id));
383
+ } catch (e) {
384
+ if (e.tag === "closed") {
385
+ throw { tag: "internal-error", val: "stream closed" };
392
386
  }
393
- if (stream.bytesRemaining > 0) {
394
- throw {
395
- tag: 'HTTP-request-body-size',
396
- val: stream.contentLength - stream.bytesRemaining,
397
- };
398
- }
399
- if (stream.bytesRemaining < 0) {
400
- throw {
401
- tag: 'HTTP-request-body-size',
402
- val: stream.contentLength - stream.bytesRemaining,
403
- };
387
+ if (e.tag === "last-operation-failed") {
388
+ throw { tag: "internal-error", val: e.val.message };
404
389
  }
405
- stream.end();
406
- return;
390
+ }
391
+ if (stream.bytesRemaining > 0) {
392
+ throw {
393
+ tag: "HTTP-request-body-size",
394
+ val: stream.contentLength - stream.bytesRemaining,
395
+ };
396
+ }
397
+ if (stream.bytesRemaining < 0) {
398
+ throw {
399
+ tag: "HTTP-request-body-size",
400
+ val: stream.contentLength - stream.bytesRemaining,
401
+ };
402
+ }
403
+ stream.end();
404
+ return;
407
405
  }
408
406
  case HTTP_OUTGOING_BODY_DISPOSE:
409
- if (debug && !streams.has(id)) {
410
- console.warn(`wasi-io: stream ${id} not found to dispose`);
411
- }
412
- streams.delete(id);
413
- return;
407
+ if (debug && !streams.has(id)) {
408
+ console.warn(`wasi-io: stream ${id} not found to dispose`);
409
+ }
410
+ streams.delete(id);
411
+ return;
414
412
  case HTTP_SERVER_START:
415
- return startHttpServer(id, payload);
413
+ return startHttpServer(id, payload);
416
414
  case HTTP_SERVER_STOP:
417
- return stopHttpServer(id);
415
+ return stopHttpServer(id);
418
416
  case HTTP_SERVER_SET_OUTGOING_RESPONSE:
419
- return setOutgoingResponse(id, payload);
417
+ return setOutgoingResponse(id, payload);
420
418
  case HTTP_SERVER_CLEAR_OUTGOING_RESPONSE:
421
- return clearOutgoingResponse(id);
419
+ return clearOutgoingResponse(id);
422
420
  case HTTP_SERVER_GET_ADDRESS:
423
- return getHttpServerAddress(id);
421
+ return getHttpServerAddress(id);
424
422
 
425
- // Sockets name resolution
423
+ // Sockets name resolution
426
424
  case SOCKET_RESOLVE_ADDRESS_CREATE_REQUEST:
427
- return createFuture(socketResolveAddress(payload));
425
+ return createFuture(socketResolveAddress(payload));
428
426
  case SOCKET_RESOLVE_ADDRESS_SUBSCRIBE_REQUEST:
429
- return createPoll(futures.get(id).pollState);
427
+ return createPoll(futures.get(id).pollState);
430
428
  case SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST:
431
- return void futureDispose(id, true);
429
+ return void futureDispose(id, true);
432
430
  case SOCKET_RESOLVE_ADDRESS_TAKE_REQUEST: {
433
- const val = futureTakeValue(id);
434
- if (val === undefined) {
435
- throw 'would-block';
436
- }
437
- // double take avoidance is ensured
438
- return val.val;
431
+ const val = futureTakeValue(id);
432
+ if (val === undefined) {
433
+ throw "would-block";
434
+ }
435
+ // double take avoidance is ensured
436
+ return val.val;
439
437
  }
440
438
 
441
439
  // Sockets TCP
442
440
  case SOCKET_TCP_ACCEPT:
443
- return socketTcpAccept(id);
441
+ return socketTcpAccept(id);
444
442
  case SOCKET_TCP_CREATE_HANDLE:
445
- return createTcpSocket();
443
+ return createTcpSocket();
446
444
  case SOCKET_TCP_BIND_START:
447
- return socketTcpBindStart(id, payload.localAddress, payload.family);
445
+ return socketTcpBindStart(id, payload.localAddress, payload.family);
448
446
  case SOCKET_TCP_BIND_FINISH:
449
- return socketTcpFinish(id, SOCKET_STATE_BIND, SOCKET_STATE_BOUND);
447
+ return socketTcpFinish(id, SOCKET_STATE_BIND, SOCKET_STATE_BOUND);
450
448
  case SOCKET_TCP_CONNECT_START:
451
- return socketTcpConnectStart(
452
- id,
453
- payload.remoteAddress,
454
- payload.family
455
- );
449
+ return socketTcpConnectStart(id, payload.remoteAddress, payload.family);
456
450
  case SOCKET_TCP_CONNECT_FINISH:
457
- return socketTcpFinish(
458
- id,
459
- SOCKET_STATE_CONNECT,
460
- SOCKET_STATE_CONNECTION
461
- );
451
+ return socketTcpFinish(id, SOCKET_STATE_CONNECT, SOCKET_STATE_CONNECTION);
462
452
  case SOCKET_TCP_LISTEN_START:
463
- return socketTcpListenStart(id);
453
+ return socketTcpListenStart(id);
464
454
  case SOCKET_TCP_LISTEN_FINISH:
465
- return socketTcpFinish(
466
- id,
467
- SOCKET_STATE_LISTEN,
468
- SOCKET_STATE_LISTENER
469
- );
455
+ return socketTcpFinish(id, SOCKET_STATE_LISTEN, SOCKET_STATE_LISTENER);
470
456
  case SOCKET_TCP_IS_LISTENING:
471
- return tcpSockets.get(id).state === SOCKET_STATE_LISTENER;
457
+ return tcpSockets.get(id).state === SOCKET_STATE_LISTENER;
472
458
  case SOCKET_GET_DEFAULT_SEND_BUFFER_SIZE:
473
- return getDefaultSendBufferSize(id);
459
+ return getDefaultSendBufferSize(id);
474
460
  case SOCKET_GET_DEFAULT_RECEIVE_BUFFER_SIZE:
475
- return getDefaultReceiveBufferSize(id);
461
+ return getDefaultReceiveBufferSize(id);
476
462
  case SOCKET_TCP_SET_LISTEN_BACKLOG_SIZE:
477
- return socketTcpSetListenBacklogSize(id);
463
+ return socketTcpSetListenBacklogSize(id);
478
464
  case SOCKET_TCP_GET_LOCAL_ADDRESS:
479
- return socketTcpGetLocalAddress(id);
465
+ return socketTcpGetLocalAddress(id);
480
466
  case SOCKET_TCP_GET_REMOTE_ADDRESS:
481
- return socketTcpGetRemoteAddress(id);
467
+ return socketTcpGetRemoteAddress(id);
482
468
  case SOCKET_TCP_SHUTDOWN:
483
- return socketTcpShutdown(id, payload);
469
+ return socketTcpShutdown(id, payload);
484
470
  case SOCKET_TCP_SUBSCRIBE:
485
- return createPoll(tcpSockets.get(id).pollState);
471
+ return createPoll(tcpSockets.get(id).pollState);
486
472
  case SOCKET_TCP_SET_KEEP_ALIVE:
487
- return socketTcpSetKeepAlive(id, payload);
473
+ return socketTcpSetKeepAlive(id, payload);
488
474
  case SOCKET_TCP_DISPOSE:
489
- return socketTcpDispose(id);
475
+ return socketTcpDispose(id);
490
476
 
491
- // Sockets UDP
477
+ // Sockets UDP
492
478
  case SOCKET_UDP_CREATE_HANDLE:
493
- return createUdpSocket(payload);
479
+ return createUdpSocket(payload);
494
480
  case SOCKET_UDP_BIND_START:
495
- return socketUdpBindStart(id, payload.localAddress, payload.family);
481
+ return socketUdpBindStart(id, payload.localAddress, payload.family);
496
482
  case SOCKET_UDP_BIND_FINISH:
497
- return socketUdpBindFinish(id);
483
+ return socketUdpBindFinish(id);
498
484
  case SOCKET_UDP_STREAM:
499
- return socketUdpStream(id, payload);
485
+ return socketUdpStream(id, payload);
500
486
  case SOCKET_UDP_SUBSCRIBE:
501
- return createPoll(udpSockets.get(id).pollState);
487
+ return createPoll(udpSockets.get(id).pollState);
502
488
  case SOCKET_UDP_GET_LOCAL_ADDRESS:
503
- return socketUdpGetLocalAddress(id);
489
+ return socketUdpGetLocalAddress(id);
504
490
  case SOCKET_UDP_GET_REMOTE_ADDRESS:
505
- return socketUdpGetRemoteAddress(id);
491
+ return socketUdpGetRemoteAddress(id);
506
492
  case SOCKET_UDP_SET_RECEIVE_BUFFER_SIZE:
507
- return socketUdpSetReceiveBufferSize(id, payload);
493
+ return socketUdpSetReceiveBufferSize(id, payload);
508
494
  case SOCKET_UDP_SET_SEND_BUFFER_SIZE:
509
- return socketUdpSetSendBufferSize(id, payload);
495
+ return socketUdpSetSendBufferSize(id, payload);
510
496
  case SOCKET_UDP_SET_UNICAST_HOP_LIMIT:
511
- return socketUdpSetUnicastHopLimit(id, payload);
497
+ return socketUdpSetUnicastHopLimit(id, payload);
512
498
  case SOCKET_UDP_GET_RECEIVE_BUFFER_SIZE:
513
- return socketUdpGetReceiveBufferSize(id);
499
+ return socketUdpGetReceiveBufferSize(id);
514
500
  case SOCKET_UDP_GET_SEND_BUFFER_SIZE:
515
- return socketUdpGetSendBufferSize(id);
501
+ return socketUdpGetSendBufferSize(id);
516
502
  case SOCKET_UDP_GET_UNICAST_HOP_LIMIT:
517
- return socketUdpGetUnicastHopLimit(id);
503
+ return socketUdpGetUnicastHopLimit(id);
518
504
  case SOCKET_UDP_DISPOSE:
519
- return socketUdpDispose(id);
505
+ return socketUdpDispose(id);
520
506
 
521
507
  case SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE:
522
- return socketIncomingDatagramStreamReceive(id, payload);
508
+ return socketIncomingDatagramStreamReceive(id, payload);
523
509
  case SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND:
524
- return socketOutgoingDatagramStreamCheckSend(id);
510
+ return socketOutgoingDatagramStreamCheckSend(id);
525
511
  case SOCKET_OUTGOING_DATAGRAM_STREAM_SEND:
526
- return socketOutgoingDatagramStreamSend(id, payload);
512
+ return socketOutgoingDatagramStreamSend(id, payload);
527
513
  case SOCKET_DATAGRAM_STREAM_SUBSCRIBE:
528
- return createPoll(datagramStreams.get(id).pollState);
514
+ return createPoll(datagramStreams.get(id).pollState);
529
515
  case SOCKET_DATAGRAM_STREAM_DISPOSE:
530
- return socketDatagramStreamDispose(id);
516
+ return socketDatagramStreamDispose(id);
531
517
 
532
- // Stdio
518
+ // Stdio
533
519
  case OUTPUT_STREAM_BLOCKING_FLUSH | STDOUT:
534
520
  case OUTPUT_STREAM_BLOCKING_FLUSH | STDERR:
535
- // no blocking flush for stdio in Node.js
536
- return;
521
+ // no blocking flush for stdio in Node.js
522
+ return;
537
523
  case OUTPUT_STREAM_DISPOSE | STDOUT:
538
524
  case OUTPUT_STREAM_DISPOSE | STDERR:
539
- return;
525
+ return;
540
526
  case INPUT_STREAM_CREATE | STDIN: {
541
- return createReadableStream(
542
- new Readable({
543
- read(n) {
544
- if (n <= 0) {
545
- return void this.push(null);
546
- }
547
- let buf = Buffer.allocUnsafeSlow(n);
548
- read(0, buf, 0, n, null, (err, bytesRead) => {
549
- if (err) {
550
- if (err.code === 'EAGAIN') {
551
- nextTick(() => void this._read(n));
552
- return;
553
- }
554
- this.destroy(err);
555
- } else if (bytesRead > 0) {
556
- if (bytesRead !== buf.length) {
557
- const dst =
558
- Buffer.allocUnsafeSlow(bytesRead);
559
- buf.copy(dst, 0, 0, bytesRead);
560
- buf = dst;
561
- }
562
- this.push(buf);
563
- } else {
564
- this.push(null);
565
- }
566
- });
567
- },
568
- })
569
- );
527
+ return createReadableStream(
528
+ new Readable({
529
+ read(n) {
530
+ if (n <= 0) {
531
+ return void this.push(null);
532
+ }
533
+ let buf = Buffer.allocUnsafeSlow(n);
534
+ read(0, buf, 0, n, null, (err, bytesRead) => {
535
+ if (err) {
536
+ if (err.code === "EAGAIN") {
537
+ nextTick(() => void this._read(n));
538
+ return;
539
+ }
540
+ this.destroy(err);
541
+ } else if (bytesRead > 0) {
542
+ if (bytesRead !== buf.length) {
543
+ const dst = Buffer.allocUnsafeSlow(bytesRead);
544
+ buf.copy(dst, 0, 0, bytesRead);
545
+ buf = dst;
546
+ }
547
+ this.push(buf);
548
+ } else {
549
+ this.push(null);
550
+ }
551
+ });
552
+ },
553
+ }),
554
+ );
570
555
  }
571
556
 
572
557
  // Clocks
573
558
  case CLOCKS_DURATION_SUBSCRIBE:
574
- payload = hrtime.bigint() + payload;
575
- // fallthrough
559
+ payload = hrtime.bigint() + payload;
560
+ // fallthrough
576
561
  case CLOCKS_INSTANT_SUBSCRIBE: {
577
- const pollState = {
578
- ready: false,
579
- listener: null,
580
- polls: [],
581
- parentStream: null,
582
- };
583
- subscribeInstant(pollState, payload);
584
- return createPoll(pollState);
562
+ const pollState = {
563
+ ready: false,
564
+ listener: null,
565
+ polls: [],
566
+ parentStream: null,
567
+ };
568
+ subscribeInstant(pollState, payload);
569
+ return createPoll(pollState);
585
570
  }
586
571
 
587
572
  // Filesystem
588
573
  case INPUT_STREAM_CREATE | FILE: {
589
- const { fd, offset } = payload;
590
- const stream = createReadStream(null, {
591
- fd,
592
- autoClose: false,
593
- highWaterMark: 64 * 1024,
594
- start: Number(offset),
595
- });
596
- return createReadableStream(stream);
574
+ const { fd, offset } = payload;
575
+ const stream = createReadStream(null, {
576
+ fd,
577
+ autoClose: false,
578
+ highWaterMark: 64 * 1024,
579
+ start: Number(offset),
580
+ });
581
+ return createReadableStream(stream);
597
582
  }
598
583
  case OUTPUT_STREAM_CREATE | FILE: {
599
- const { fd, offset } = payload;
600
- const stream = createWriteStream(null, {
601
- fd,
602
- autoClose: false,
603
- emitClose: false,
604
- highWaterMark: 64 * 1024,
605
- start: Number(offset),
606
- });
607
- return createWritableStream(stream);
608
- }
584
+ const { fd, offset } = payload;
585
+ const stream = createWriteStream(null, {
586
+ fd,
587
+ autoClose: false,
588
+ emitClose: false,
589
+ highWaterMark: 64 * 1024,
590
+ start: Number(offset),
591
+ });
592
+ return createWritableStream(stream);
609
593
  }
594
+ }
610
595
 
611
- // Generic call implementations (streams + polls)
612
- switch (call & CALL_MASK) {
596
+ // Generic call implementations (streams + polls)
597
+ switch (call & CALL_MASK) {
613
598
  case INPUT_STREAM_READ: {
614
- const stream = getStreamOrThrow(id);
615
- if (!stream.pollState.ready) {
616
- return new Uint8Array();
617
- }
618
- const res = stream.stream.read(
619
- Math.min(stream.stream.readableLength, Number(payload))
620
- );
621
- if (res) {
622
- return res;
623
- }
624
- if (stream.stream.readableEnded) {
625
- throw { tag: 'closed' };
626
- }
599
+ const stream = getStreamOrThrow(id);
600
+ if (!stream.pollState.ready) {
627
601
  return new Uint8Array();
602
+ }
603
+ const res = stream.stream.read(Math.min(stream.stream.readableLength, Number(payload)));
604
+ if (res) {
605
+ return res;
606
+ }
607
+ if (stream.stream.readableEnded) {
608
+ throw { tag: "closed" };
609
+ }
610
+ return new Uint8Array();
628
611
  }
629
612
  case INPUT_STREAM_BLOCKING_READ: {
630
- const { pollState } = streams.get(id);
631
- pollStateCheck(pollState);
632
- if (pollState.ready) {
633
- return handle(
634
- INPUT_STREAM_READ | (call & CALL_TYPE_MASK),
635
- id,
636
- payload
637
- );
638
- }
639
- return new Promise(
640
- (resolve) => void (pollState.listener = resolve)
641
- ).then(() =>
642
- handle(INPUT_STREAM_READ | (call & CALL_TYPE_MASK), id, payload)
643
- );
613
+ const { pollState } = streams.get(id);
614
+ pollStateCheck(pollState);
615
+ if (pollState.ready) {
616
+ return handle(INPUT_STREAM_READ | (call & CALL_TYPE_MASK), id, payload);
617
+ }
618
+ return new Promise((resolve) => void (pollState.listener = resolve)).then(() =>
619
+ handle(INPUT_STREAM_READ | (call & CALL_TYPE_MASK), id, payload),
620
+ );
644
621
  }
645
622
  case INPUT_STREAM_SKIP:
646
- return handle(
647
- INPUT_STREAM_READ | (call & CALL_TYPE_MASK),
648
- id,
649
- new Uint8Array(Number(payload))
650
- );
623
+ return handle(
624
+ INPUT_STREAM_READ | (call & CALL_TYPE_MASK),
625
+ id,
626
+ new Uint8Array(Number(payload)),
627
+ );
651
628
  case INPUT_STREAM_BLOCKING_SKIP:
652
- return handle(
653
- INPUT_STREAM_BLOCKING_READ | (call & CALL_TYPE_MASK),
654
- id,
655
- new Uint8Array(Number(payload))
656
- );
629
+ return handle(
630
+ INPUT_STREAM_BLOCKING_READ | (call & CALL_TYPE_MASK),
631
+ id,
632
+ new Uint8Array(Number(payload)),
633
+ );
657
634
  case INPUT_STREAM_SUBSCRIBE:
658
- return createPoll(streams.get(id).pollState);
635
+ return createPoll(streams.get(id).pollState);
659
636
  case INPUT_STREAM_DISPOSE: {
660
- const stream = streams.get(id);
661
- verifyPollsDroppedForDrop(stream.pollState, 'input stream');
662
- streams.delete(id);
663
- return;
637
+ const stream = streams.get(id);
638
+ verifyPollsDroppedForDrop(stream.pollState, "input stream");
639
+ streams.delete(id);
640
+ return;
664
641
  }
665
642
  case OUTPUT_STREAM_CHECK_WRITE: {
666
- const { stream, pollState } = getStreamOrThrow(id);
667
- const bytes = stream.writableHighWaterMark - stream.writableLength;
668
- if (bytes === 0) {
669
- pollState.ready = false;
670
- }
671
- return BigInt(bytes);
643
+ const { stream, pollState } = getStreamOrThrow(id);
644
+ const bytes = stream.writableHighWaterMark - stream.writableLength;
645
+ if (bytes === 0) {
646
+ pollState.ready = false;
647
+ }
648
+ return BigInt(bytes);
672
649
  }
673
650
  case OUTPUT_STREAM_WRITE: {
674
- const { stream } = getStreamOrThrow(id);
675
- if (
676
- payload.byteLength >
677
- stream.writableHighWaterMark - stream.writableLength
678
- ) {
679
- throw new Error(
680
- 'wasi-io trap: attempt to write too many bytes'
681
- );
682
- }
683
- return void stream.write(payload);
651
+ const { stream } = getStreamOrThrow(id);
652
+ if (payload.byteLength > stream.writableHighWaterMark - stream.writableLength) {
653
+ throw new Error("wasi-io trap: attempt to write too many bytes");
654
+ }
655
+ return void stream.write(payload);
684
656
  }
685
657
  case OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH: {
686
- const stream = getStreamOrThrow(id);
687
- // if an existing flush, try again after that
688
- if (stream.flushPromise) {
689
- return stream.flushPromise.then(() =>
690
- handle(call, id, payload)
691
- );
692
- }
693
- if (
694
- payload.byteLength >
695
- stream.stream.writableHighWaterMark -
696
- stream.stream.writableLength
697
- ) {
698
- throw new Error(
699
- 'wasi-io trap: Cannot write more than permitted writable length'
700
- );
701
- }
702
- stream.pollState.ready = false;
703
- return (stream.flushPromise = new Promise((resolve, reject) => {
704
- if (stream.stream === stdout || stream.stream === stderr) {
705
- // Inside workers, NodeJS actually queues writes destined for
706
- // stdout/stderr in a port that is only flushed on exit of the worker.
707
- //
708
- // In this case, we cannot attempt to wait for the promise.
709
- //
710
- // This code may have to be reworked for browsers.
711
- //
712
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
713
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
714
- // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
715
- stream.stream.write(payload);
716
- stream.flushPromise = null;
717
- pollStateReady(stream.pollState);
718
- resolve(BigInt(payload.byteLength));
719
- } else {
720
- stream.stream.write(payload, (err) => {
721
- stream.flushPromise = null;
722
- pollStateReady(stream.pollState);
723
- if (err) {
724
- return void reject(streamError(err));
725
- }
726
- resolve(BigInt(payload.byteLength));
727
- });
658
+ const stream = getStreamOrThrow(id);
659
+ // if an existing flush, try again after that
660
+ if (stream.flushPromise) {
661
+ return stream.flushPromise.then(() => handle(call, id, payload));
662
+ }
663
+ if (payload.byteLength > stream.stream.writableHighWaterMark - stream.stream.writableLength) {
664
+ throw new Error("wasi-io trap: Cannot write more than permitted writable length");
665
+ }
666
+ stream.pollState.ready = false;
667
+ return (stream.flushPromise = new Promise((resolve, reject) => {
668
+ if (stream.stream === stdout || stream.stream === stderr) {
669
+ // Inside workers, NodeJS actually queues writes destined for
670
+ // stdout/stderr in a port that is only flushed on exit of the worker.
671
+ //
672
+ // In this case, we cannot attempt to wait for the promise.
673
+ //
674
+ // This code may have to be reworked for browsers.
675
+ //
676
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
677
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
678
+ // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
679
+ stream.stream.write(payload);
680
+ stream.flushPromise = null;
681
+ pollStateReady(stream.pollState);
682
+ resolve(BigInt(payload.byteLength));
683
+ } else {
684
+ stream.stream.write(payload, (err) => {
685
+ stream.flushPromise = null;
686
+ pollStateReady(stream.pollState);
687
+ if (err) {
688
+ return void reject(streamError(err));
728
689
  }
729
- }));
690
+ resolve(BigInt(payload.byteLength));
691
+ });
692
+ }
693
+ }));
730
694
  }
731
695
  case OUTPUT_STREAM_FLUSH: {
732
- const stream = getStreamOrThrow(id);
733
- if (stream.flushPromise) {
734
- return;
735
- }
736
- stream.pollState.ready = false;
737
- stream.flushPromise = new Promise((resolve, reject) => {
738
- if (stream.stream === stdout || stream.stream === stderr) {
739
- // Inside workers, NodeJS actually queues writes destined for
740
- // stdout/stderr in a port that is only flushed on exit of the worker.
741
- //
742
- // In this case, we cannot attempt to wait for the promise.
743
- //
744
- // This code may have to be reworked for browsers.
745
- //
746
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
747
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
748
- // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
749
- stream.flushPromise = null;
750
- pollStateReady(stream.pollState);
751
- resolve();
752
- } else {
753
- // For all other writes, we can perform the actual write and expect the write to complete
754
- // and trigger the relevant callback
755
- stream.stream.write(new Uint8Array([]), (err) => {
756
- stream.flushPromise = null;
757
- pollStateReady(stream.pollState);
758
- if (err) {
759
- return void reject(streamError(err));
760
- }
761
- resolve();
762
- });
696
+ const stream = getStreamOrThrow(id);
697
+ if (stream.flushPromise) {
698
+ return;
699
+ }
700
+ stream.pollState.ready = false;
701
+ stream.flushPromise = new Promise((resolve, reject) => {
702
+ if (stream.stream === stdout || stream.stream === stderr) {
703
+ // Inside workers, NodeJS actually queues writes destined for
704
+ // stdout/stderr in a port that is only flushed on exit of the worker.
705
+ //
706
+ // In this case, we cannot attempt to wait for the promise.
707
+ //
708
+ // This code may have to be reworked for browsers.
709
+ //
710
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
711
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
712
+ // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
713
+ stream.flushPromise = null;
714
+ pollStateReady(stream.pollState);
715
+ resolve();
716
+ } else {
717
+ // For all other writes, we can perform the actual write and expect the write to complete
718
+ // and trigger the relevant callback
719
+ stream.stream.write(new Uint8Array([]), (err) => {
720
+ stream.flushPromise = null;
721
+ pollStateReady(stream.pollState);
722
+ if (err) {
723
+ return void reject(streamError(err));
763
724
  }
764
- });
765
- return stream.flushPromise;
725
+ resolve();
726
+ });
727
+ }
728
+ });
729
+ return stream.flushPromise;
766
730
  }
767
731
  case OUTPUT_STREAM_BLOCKING_FLUSH: {
768
- const stream = getStreamOrThrow(id);
769
- if (stream.flushPromise) {
770
- return stream.flushPromise;
732
+ const stream = getStreamOrThrow(id);
733
+ if (stream.flushPromise) {
734
+ return stream.flushPromise;
735
+ }
736
+ return new Promise((resolve, reject) => {
737
+ if (stream.stream === stdout || stream.stream === stderr) {
738
+ // Inside workers, NodeJS actually queues writes destined for
739
+ // stdout/stderr in a port that is only flushed on exit of the worker.
740
+ //
741
+ // In this case, we cannot attempt to wait for the promise.
742
+ //
743
+ // This code may have to be reworked for browsers.
744
+ //
745
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
746
+ // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
747
+ // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
748
+ resolve();
749
+ } else {
750
+ // For all other writes, we can perform the actual write and expect the write to complete
751
+ // and trigger the relevant callback
752
+ stream.stream.write(new Uint8Array([]), (err) =>
753
+ err ? reject(streamError(err)) : resolve(),
754
+ );
771
755
  }
772
- return new Promise((resolve, reject) => {
773
- if (stream.stream === stdout || stream.stream === stderr) {
774
- // Inside workers, NodeJS actually queues writes destined for
775
- // stdout/stderr in a port that is only flushed on exit of the worker.
776
- //
777
- // In this case, we cannot attempt to wait for the promise.
778
- //
779
- // This code may have to be reworked for browsers.
780
- //
781
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker/io.js#L288
782
- // see: https://github.com/nodejs/node/blob/v22.12.0/lib/internal/worker.js#L303
783
- // see: https://github.com/nodejs/node/blob/v22.12.0/typings/internalBinding/messaging.d.ts#L27
784
- resolve();
785
- } else {
786
- // For all other writes, we can perform the actual write and expect the write to complete
787
- // and trigger the relevant callback
788
- stream.stream.write(new Uint8Array([]), (err) =>
789
- err ? reject(streamError(err)) : resolve()
790
- );
791
- }
792
- });
756
+ });
793
757
  }
794
758
  case OUTPUT_STREAM_WRITE_ZEROES:
795
- return handle(
796
- OUTPUT_STREAM_WRITE | (call & CALL_TYPE_MASK),
797
- id,
798
- new Uint8Array(Number(payload))
799
- );
759
+ return handle(
760
+ OUTPUT_STREAM_WRITE | (call & CALL_TYPE_MASK),
761
+ id,
762
+ new Uint8Array(Number(payload)),
763
+ );
800
764
  case OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH:
801
- return handle(
802
- OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH |
803
- (call & CALL_TYPE_MASK),
804
- id,
805
- new Uint8Array(Number(payload))
806
- );
765
+ return handle(
766
+ OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | (call & CALL_TYPE_MASK),
767
+ id,
768
+ new Uint8Array(Number(payload)),
769
+ );
807
770
  case OUTPUT_STREAM_SPLICE: {
808
- const outputStream = getStreamOrThrow(id);
809
- const inputStream = getStreamOrThrow(payload.src);
810
- let bytesRemaining = Number(payload.len);
811
- let chunk;
812
- while (
813
- bytesRemaining > 0 &&
814
- (chunk = inputStream.stream.read(
815
- Math.min(
816
- outputStream.writableHighWaterMark -
817
- outputStream.writableLength,
818
- bytesRemaining
819
- )
820
- ))
821
- ) {
822
- bytesRemaining -= chunk.byteLength;
823
- outputStream.stream.write(chunk);
824
- }
825
- if (inputStream.stream.errored) {
826
- throw streamError(inputStream.stream.errored);
827
- }
828
- if (outputStream.stream.errored) {
829
- throw streamError(outputStream.stream.errored);
830
- }
831
- return payload.len - BigInt(bytesRemaining);
771
+ const outputStream = getStreamOrThrow(id);
772
+ const inputStream = getStreamOrThrow(payload.src);
773
+ let bytesRemaining = Number(payload.len);
774
+ let chunk;
775
+ while (
776
+ bytesRemaining > 0 &&
777
+ (chunk = inputStream.stream.read(
778
+ Math.min(
779
+ outputStream.writableHighWaterMark - outputStream.writableLength,
780
+ bytesRemaining,
781
+ ),
782
+ ))
783
+ ) {
784
+ bytesRemaining -= chunk.byteLength;
785
+ outputStream.stream.write(chunk);
786
+ }
787
+ if (inputStream.stream.errored) {
788
+ throw streamError(inputStream.stream.errored);
789
+ }
790
+ if (outputStream.stream.errored) {
791
+ throw streamError(outputStream.stream.errored);
792
+ }
793
+ return payload.len - BigInt(bytesRemaining);
832
794
  }
833
795
  case OUTPUT_STREAM_SUBSCRIBE:
834
- return createPoll(streams.get(id).pollState);
796
+ return createPoll(streams.get(id).pollState);
835
797
  case OUTPUT_STREAM_BLOCKING_SPLICE: {
836
- const outputStream = getStreamOrThrow(id);
837
- let promise = Promise.resolve();
838
- let resolve, reject;
839
- if (outputStream.stream.writableNeedDrain) {
840
- promise = new Promise((_resolve, _reject) => {
841
- outputStream.stream
842
- .once('drain', (resolve = _resolve))
843
- .once('error', (reject = _reject));
844
- }).then(
845
- () => {
846
- outputStream.stream.off('error', reject);
847
- },
848
- (err) => {
849
- outputStream.stream.off('drain', resolve);
850
- throw streamError(err);
851
- }
852
- );
853
- }
854
- const inputStream = getStreamOrThrow(payload.src);
855
- if (!inputStream.stream.readable) {
856
- promise = promise.then(() =>
857
- new Promise((_resolve, _reject) => {
858
- inputStream.stream
859
- .once('readable', (resolve = _resolve))
860
- .once('error', (reject = _reject));
861
- }).then(
862
- () => {
863
- inputStream.stream.off('error', reject);
864
- },
865
- (err) => {
866
- inputStream.stream.off('readable', resolve);
867
- throw streamError(err);
868
- }
869
- )
870
- );
871
- }
872
- return promise.then(() =>
873
- handle(OUTPUT_STREAM_SPLICE, id, payload)
798
+ const outputStream = getStreamOrThrow(id);
799
+ let promise = Promise.resolve();
800
+ let resolve, reject;
801
+ if (outputStream.stream.writableNeedDrain) {
802
+ promise = new Promise((_resolve, _reject) => {
803
+ outputStream.stream.once("drain", (resolve = _resolve)).once("error", (reject = _reject));
804
+ }).then(
805
+ () => {
806
+ outputStream.stream.off("error", reject);
807
+ },
808
+ (err) => {
809
+ outputStream.stream.off("drain", resolve);
810
+ throw streamError(err);
811
+ },
874
812
  );
813
+ }
814
+ const inputStream = getStreamOrThrow(payload.src);
815
+ if (!inputStream.stream.readable) {
816
+ promise = promise.then(() =>
817
+ new Promise((_resolve, _reject) => {
818
+ inputStream.stream
819
+ .once("readable", (resolve = _resolve))
820
+ .once("error", (reject = _reject));
821
+ }).then(
822
+ () => {
823
+ inputStream.stream.off("error", reject);
824
+ },
825
+ (err) => {
826
+ inputStream.stream.off("readable", resolve);
827
+ throw streamError(err);
828
+ },
829
+ ),
830
+ );
831
+ }
832
+ return promise.then(() => handle(OUTPUT_STREAM_SPLICE, id, payload));
875
833
  }
876
834
  case OUTPUT_STREAM_DISPOSE: {
877
- const stream = streams.get(id);
878
- verifyPollsDroppedForDrop(stream.pollState, 'output stream');
879
- stream.stream.end();
880
- streams.delete(id);
881
- return;
835
+ const stream = streams.get(id);
836
+ verifyPollsDroppedForDrop(stream.pollState, "output stream");
837
+ stream.stream.end();
838
+ streams.delete(id);
839
+ return;
882
840
  }
883
841
 
884
842
  case POLL_POLLABLE_READY:
885
- return polls.get(id).ready;
843
+ return polls.get(id).ready;
886
844
  case POLL_POLLABLE_BLOCK:
887
- payload = [id];
888
- // [intentional case fall-through]
845
+ payload = [id];
846
+ // [intentional case fall-through]
889
847
  case POLL_POLL_LIST: {
890
- if (payload.length === 0) {
891
- throw new Error('wasi-io trap: attempt to poll on empty list');
848
+ if (payload.length === 0) {
849
+ throw new Error("wasi-io trap: attempt to poll on empty list");
850
+ }
851
+ const doneList = [];
852
+ const pollList = payload.map((pollId) => polls.get(pollId));
853
+ for (const [idx, pollState] of pollList.entries()) {
854
+ pollStateCheck(pollState);
855
+ if (pollState.ready) {
856
+ doneList.push(idx);
892
857
  }
893
- const doneList = [];
894
- const pollList = payload.map((pollId) => polls.get(pollId));
858
+ }
859
+ if (doneList.length > 0) {
860
+ return new Uint32Array(doneList);
861
+ }
862
+ let readyPromiseResolve;
863
+ const readyPromise = new Promise((resolve) => void (readyPromiseResolve = resolve));
864
+ for (const poll of pollList) {
865
+ poll.listener = readyPromiseResolve;
866
+ }
867
+ return readyPromise.then(() => {
895
868
  for (const [idx, pollState] of pollList.entries()) {
896
- pollStateCheck(pollState);
897
- if (pollState.ready) {
898
- doneList.push(idx);
899
- }
869
+ pollState.listener = null;
870
+ if (pollState.ready) {
871
+ doneList.push(idx);
872
+ }
900
873
  }
901
- if (doneList.length > 0) {
902
- return new Uint32Array(doneList);
903
- }
904
- let readyPromiseResolve;
905
- const readyPromise = new Promise(
906
- (resolve) => void (readyPromiseResolve = resolve)
907
- );
908
- for (const poll of pollList) {
909
- poll.listener = readyPromiseResolve;
910
- }
911
- return readyPromise.then(() => {
912
- for (const [idx, pollState] of pollList.entries()) {
913
- pollState.listener = null;
914
- if (pollState.ready) {
915
- doneList.push(idx);
916
- }
917
- }
918
- return new Uint32Array(doneList);
919
- });
874
+ return new Uint32Array(doneList);
875
+ });
920
876
  }
921
877
  case POLL_POLLABLE_DISPOSE:
922
- if (!polls.delete(id)) {
923
- throw new Error(
924
- `wasi-io trap: Disposed a poll ${id} that does not exist`
925
- );
926
- }
927
- return;
878
+ if (!polls.delete(id)) {
879
+ throw new Error(`wasi-io trap: Disposed a poll ${id} that does not exist`);
880
+ }
881
+ return;
928
882
 
929
883
  case FUTURE_TAKE_VALUE:
930
- return futureTakeValue(id);
884
+ return futureTakeValue(id);
931
885
 
932
886
  case FUTURE_SUBSCRIBE: {
933
- const { pollState } = futures.get(id);
934
- const pollId = ++pollCnt;
935
- polls.set(pollId, pollState);
936
- return pollId;
887
+ const { pollState } = futures.get(id);
888
+ const pollId = ++pollCnt;
889
+ polls.set(pollId, pollState);
890
+ return pollId;
937
891
  }
938
892
  case FUTURE_DISPOSE:
939
- return void futureDispose(id, true);
893
+ return void futureDispose(id, true);
940
894
  default:
941
- throw new Error(
942
- `wasi-io trap: Unknown call ${call} (${reverseMap[call]}) with type ${
943
- reverseMap[call & CALL_TYPE_MASK]
944
- }`
945
- );
946
- }
895
+ throw new Error(
896
+ `wasi-io trap: Unknown call ${call} (${reverseMap[call]}) with type ${
897
+ reverseMap[call & CALL_TYPE_MASK]
898
+ }`,
899
+ );
900
+ }
947
901
  }
948
902
 
949
903
  /**
950
904
  * @param {PollState} pollState
951
905
  */
952
906
  function createPoll(pollState) {
953
- const pollId = ++pollCnt;
954
- pollState.polls.push(pollId);
955
- polls.set(pollId, pollState);
956
- return pollId;
907
+ const pollId = ++pollCnt;
908
+ pollState.polls.push(pollId);
909
+ polls.set(pollId, pollState);
910
+ return pollId;
957
911
  }
958
912
 
959
913
  function subscribeInstant(pollState, instant) {
960
- const duration = instant - hrtime.bigint();
961
- if (duration <= 0) {
962
- return pollStateReady(pollState);
963
- }
964
- function cb() {
965
- if (hrtime.bigint() < instant) {
966
- return subscribeInstant(pollState, instant);
967
- }
968
- pollStateReady(pollState);
969
- }
970
- if (duration < 10e6) {
971
- setImmediate(cb);
972
- } else {
973
- setTimeout(cb, Number(duration) / 1e6);
914
+ const duration = instant - hrtime.bigint();
915
+ if (duration <= 0) {
916
+ return pollStateReady(pollState);
917
+ }
918
+ function cb() {
919
+ if (hrtime.bigint() < instant) {
920
+ return subscribeInstant(pollState, instant);
974
921
  }
922
+ pollStateReady(pollState);
923
+ }
924
+ if (duration < 10e6) {
925
+ setImmediate(cb);
926
+ } else {
927
+ setTimeout(cb, Number(duration) / 1e6);
928
+ }
975
929
  }
976
930
 
977
931
  /**
@@ -979,14 +933,14 @@ function subscribeInstant(pollState, instant) {
979
933
  * @param {string} polledResourceDebugName
980
934
  */
981
935
  export function verifyPollsDroppedForDrop(pollState, polledResourceDebugName) {
982
- for (const pollId of pollState.polls) {
983
- const poll = polls.get(pollId);
984
- if (poll) {
985
- throw new Error(
986
- `wasi-io trap: Cannot drop ${polledResourceDebugName} as it has a child poll resource which has not yet been dropped`
987
- );
988
- }
936
+ for (const pollId of pollState.polls) {
937
+ const poll = polls.get(pollId);
938
+ if (poll) {
939
+ throw new Error(
940
+ `wasi-io trap: Cannot drop ${polledResourceDebugName} as it has a child poll resource which has not yet been dropped`,
941
+ );
989
942
  }
943
+ }
990
944
  }
991
945
 
992
946
  /**
@@ -994,41 +948,39 @@ export function verifyPollsDroppedForDrop(pollState, polledResourceDebugName) {
994
948
  * @param {bool} finished
995
949
  */
996
950
  export function pollStateReady(pollState) {
997
- if (pollState.ready && pollState.listener) {
998
- uncaughtException = new Error(
999
- 'wasi-io trap: poll already ready with listener attached'
1000
- );
1001
- }
1002
- pollState.ready = true;
1003
- if (pollState.listener) {
1004
- pollState.listener();
1005
- pollState.listener = null;
1006
- }
951
+ if (pollState.ready && pollState.listener) {
952
+ uncaughtException = new Error("wasi-io trap: poll already ready with listener attached");
953
+ }
954
+ pollState.ready = true;
955
+ if (pollState.listener) {
956
+ pollState.listener();
957
+ pollState.listener = null;
958
+ }
1007
959
  }
1008
960
 
1009
961
  /**
1010
962
  * @param {PollState} pollState
1011
963
  */
1012
964
  function pollStateCheck(pollState) {
1013
- if (pollState.ready && pollState.parentStream) {
1014
- // stream ONLY applies to readable streams here
1015
- const stream = pollState.parentStream;
1016
- const res = stream.read(0);
1017
- if (res !== null) {
1018
- throw new Error('wasi-io trap: got data for a null read');
1019
- }
1020
- if (
1021
- pollState.ready &&
1022
- stream.readableLength === 0 &&
1023
- !stream.readableEnded &&
1024
- !stream.errored
1025
- ) {
1026
- pollState.ready = false;
1027
- stream.once('readable', () => {
1028
- pollStateReady(pollState);
1029
- });
1030
- }
965
+ if (pollState.ready && pollState.parentStream) {
966
+ // stream ONLY applies to readable streams here
967
+ const stream = pollState.parentStream;
968
+ const res = stream.read(0);
969
+ if (res !== null) {
970
+ throw new Error("wasi-io trap: got data for a null read");
971
+ }
972
+ if (
973
+ pollState.ready &&
974
+ stream.readableLength === 0 &&
975
+ !stream.readableEnded &&
976
+ !stream.errored
977
+ ) {
978
+ pollState.ready = false;
979
+ stream.once("readable", () => {
980
+ pollStateReady(pollState);
981
+ });
1031
982
  }
983
+ }
1032
984
  }
1033
985
 
1034
986
  /**
@@ -1038,31 +990,31 @@ function pollStateCheck(pollState) {
1038
990
  * @returns {number}
1039
991
  */
1040
992
  export function createFuture(promise, pollState) {
1041
- const futureId = ++futureCnt;
1042
- if (pollState) {
1043
- pollState.ready = false;
1044
- } else {
1045
- pollState = {
1046
- ready: false,
1047
- listener: null,
1048
- polls: [],
1049
- parent: null,
1050
- };
1051
- }
1052
- const future = { tag: 'ok', val: null };
1053
- futures.set(futureId, { future, pollState });
1054
- promise.then(
1055
- (value) => {
1056
- pollStateReady(pollState);
1057
- future.val = value;
1058
- },
1059
- (value) => {
1060
- pollStateReady(pollState);
1061
- future.tag = 'err';
1062
- future.val = value;
1063
- }
1064
- );
1065
- return futureId;
993
+ const futureId = ++futureCnt;
994
+ if (pollState) {
995
+ pollState.ready = false;
996
+ } else {
997
+ pollState = {
998
+ ready: false,
999
+ listener: null,
1000
+ polls: [],
1001
+ parent: null,
1002
+ };
1003
+ }
1004
+ const future = { tag: "ok", val: null };
1005
+ futures.set(futureId, { future, pollState });
1006
+ promise.then(
1007
+ (value) => {
1008
+ pollStateReady(pollState);
1009
+ future.val = value;
1010
+ },
1011
+ (value) => {
1012
+ pollStateReady(pollState);
1013
+ future.tag = "err";
1014
+ future.val = value;
1015
+ },
1016
+ );
1017
+ return futureId;
1066
1018
  }
1067
1019
 
1068
1020
  /**
@@ -1071,29 +1023,29 @@ export function createFuture(promise, pollState) {
1071
1023
  * @throws {undefined}
1072
1024
  */
1073
1025
  export function futureTakeValue(id) {
1074
- const future = futures.get(id);
1075
- // Not ready = return undefined
1076
- if (!future.pollState.ready) {
1077
- return undefined;
1078
- }
1079
- // Ready but already taken = return { tag: 'err', val: undefined }
1080
- if (!future.future) {
1081
- return { tag: 'err', val: undefined };
1082
- }
1083
- const out = { tag: 'ok', val: future.future };
1084
- future.future = null;
1085
- return out;
1026
+ const future = futures.get(id);
1027
+ // Not ready = return undefined
1028
+ if (!future.pollState.ready) {
1029
+ return undefined;
1030
+ }
1031
+ // Ready but already taken = return { tag: 'err', val: undefined }
1032
+ if (!future.future) {
1033
+ return { tag: "err", val: undefined };
1034
+ }
1035
+ const out = { tag: "ok", val: future.future };
1036
+ future.future = null;
1037
+ return out;
1086
1038
  }
1087
1039
 
1088
1040
  export function futureDispose(id, ownsState) {
1089
- const { pollState } = futures.get(id);
1090
- if (ownsState) {
1091
- verifyPollsDroppedForDrop(pollState, 'future');
1092
- }
1093
- return void futures.delete(id);
1041
+ const { pollState } = futures.get(id);
1042
+ if (ownsState) {
1043
+ verifyPollsDroppedForDrop(pollState, "future");
1044
+ }
1045
+ return void futures.delete(id);
1094
1046
  }
1095
1047
 
1096
1048
  let uncaughtException;
1097
- process.on('uncaughtException', (err) => (uncaughtException = err));
1049
+ process.on("uncaughtException", (err) => (uncaughtException = err));
1098
1050
 
1099
1051
  const debug = runAsWorker(handle);