@bytecodealliance/preview2-shim 0.20.0 → 0.20.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.
@@ -9,6 +9,7 @@ export interface Stream {
9
9
  stream: NodeJS.ReadableStream | NodeJS.WritableStream;
10
10
  flushPromise: Promise<void> | null;
11
11
  pollState: any;
12
+ fileResourceId?: number;
12
13
  }
13
14
  export interface Future {
14
15
  future: {
@@ -6,7 +6,8 @@ import { clearOutgoingResponse, createHttpRequest, setOutgoingResponse, startHtt
6
6
  import { Readable } from "node:stream";
7
7
  import { read } from "node:fs";
8
8
  import { nextTick } from "node:process";
9
- import { CALL_MASK, CALL_TYPE_MASK, CLOCKS_DURATION_SUBSCRIBE, CLOCKS_INSTANT_SUBSCRIBE, FILE, FUTURE_DISPOSE, FUTURE_SUBSCRIBE, FUTURE_TAKE_VALUE, HTTP, HTTP_CREATE_REQUEST, HTTP_OUTGOING_BODY_DISPOSE, HTTP_OUTPUT_STREAM_FINISH, HTTP_SERVER_CLEAR_OUTGOING_RESPONSE, HTTP_SERVER_SET_OUTGOING_RESPONSE, HTTP_SERVER_START, HTTP_SERVER_STOP, HTTP_SERVER_GET_ADDRESS, INPUT_STREAM_BLOCKING_READ, INPUT_STREAM_BLOCKING_SKIP, INPUT_STREAM_CREATE, INPUT_STREAM_DISPOSE, INPUT_STREAM_READ, INPUT_STREAM_SKIP, INPUT_STREAM_SUBSCRIBE, OUTPUT_STREAM_BLOCKING_FLUSH, OUTPUT_STREAM_BLOCKING_SPLICE, OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH, OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH, OUTPUT_STREAM_CHECK_WRITE, OUTPUT_STREAM_CREATE, OUTPUT_STREAM_DISPOSE, OUTPUT_STREAM_FLUSH, OUTPUT_STREAM_SPLICE, OUTPUT_STREAM_SUBSCRIBE, OUTPUT_STREAM_WRITE, OUTPUT_STREAM_WRITE_ZEROES, POLL_POLLABLE_BLOCK, POLL_POLLABLE_DISPOSE, POLL_POLLABLE_READY, POLL_POLL_LIST, SOCKET_RESOLVE_ADDRESS_CREATE_REQUEST, SOCKET_RESOLVE_ADDRESS_SUBSCRIBE_REQUEST, SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST, SOCKET_RESOLVE_ADDRESS_TAKE_REQUEST, SOCKET_GET_DEFAULT_RECEIVE_BUFFER_SIZE, SOCKET_GET_DEFAULT_SEND_BUFFER_SIZE, SOCKET_TCP_ACCEPT, SOCKET_TCP_BIND_FINISH, SOCKET_TCP_BIND_START, SOCKET_TCP_CONNECT_FINISH, SOCKET_TCP_CONNECT_START, SOCKET_TCP_CREATE_HANDLE, SOCKET_TCP_DISPOSE, SOCKET_TCP_GET_LOCAL_ADDRESS, SOCKET_TCP_GET_REMOTE_ADDRESS, SOCKET_TCP_IS_LISTENING, SOCKET_TCP_LISTEN_FINISH, SOCKET_TCP_LISTEN_START, SOCKET_TCP_SET_KEEP_ALIVE, SOCKET_TCP_SET_LISTEN_BACKLOG_SIZE, SOCKET_TCP_SHUTDOWN, SOCKET_TCP_SUBSCRIBE, SOCKET_UDP_BIND_FINISH, SOCKET_UDP_BIND_START, SOCKET_UDP_CREATE_HANDLE, SOCKET_UDP_DISPOSE, SOCKET_UDP_GET_LOCAL_ADDRESS, SOCKET_UDP_GET_RECEIVE_BUFFER_SIZE, SOCKET_UDP_GET_REMOTE_ADDRESS, SOCKET_UDP_GET_SEND_BUFFER_SIZE, SOCKET_UDP_GET_UNICAST_HOP_LIMIT, SOCKET_UDP_SET_RECEIVE_BUFFER_SIZE, SOCKET_UDP_SET_SEND_BUFFER_SIZE, SOCKET_UDP_SET_UNICAST_HOP_LIMIT, SOCKET_UDP_STREAM, SOCKET_UDP_SUBSCRIBE, SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE, SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND, SOCKET_OUTGOING_DATAGRAM_STREAM_SEND, SOCKET_DATAGRAM_STREAM_SUBSCRIBE, SOCKET_DATAGRAM_STREAM_DISPOSE, STDERR, STDIN, STDOUT, reverseMap, } from "./calls.js";
9
+ import { CALL_MASK, CALL_TYPE_MASK, CLOCKS_DURATION_SUBSCRIBE, CLOCKS_INSTANT_SUBSCRIBE, FILE, FILESYSTEM_DESCRIPTOR_CLOSE, FILESYSTEM_DESCRIPTOR_GET_TYPE, FILESYSTEM_DESCRIPTOR_METADATA_HASH, FILESYSTEM_DESCRIPTOR_OPEN, FILESYSTEM_DESCRIPTOR_READ, FILESYSTEM_DESCRIPTOR_SET_SIZE, FILESYSTEM_DESCRIPTOR_SET_TIMES, FILESYSTEM_DESCRIPTOR_STAT, FILESYSTEM_DESCRIPTOR_SYNC, FILESYSTEM_DESCRIPTOR_SYNC_DATA, FILESYSTEM_DESCRIPTOR_WRITE, FUTURE_DISPOSE, FUTURE_SUBSCRIBE, FUTURE_TAKE_VALUE, HTTP, HTTP_CREATE_REQUEST, HTTP_OUTGOING_BODY_DISPOSE, HTTP_OUTPUT_STREAM_FINISH, HTTP_SERVER_CLEAR_OUTGOING_RESPONSE, HTTP_SERVER_SET_OUTGOING_RESPONSE, HTTP_SERVER_START, HTTP_SERVER_STOP, HTTP_SERVER_GET_ADDRESS, INPUT_STREAM_BLOCKING_READ, INPUT_STREAM_BLOCKING_SKIP, INPUT_STREAM_CREATE, INPUT_STREAM_DISPOSE, INPUT_STREAM_READ, INPUT_STREAM_SKIP, INPUT_STREAM_SUBSCRIBE, OUTPUT_STREAM_BLOCKING_FLUSH, OUTPUT_STREAM_BLOCKING_SPLICE, OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH, OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH, OUTPUT_STREAM_CHECK_WRITE, OUTPUT_STREAM_CREATE, OUTPUT_STREAM_DISPOSE, OUTPUT_STREAM_FLUSH, OUTPUT_STREAM_SPLICE, OUTPUT_STREAM_SUBSCRIBE, OUTPUT_STREAM_WRITE, OUTPUT_STREAM_WRITE_ZEROES, POLL_POLLABLE_BLOCK, POLL_POLLABLE_DISPOSE, POLL_POLLABLE_READY, POLL_POLL_LIST, SOCKET_RESOLVE_ADDRESS_CREATE_REQUEST, SOCKET_RESOLVE_ADDRESS_SUBSCRIBE_REQUEST, SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST, SOCKET_RESOLVE_ADDRESS_TAKE_REQUEST, SOCKET_GET_DEFAULT_RECEIVE_BUFFER_SIZE, SOCKET_GET_DEFAULT_SEND_BUFFER_SIZE, SOCKET_TCP_ACCEPT, SOCKET_TCP_BIND_FINISH, SOCKET_TCP_BIND_START, SOCKET_TCP_CONNECT_FINISH, SOCKET_TCP_CONNECT_START, SOCKET_TCP_CREATE_HANDLE, SOCKET_TCP_DISPOSE, SOCKET_TCP_GET_LOCAL_ADDRESS, SOCKET_TCP_GET_REMOTE_ADDRESS, SOCKET_TCP_IS_LISTENING, SOCKET_TCP_LISTEN_FINISH, SOCKET_TCP_LISTEN_START, SOCKET_TCP_SET_KEEP_ALIVE, SOCKET_TCP_SET_LISTEN_BACKLOG_SIZE, SOCKET_TCP_SHUTDOWN, SOCKET_TCP_SUBSCRIBE, SOCKET_UDP_BIND_FINISH, SOCKET_UDP_BIND_START, SOCKET_UDP_CREATE_HANDLE, SOCKET_UDP_DISPOSE, SOCKET_UDP_GET_LOCAL_ADDRESS, SOCKET_UDP_GET_RECEIVE_BUFFER_SIZE, SOCKET_UDP_GET_REMOTE_ADDRESS, SOCKET_UDP_GET_SEND_BUFFER_SIZE, SOCKET_UDP_GET_UNICAST_HOP_LIMIT, SOCKET_UDP_SET_RECEIVE_BUFFER_SIZE, SOCKET_UDP_SET_SEND_BUFFER_SIZE, SOCKET_UDP_SET_UNICAST_HOP_LIMIT, SOCKET_UDP_STREAM, SOCKET_UDP_SUBSCRIBE, SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE, SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND, SOCKET_OUTGOING_DATAGRAM_STREAM_SEND, SOCKET_DATAGRAM_STREAM_SUBSCRIBE, SOCKET_DATAGRAM_STREAM_DISPOSE, STDERR, STDIN, STDOUT, reverseMap, } from "./calls.js";
10
+ import { fileResourceFd, getFileResourceType, metadataHashFileResource, openFileResource, readFileResource, releaseFileResource, retainFileResource, setFileResourceSize, setFileResourceTimes, statFileResource, syncFileResource, syncFileResourceData, writeFileResource, } from "./worker-filesystem.js";
10
11
  import { SOCKET_STATE_BIND, SOCKET_STATE_BOUND, SOCKET_STATE_CONNECT, SOCKET_STATE_CONNECTION, SOCKET_STATE_LISTEN, SOCKET_STATE_LISTENER, socketResolveAddress, getDefaultSendBufferSize, getDefaultReceiveBufferSize, } from "./worker-sockets.js";
11
12
  import { createTcpSocket, socketTcpAccept, socketTcpBindStart, socketTcpConnectStart, socketTcpDispose, socketTcpFinish, socketTcpGetLocalAddress, socketTcpGetRemoteAddress, socketTcpListenStart, socketTcpSetKeepAlive, socketTcpSetListenBacklogSize, socketTcpShutdown, tcpSockets, } from "./worker-socket-tcp.js";
12
13
  import { createUdpSocket, datagramStreams, socketDatagramStreamDispose, socketIncomingDatagramStreamReceive, socketOutgoingDatagramStreamCheckSend, socketOutgoingDatagramStreamSend, socketUdpBindFinish, socketUdpBindStart, socketUdpDispose, socketUdpGetLocalAddress, socketUdpGetReceiveBufferSize, socketUdpGetRemoteAddress, socketUdpGetSendBufferSize, socketUdpGetUnicastHopLimit, socketUdpSetReceiveBufferSize, socketUdpSetSendBufferSize, socketUdpSetUnicastHopLimit, socketUdpStream, udpSockets, } from "./worker-socket-udp.js";
@@ -365,18 +366,44 @@ function handle(call, id, payload) {
365
366
  return createPoll(pollState);
366
367
  }
367
368
  // Filesystem
369
+ case FILESYSTEM_DESCRIPTOR_OPEN:
370
+ return openFileResource(payload.path, payload.flags);
371
+ case FILESYSTEM_DESCRIPTOR_CLOSE:
372
+ return releaseFileResource(id);
373
+ case FILESYSTEM_DESCRIPTOR_SYNC_DATA:
374
+ return syncFileResourceData(id);
375
+ case FILESYSTEM_DESCRIPTOR_GET_TYPE:
376
+ return getFileResourceType(id);
377
+ case FILESYSTEM_DESCRIPTOR_SET_SIZE:
378
+ return setFileResourceSize(id, payload);
379
+ case FILESYSTEM_DESCRIPTOR_SET_TIMES:
380
+ return setFileResourceTimes(id, payload.atime, payload.mtime);
381
+ case FILESYSTEM_DESCRIPTOR_READ:
382
+ return readFileResource(id, payload.length, payload.offset);
383
+ case FILESYSTEM_DESCRIPTOR_WRITE:
384
+ return writeFileResource(id, payload.buffer, payload.offset);
385
+ case FILESYSTEM_DESCRIPTOR_SYNC:
386
+ return syncFileResource(id);
387
+ case FILESYSTEM_DESCRIPTOR_STAT:
388
+ return statFileResource(id);
389
+ case FILESYSTEM_DESCRIPTOR_METADATA_HASH:
390
+ return metadataHashFileResource(id);
368
391
  case INPUT_STREAM_CREATE | FILE: {
369
- const { fd, offset } = payload;
392
+ const { descriptorId, offset } = payload;
393
+ const fd = fileResourceFd(descriptorId);
370
394
  const stream = createReadStream(null, {
371
395
  fd,
372
396
  autoClose: false,
373
397
  highWaterMark: 64 * 1024,
374
398
  start: Number(offset),
375
399
  });
376
- return createReadableStream(stream);
400
+ const streamId = createReadableStream(stream);
401
+ streams.get(streamId).fileResourceId = retainFileResource(descriptorId);
402
+ return streamId;
377
403
  }
378
404
  case OUTPUT_STREAM_CREATE | FILE: {
379
- const { fd, offset } = payload;
405
+ const { descriptorId, offset } = payload;
406
+ const fd = fileResourceFd(descriptorId);
380
407
  const stream = createWriteStream(null, {
381
408
  fd,
382
409
  autoClose: false,
@@ -384,7 +411,9 @@ function handle(call, id, payload) {
384
411
  highWaterMark: 64 * 1024,
385
412
  start: Number(offset),
386
413
  });
387
- return createWritableStream(stream);
414
+ const streamId = createWritableStream(stream);
415
+ streams.get(streamId).fileResourceId = retainFileResource(descriptorId);
416
+ return streamId;
388
417
  }
389
418
  }
390
419
  // Generic call implementations (streams + polls)
@@ -421,6 +450,9 @@ function handle(call, id, payload) {
421
450
  const stream = streams.get(id);
422
451
  verifyPollsDroppedForDrop(stream.pollState, "input stream");
423
452
  streams.delete(id);
453
+ if (stream.fileResourceId) {
454
+ return releaseFileResource(stream.fileResourceId);
455
+ }
424
456
  return;
425
457
  }
426
458
  case OUTPUT_STREAM_CHECK_WRITE: {
@@ -599,9 +631,14 @@ function handle(call, id, payload) {
599
631
  case OUTPUT_STREAM_DISPOSE: {
600
632
  const stream = streams.get(id);
601
633
  verifyPollsDroppedForDrop(stream.pollState, "output stream");
602
- stream.stream.end();
603
634
  streams.delete(id);
604
- return;
635
+ if (stream.fileResourceId) {
636
+ return new Promise((resolve) => stream.stream.end(resolve)).then(() => releaseFileResource(stream.fileResourceId));
637
+ }
638
+ else {
639
+ stream.stream.end();
640
+ return;
641
+ }
605
642
  }
606
643
  case POLL_POLLABLE_READY:
607
644
  return polls.get(id).ready;
@@ -1,5 +1,5 @@
1
1
  import { types as TypesNamespace, preopens as PreopensNamespace } from "../../types/filesystem.js";
2
- import type { Descriptor as IDescriptor, DirectoryEntryStream as IDirectoryEntryStream } from "../../types/interfaces/wasi-filesystem-types.js";
2
+ import type { Descriptor as IDescriptor, DescriptorType, DirectoryEntryStream as IDirectoryEntryStream } from "../../types/interfaces/wasi-filesystem-types.js";
3
3
  declare const symbolDispose: symbol;
4
4
  /**
5
5
  * @implements {DescriptorProps}
@@ -9,14 +9,14 @@ declare class Descriptor implements IDescriptor {
9
9
  [symbolDispose]: () => void;
10
10
  private _id;
11
11
  static _createPreopen(hostPreopen: any): Descriptor;
12
- static _create(fd: any, mode: any, fullPath: any): Descriptor;
12
+ static _create(fileResourceId: any, mode: any, fullPath: any): Descriptor;
13
13
  readViaStream(offset: any): any;
14
14
  writeViaStream(offset: any): any;
15
15
  appendViaStream(): any;
16
16
  advise(_offset: any, _length: any, _advice: any): void;
17
17
  syncData(): void;
18
18
  getFlags(): any;
19
- getType(): TypesNamespace.DescriptorType;
19
+ getType(): any;
20
20
  setSize(size: any): void;
21
21
  setTimes(dataAccessTimestamp: any, dataModificationTimestamp: any): void;
22
22
  read(length: any, offset: any): [Uint8Array, boolean];
@@ -25,7 +25,7 @@ declare class Descriptor implements IDescriptor {
25
25
  sync(): void;
26
26
  createDirectoryAt(path: any): void;
27
27
  stat(): {
28
- type: TypesNamespace.DescriptorType;
28
+ type: any;
29
29
  linkCount: any;
30
30
  size: any;
31
31
  dataAccessTimestamp: {
@@ -42,7 +42,7 @@ declare class Descriptor implements IDescriptor {
42
42
  };
43
43
  };
44
44
  statAt(pathFlags: any, path: any): {
45
- type: TypesNamespace.DescriptorType;
45
+ type: DescriptorType;
46
46
  linkCount: any;
47
47
  size: any;
48
48
  dataAccessTimestamp: {
@@ -67,10 +67,7 @@ declare class Descriptor implements IDescriptor {
67
67
  symlinkAt(target: any, path: any): void;
68
68
  unlinkFileAt(path: any): void;
69
69
  isSameObject(other: any): boolean;
70
- metadataHash(): {
71
- upper: bigint;
72
- lower: bigint;
73
- };
70
+ metadataHash(): any;
74
71
  metadataHashAt(pathFlags: any, path: any): {
75
72
  upper: bigint;
76
73
  lower: bigint;
@@ -1,6 +1,6 @@
1
1
  import { earlyDispose, inputStreamCreate, ioCall, outputStreamCreate, registerDispose, } from "../io/worker-io.js";
2
- import { FILE, INPUT_STREAM_CREATE, OUTPUT_STREAM_CREATE } from "../io/calls.js";
3
- import { closeSync, constants, fdatasyncSync, fstatSync, fsyncSync, ftruncateSync, futimesSync, linkSync, lstatSync, lutimesSync, mkdirSync, opendirSync, openSync, readlinkSync, readSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync, writeSync, } from "node:fs";
2
+ import { FILE, FILESYSTEM_DESCRIPTOR_CLOSE, FILESYSTEM_DESCRIPTOR_GET_TYPE, FILESYSTEM_DESCRIPTOR_METADATA_HASH, FILESYSTEM_DESCRIPTOR_OPEN, FILESYSTEM_DESCRIPTOR_READ, FILESYSTEM_DESCRIPTOR_SET_SIZE, FILESYSTEM_DESCRIPTOR_SET_TIMES, FILESYSTEM_DESCRIPTOR_STAT, FILESYSTEM_DESCRIPTOR_SYNC, FILESYSTEM_DESCRIPTOR_SYNC_DATA, FILESYSTEM_DESCRIPTOR_WRITE, INPUT_STREAM_CREATE, OUTPUT_STREAM_CREATE, } from "../io/calls.js";
3
+ import { constants, linkSync, lstatSync, lutimesSync, mkdirSync, opendirSync, readlinkSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync, } from "node:fs";
4
4
  import { platform } from "node:process";
5
5
  const symbolDispose = Symbol.dispose || Symbol.for("dispose");
6
6
  const isWindows = platform === "win32";
@@ -35,6 +35,9 @@ function lookupType(obj) {
35
35
  }
36
36
  return "unknown";
37
37
  }
38
+ function closeFileResource(id) {
39
+ ioCall(FILESYSTEM_DESCRIPTOR_CLOSE, id);
40
+ }
38
41
  // Note: This should implement per-segment semantics of openAt, but we cannot
39
42
  // currently due to the lack of support for openat() in Node.js.
40
43
  // Tracking issue: https://github.com/libuv/libuv/issues/4167
@@ -43,7 +46,7 @@ function lookupType(obj) {
43
46
  */
44
47
  class Descriptor {
45
48
  #hostPreopen;
46
- #fd;
49
+ #fileResourceId;
47
50
  #finalizer;
48
51
  #mode;
49
52
  #fullPath;
@@ -62,10 +65,10 @@ class Descriptor {
62
65
  }
63
66
  return descriptor;
64
67
  }
65
- static _create(fd, mode, fullPath) {
68
+ static _create(fileResourceId, mode, fullPath) {
66
69
  const descriptor = new Descriptor();
67
- descriptor.#fd = fd;
68
- descriptor.#finalizer = registerDispose(descriptor, null, fd, closeSync);
70
+ descriptor.#fileResourceId = fileResourceId;
71
+ descriptor.#finalizer = registerDispose(descriptor, null, fileResourceId, closeFileResource);
69
72
  descriptor.#mode = mode;
70
73
  descriptor.#fullPath = fullPath;
71
74
  return descriptor;
@@ -81,7 +84,7 @@ class Descriptor {
81
84
  throw "is-directory";
82
85
  }
83
86
  return inputStreamCreate(FILE, ioCall(INPUT_STREAM_CREATE | FILE, null, {
84
- fd: this.#fd,
87
+ descriptorId: this.#fileResourceId,
85
88
  offset,
86
89
  }));
87
90
  }
@@ -89,7 +92,10 @@ class Descriptor {
89
92
  if (this.#hostPreopen) {
90
93
  throw "is-directory";
91
94
  }
92
- return outputStreamCreate(FILE, ioCall(OUTPUT_STREAM_CREATE | FILE, null, { fd: this.#fd, offset }));
95
+ return outputStreamCreate(FILE, ioCall(OUTPUT_STREAM_CREATE | FILE, null, {
96
+ descriptorId: this.#fileResourceId,
97
+ offset,
98
+ }));
93
99
  }
94
100
  appendViaStream() {
95
101
  return this.writeViaStream(this.stat().size);
@@ -104,7 +110,7 @@ class Descriptor {
104
110
  throw "invalid";
105
111
  }
106
112
  try {
107
- fdatasyncSync(this.#fd);
113
+ ioCall(FILESYSTEM_DESCRIPTOR_SYNC_DATA, this.#fileResourceId);
108
114
  }
109
115
  catch (e) {
110
116
  if (e.code === "EPERM") {
@@ -120,15 +126,14 @@ class Descriptor {
120
126
  if (this.#hostPreopen) {
121
127
  return "directory";
122
128
  }
123
- const stats = fstatSync(this.#fd);
124
- return lookupType(stats);
129
+ return ioCall(FILESYSTEM_DESCRIPTOR_GET_TYPE, this.#fileResourceId);
125
130
  }
126
131
  setSize(size) {
127
132
  if (this.#hostPreopen) {
128
133
  throw "is-directory";
129
134
  }
130
135
  try {
131
- ftruncateSync(this.#fd, Number(size));
136
+ ioCall(FILESYSTEM_DESCRIPTOR_SET_SIZE, this.#fileResourceId, Number(size));
132
137
  }
133
138
  catch (e) {
134
139
  if (isWindows && e.code === "EPERM") {
@@ -149,7 +154,7 @@ class Descriptor {
149
154
  const atime = this.#getNewTimestamp(dataAccessTimestamp, dataAccessTimestamp.tag === "no-change" && stats.dataAccessTimestamp);
150
155
  const mtime = this.#getNewTimestamp(dataModificationTimestamp, dataModificationTimestamp.tag === "no-change" && stats.dataModificationTimestamp);
151
156
  try {
152
- futimesSync(this.#fd, atime, mtime);
157
+ ioCall(FILESYSTEM_DESCRIPTOR_SET_TIMES, this.#fileResourceId, { atime, mtime });
153
158
  }
154
159
  catch (e) {
155
160
  throw convertFsError(e);
@@ -169,16 +174,20 @@ class Descriptor {
169
174
  if (!this.#fullPath) {
170
175
  throw "bad-descriptor";
171
176
  }
172
- const buf = new Uint8Array(Number(length));
173
- const bytesRead = readSync(this.#fd, buf, 0, Number(length), Number(offset));
174
- const out = new Uint8Array(buf.buffer, 0, bytesRead);
175
- return [out, bytesRead === 0];
177
+ const { bytes, eof } = ioCall(FILESYSTEM_DESCRIPTOR_READ, this.#fileResourceId, {
178
+ length: Number(length),
179
+ offset: Number(offset),
180
+ });
181
+ return [bytes, eof];
176
182
  }
177
183
  write(buffer, offset) {
178
184
  if (!this.#fullPath) {
179
185
  throw "bad-descriptor";
180
186
  }
181
- return BigInt(writeSync(this.#fd, buffer, 0, buffer.byteLength, Number(offset)));
187
+ return BigInt(ioCall(FILESYSTEM_DESCRIPTOR_WRITE, this.#fileResourceId, {
188
+ buffer,
189
+ offset: Number(offset),
190
+ }));
182
191
  }
183
192
  readDirectory() {
184
193
  if (!this.#fullPath) {
@@ -197,7 +206,7 @@ class Descriptor {
197
206
  throw "invalid";
198
207
  }
199
208
  try {
200
- fsyncSync(this.#fd);
209
+ ioCall(FILESYSTEM_DESCRIPTOR_SYNC, this.#fileResourceId);
201
210
  }
202
211
  catch (e) {
203
212
  if (e.code === "EPERM") {
@@ -221,12 +230,12 @@ class Descriptor {
221
230
  }
222
231
  let stats;
223
232
  try {
224
- stats = fstatSync(this.#fd, { bigint: true });
233
+ stats = ioCall(FILESYSTEM_DESCRIPTOR_STAT, this.#fileResourceId);
225
234
  }
226
235
  catch (e) {
227
236
  throw convertFsError(e);
228
237
  }
229
- const type = lookupType(stats);
238
+ const type = stats.type;
230
239
  return {
231
240
  type,
232
241
  linkCount: stats.nlink,
@@ -361,9 +370,12 @@ class Descriptor {
361
370
  }
362
371
  }
363
372
  try {
364
- const fd = openSync(fullPath.endsWith("/") ? fullPath.slice(0, -1) : fullPath, fsOpenFlags);
365
- const descriptor = descriptorCreate(fd, descriptorFlags, fullPath);
366
- if (fullPath.endsWith("/") && descriptor.getType() !== "directory") {
373
+ const { id, type } = ioCall(FILESYSTEM_DESCRIPTOR_OPEN, null, {
374
+ path: fullPath.endsWith("/") ? fullPath.slice(0, -1) : fullPath,
375
+ flags: fsOpenFlags,
376
+ });
377
+ const descriptor = descriptorCreate(id, descriptorFlags, fullPath);
378
+ if (fullPath.endsWith("/") && type !== "directory") {
367
379
  descriptor[symbolDispose]();
368
380
  throw "not-directory";
369
381
  }
@@ -475,8 +487,7 @@ class Descriptor {
475
487
  return { upper: 0n, lower: BigInt(this._id) };
476
488
  }
477
489
  try {
478
- const stats = fstatSync(this.#fd, { bigint: true });
479
- return { upper: stats.mtimeNs, lower: stats.ino };
490
+ return ioCall(FILESYSTEM_DESCRIPTOR_METADATA_HASH, this.#fileResourceId);
480
491
  }
481
492
  catch (e) {
482
493
  throw convertFsError(e);
@@ -1,2 +1,2 @@
1
- export declare function createSyncFn(workerPath: any, debug: any, callbackHandler: any): (...args: any[]) => any;
1
+ export declare function createSyncFn(createWorker: any, debug: any, callbackHandler: any): (...args: any[]) => any;
2
2
  export declare function runAsWorker(fn: any): any;
@@ -22,8 +22,7 @@
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
23
  SOFTWARE.
24
24
  */
25
- import path from "node:path";
26
- import { MessageChannel, Worker, receiveMessageOnPort, workerData, parentPort, } from "node:worker_threads";
25
+ import { MessageChannel, receiveMessageOnPort, workerData, parentPort } from "node:worker_threads";
27
26
  const DEFAULT_WORKER_BUFFER_SIZE = 1024;
28
27
  function extractProperties(object) {
29
28
  if (object && typeof object === "object") {
@@ -35,12 +34,9 @@ function extractProperties(object) {
35
34
  }
36
35
  }
37
36
  const CALL_TIMEOUT = undefined;
38
- export function createSyncFn(workerPath, debug, callbackHandler) {
39
- if (!path.isAbsolute(workerPath)) {
40
- throw new Error("`workerPath` must be absolute");
41
- }
37
+ export function createSyncFn(createWorker, debug, callbackHandler) {
42
38
  const { port1: mainPort, port2: workerPort } = new MessageChannel();
43
- const worker = new Worker(workerPath, {
39
+ const worker = createWorker({
44
40
  workerData: { workerPort, debug },
45
41
  transferList: [workerPort],
46
42
  execArgv: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytecodealliance/preview2-shim",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "WASI Preview2 shim for JS environments",
5
5
  "homepage": "https://github.com/bytecodealliance/jco#readme",
6
6
  "bugs": {
@@ -62,17 +62,19 @@
62
62
  "@types/node": "^24.12.4",
63
63
  "mime": "^4.0.7",
64
64
  "puppeteer": "^25.1.0",
65
- "typescript": "^6.0.3",
66
- "vitest": "^4.0.8"
65
+ "rolldown": "^1.2.4",
66
+ "typescript": "7.0.2",
67
+ "vitest": "^4.1.10"
67
68
  },
68
69
  "scripts": {
69
- "build": "tsc --project tsconfig.build.json",
70
+ "build": "tsc --project tsconfig.build.json && node scripts/build-worker.mjs",
70
71
  "build:watch": "tsc --watch",
71
72
  "types:check": "tsc --noEmit",
72
73
  "fmt": "oxfmt",
73
74
  "fmt:check": "oxfmt --check",
74
75
  "lint": "oxlint",
75
76
  "lint:fix": "oxlint --fix",
76
- "test": "vitest run -c test/vitest.ts"
77
+ "test": "vitest run -c test/vitest.ts",
78
+ "test:deno": "deno test --no-check -A test/deno/*.mjs"
77
79
  }
78
80
  }