@bytecodealliance/preview3-shim 0.3.0 → 0.3.2

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.
@@ -17,7 +17,7 @@ export declare const stdin: {
17
17
  *
18
18
  * @returns {[StreamReader, FutureReader]} A tuple of [stream, future].
19
19
  */
20
- readViaStream(): (StreamReader | import("./future.js").FutureReader)[];
20
+ readViaStream(): (import("./future.js").FutureReader | StreamReader)[];
21
21
  };
22
22
  export declare const stdout: {
23
23
  /**
@@ -13,6 +13,8 @@ export declare const systemClock: {
13
13
  getResolution(): bigint;
14
14
  };
15
15
  export declare const monotonicClock: {
16
+ now(): import("@bytecodealliance/preview2-shim/interfaces/wasi-clocks-monotonic-clock").Instant;
17
+ resolution(): import("@bytecodealliance/preview2-shim/interfaces/wasi-clocks-monotonic-clock").Duration;
16
18
  /**
17
19
  * Query the resolution of the clock.
18
20
  *
@@ -50,6 +52,4 @@ export declare const monotonicClock: {
50
52
  * @throws {TypeError} If durationNs is not a bigint
51
53
  */
52
54
  waitFor(durationNs: any): Promise<void>;
53
- now(): import("@bytecodealliance/preview2-shim/interfaces/wasi-clocks-monotonic-clock").Instant;
54
- resolution(): import("@bytecodealliance/preview2-shim/interfaces/wasi-clocks-monotonic-clock").Duration;
55
55
  };
@@ -18,7 +18,7 @@ declare class Descriptor {
18
18
  * A tuple: a readable byte stream and a future that resolves to an error code.
19
19
  * @throws {FSError} `payload.tag` contains mapped WASI error code.
20
20
  */
21
- readViaStream(offset: any): (StreamReader | FutureReader)[];
21
+ readViaStream(offset: any): (FutureReader | StreamReader)[];
22
22
  /**
23
23
  * Write to a file via a byte stream.
24
24
  * WIT:
@@ -141,7 +141,7 @@ declare class Descriptor {
141
141
  * @returns {{stream: StreamReader, future: FutureReader}}
142
142
  * @throws {FSError} `payload.tag` contains mapped WASI error code.
143
143
  */
144
- readDirectory(): (StreamReader | FutureReader)[];
144
+ readDirectory(): (FutureReader | StreamReader)[];
145
145
  /**
146
146
  * Synchronize data & metadata to disk.
147
147
  * WIT:
@@ -64,10 +64,10 @@ export declare const makeIpAddress: (family: any, host: any, port: any) => {
64
64
  } | {
65
65
  tag: string;
66
66
  val: {
67
- flowInfo: number;
68
- scopeId: number;
69
67
  address: any;
70
68
  port: any;
69
+ flowInfo: number;
70
+ scopeId: number;
71
71
  };
72
72
  };
73
73
  /**
@@ -108,7 +108,7 @@ export declare class TcpSocket {
108
108
  * @throws {SocketError} for other errors, payload.tag maps the system error
109
109
  * @returns {{ stream: StreamReader, future: FutureReader }}
110
110
  */
111
- receive(): (StreamReader | FutureReader)[];
111
+ receive(): (FutureReader | StreamReader)[];
112
112
  /**
113
113
  * Gets the bound local address
114
114
  * WIT:
@@ -686,7 +686,7 @@ export class TcpSocket {
686
686
  * Disposes the socket
687
687
  */
688
688
  [Symbol.dispose]() {
689
- if (this.#socketId) {
689
+ if (this.#socketId !== null) {
690
690
  worker().runSync({
691
691
  op: "tcp-dispose",
692
692
  socketId: this.#socketId,
@@ -462,7 +462,7 @@ export class UdpSocket {
462
462
  * Releases native resources and marks the socket as closed.
463
463
  */
464
464
  [Symbol.dispose]() {
465
- if (this.#socketId) {
465
+ if (this.#socketId !== null) {
466
466
  worker().runSync({
467
467
  op: "udp-dispose",
468
468
  socketId: this.#socketId,
@@ -64,7 +64,9 @@ function notify(condvar) {
64
64
  Router().op("stdout", handleOp).op("stderr", handleOp);
65
65
  async function handleOp(msg) {
66
66
  const { op, stream } = msg;
67
- await pipeline(Readable.from(byteChunks(stream), { objectMode: false }), op === "stdout" ? process.stdout : process.stderr, { end: false });
67
+ const readable = Readable.from(byteChunks(stream), { objectMode: false });
68
+ const writable = op === "stdout" ? process.stdout : process.stderr;
69
+ await pipeline(readable, writable, { end: false });
68
70
  return { ok: true };
69
71
  }
70
72
  async function* byteChunks(stream) {
@@ -156,7 +156,7 @@ function wasiTypeFromDirent(obj) {
156
156
  const readAsync = promisify(fs.read);
157
157
  const writeAsync = promisify(fs.write);
158
158
  const { opendir } = fs.promises;
159
- const CHUNK_BYTES = 64 * 1024;
159
+ const CHUNK_BYTES = 65536;
160
160
  const BUFFER = Buffer.alloc(CHUNK_BYTES);
161
161
  const MAX_SAFE_FILE_POSITION = BigInt(Number.MAX_SAFE_INTEGER);
162
162
  /** Auto‐dispatch all ops */
@@ -173,7 +173,8 @@ async function handleNext({ serverId }) {
173
173
  const { req } = srv.inflight.get(requestId);
174
174
  const { port1: tx, port2: trailers } = new MessageChannel();
175
175
  const { readable: body, writable } = new TransformStream();
176
- pipeline(req, Writable.fromWeb(writable)).then(() => tx.postMessage({ val: toEntries(req.trailersDistinct || req.trailers || {}) })).catch((err) => tx.postMessage({ err })).finally(() => tx.close());
176
+ const stream = Writable.fromWeb(writable);
177
+ pipeline(req, stream).then(() => tx.postMessage({ val: toEntries(req.trailersDistinct || req.trailers || {}) })).catch((err) => tx.postMessage({ err })).finally(() => tx.close());
177
178
  const headers = toEntries(req.headersDistinct);
178
179
  const { method, url } = req;
179
180
  return {
@@ -308,14 +308,11 @@ async function handleTcpConnect({ socketId, remoteAddress }) {
308
308
  allowHalfOpen: true
309
309
  });
310
310
  const onConnect = once(tcp, "connect");
311
- const onError = once(tcp, "error").then(([err]) => {
312
- throw err;
313
- });
314
311
  tcp.connect({
315
312
  port,
316
313
  host
317
314
  });
318
- await Promise.race([onConnect, onError]);
315
+ await onConnect;
319
316
  }
320
317
  async function handleTcpListen({ socketId, stream }) {
321
318
  const writer = stream.getWriter();
@@ -326,11 +323,8 @@ async function handleTcpListen({ socketId, stream }) {
326
323
  allowHalfOpen: true
327
324
  });
328
325
  const onListening = once(server, "listening");
329
- const onError = once(server, "error").then(([err]) => {
330
- throw err;
331
- });
332
326
  server.listen(handle, backlog);
333
- await Promise.race([onListening, onError]);
327
+ await onListening;
334
328
  const addr = server.address();
335
329
  if (addr && typeof addr === "object") socket.localAddress = makeIpAddress(family, addr.address, addr.port);
336
330
  server.on("connection", (conn) => {
@@ -91,13 +91,14 @@ async function handleTcpConnect({ socketId, remoteAddress }) {
91
91
  pauseOnCreate: true,
92
92
  allowHalfOpen: true,
93
93
  }));
94
- const onConnect = once(tcp, "connect");
95
- const onError = once(tcp, "error").then(([err]) => {
96
- throw err;
97
- });
98
94
  // TODO(tandr): Add lookup
95
+ const onConnect = once(tcp, "connect");
99
96
  tcp.connect({ port, host });
100
- await Promise.race([onConnect, onError]);
97
+ // events.once rejects when the emitter produces an error while waiting and
98
+ // removes its temporary listeners after settling. A separate error promise
99
+ // would remain attached after a successful connect and could later reject
100
+ // unobserved when an established connection is reset.
101
+ await onConnect;
101
102
  }
102
103
  async function handleTcpListen({ socketId, stream }) {
103
104
  const writer = stream.getWriter();
@@ -108,11 +109,8 @@ async function handleTcpListen({ socketId, stream }) {
108
109
  allowHalfOpen: true,
109
110
  });
110
111
  const onListening = once(server, "listening");
111
- const onError = once(server, "error").then(([err]) => {
112
- throw err;
113
- });
114
112
  server.listen(handle, backlog);
115
- await Promise.race([onListening, onError]);
113
+ await onListening;
116
114
  const addr = server.address();
117
115
  if (addr && typeof addr === "object") {
118
116
  socket.localAddress = makeIpAddress(family, addr.address, addr.port);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytecodealliance/preview3-shim",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "WASI Preview3 shim for JS environments",
5
5
  "homepage": "https://github.com/bytecodealliance/jco/blob/main/packages/preview3-shim/#readme",
6
6
  "bugs": {
@@ -53,10 +53,10 @@
53
53
  "devDependencies": {
54
54
  "@types/node": "^24.12.4",
55
55
  "globals": "^17.6.0",
56
- "rolldown": "^1.2.0",
57
- "typescript": "^6.0.3",
56
+ "rolldown": "^1.2.4",
57
+ "typescript": "7.0.2",
58
58
  "vite": "^8.0.16",
59
- "vitest": "^4.0.8"
59
+ "vitest": "^4.1.10"
60
60
  },
61
61
  "scripts": {
62
62
  "build": "tsc --project tsconfig.build.json && node scripts/build-workers.mjs",