@bytecodealliance/preview2-shim 0.18.1 → 0.19.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.
Files changed (81) hide show
  1. package/dist/browser/cli.d.ts +16 -0
  2. package/dist/browser/cli.js +109 -0
  3. package/dist/browser/clocks.d.ts +3 -0
  4. package/dist/browser/clocks.js +36 -0
  5. package/dist/browser/config.d.ts +2 -0
  6. package/{lib → dist}/browser/config.js +2 -4
  7. package/dist/browser/environment.d.ts +5 -0
  8. package/dist/browser/environment.js +24 -0
  9. package/dist/browser/filesystem.d.ts +132 -0
  10. package/dist/browser/filesystem.js +464 -0
  11. package/dist/browser/http.d.ts +4 -0
  12. package/dist/browser/http.js +643 -0
  13. package/dist/browser/index.d.ts +7 -0
  14. package/dist/browser/index.js +7 -0
  15. package/dist/browser/io.d.ts +58 -0
  16. package/dist/browser/io.js +205 -0
  17. package/dist/browser/random.d.ts +4 -0
  18. package/dist/browser/random.js +49 -0
  19. package/dist/browser/sockets.d.ts +8 -0
  20. package/dist/browser/sockets.js +66 -0
  21. package/dist/common/instantiation.d.ts +97 -0
  22. package/dist/common/instantiation.js +227 -0
  23. package/dist/io/calls.d.ts +91 -0
  24. package/{lib → dist}/io/calls.js +4 -19
  25. package/dist/io/worker-http.d.ts +17 -0
  26. package/dist/io/worker-http.js +192 -0
  27. package/dist/io/worker-io.d.ts +84 -0
  28. package/dist/io/worker-io.js +375 -0
  29. package/dist/io/worker-socket-tcp.d.ts +34 -0
  30. package/dist/io/worker-socket-tcp.js +251 -0
  31. package/dist/io/worker-socket-udp.d.ts +54 -0
  32. package/dist/io/worker-socket-udp.js +492 -0
  33. package/dist/io/worker-sockets.d.ts +32 -0
  34. package/dist/io/worker-sockets.js +265 -0
  35. package/dist/io/worker-thread.d.ts +73 -0
  36. package/dist/io/worker-thread.js +791 -0
  37. package/dist/nodejs/cli.d.ts +30 -0
  38. package/dist/nodejs/cli.js +86 -0
  39. package/dist/nodejs/clocks.d.ts +3 -0
  40. package/dist/nodejs/clocks.js +61 -0
  41. package/dist/nodejs/filesystem.d.ts +113 -0
  42. package/dist/nodejs/filesystem.js +758 -0
  43. package/dist/nodejs/http.d.ts +82 -0
  44. package/dist/nodejs/http.js +674 -0
  45. package/dist/nodejs/index.d.ts +7 -0
  46. package/dist/nodejs/index.js +7 -0
  47. package/dist/nodejs/io.d.ts +1 -0
  48. package/dist/nodejs/io.js +1 -0
  49. package/dist/nodejs/random.d.ts +4 -0
  50. package/dist/nodejs/random.js +42 -0
  51. package/dist/nodejs/sockets.d.ts +21 -0
  52. package/dist/nodejs/sockets.js +482 -0
  53. package/dist/synckit/index.d.ts +2 -0
  54. package/dist/synckit/index.js +117 -0
  55. package/package.json +26 -13
  56. package/types/instantiation.d.ts +7 -7
  57. package/lib/browser/cli.js +0 -135
  58. package/lib/browser/clocks.js +0 -39
  59. package/lib/browser/environment.js +0 -29
  60. package/lib/browser/filesystem.js +0 -503
  61. package/lib/browser/http.js +0 -707
  62. package/lib/browser/index.js +0 -9
  63. package/lib/browser/io.js +0 -262
  64. package/lib/browser/random.js +0 -56
  65. package/lib/browser/sockets.js +0 -88
  66. package/lib/common/instantiation.js +0 -253
  67. package/lib/io/worker-http.js +0 -206
  68. package/lib/io/worker-io.js +0 -468
  69. package/lib/io/worker-socket-tcp.js +0 -331
  70. package/lib/io/worker-socket-udp.js +0 -587
  71. package/lib/io/worker-sockets.js +0 -364
  72. package/lib/io/worker-thread.js +0 -1051
  73. package/lib/nodejs/cli.js +0 -109
  74. package/lib/nodejs/clocks.js +0 -67
  75. package/lib/nodejs/filesystem.js +0 -829
  76. package/lib/nodejs/http.js +0 -764
  77. package/lib/nodejs/index.js +0 -9
  78. package/lib/nodejs/io.js +0 -1
  79. package/lib/nodejs/random.js +0 -49
  80. package/lib/nodejs/sockets.js +0 -565
  81. package/lib/synckit/index.js +0 -127
@@ -0,0 +1,464 @@
1
+ import { inputStreamCreate, outputStreamCreate } from "./io.js";
2
+ import { environment } from "./environment.js";
3
+ import { _setCwd, _getCwd } from "./config.js";
4
+ export { _setCwd } from "./config.js";
5
+ export function _setFileData(fileData) {
6
+ _fileData = fileData;
7
+ _rootPreopen[0] = descriptorCreate(fileData);
8
+ const cwd = environment.initialCwd();
9
+ _setCwd(cwd || "/");
10
+ }
11
+ export function _getFileData() {
12
+ return JSON.stringify(_fileData);
13
+ }
14
+ let _fileData = { dir: {} };
15
+ const timeZero = {
16
+ seconds: 0n,
17
+ nanoseconds: 0,
18
+ };
19
+ /** Coerce the given object to a safe integer */
20
+ function coerceToSafeIntegerNumber(obj) {
21
+ let n;
22
+ if (typeof obj === "number") {
23
+ n = obj;
24
+ }
25
+ else if (typeof obj == "bigint") {
26
+ n = Number(obj);
27
+ }
28
+ else {
29
+ throw new TypeError(`unexpected non-numeric type: ${obj}`);
30
+ }
31
+ if (n > Number.MAX_SAFE_INTEGER) {
32
+ throw new TypeError(`excessively large number: ${n}`);
33
+ }
34
+ return n;
35
+ }
36
+ function getChildEntry(parentEntry, subpath, openFlags) {
37
+ if (subpath === "." && _rootPreopen && descriptorGetEntry(_rootPreopen[0]) === parentEntry) {
38
+ subpath = _getCwd();
39
+ if (subpath.startsWith("/") && subpath !== "/") {
40
+ subpath = subpath.slice(1);
41
+ }
42
+ }
43
+ let entry = parentEntry;
44
+ let segmentIdx;
45
+ do {
46
+ if (!entry?.dir) {
47
+ throw "not-directory";
48
+ }
49
+ segmentIdx = subpath.indexOf("/");
50
+ const segment = segmentIdx === -1 ? subpath : subpath.slice(0, segmentIdx);
51
+ if (segment === "..") {
52
+ throw "no-entry";
53
+ }
54
+ if (segment === "." || segment === "") {
55
+ }
56
+ else if (!entry.dir[segment] && openFlags.create) {
57
+ entry = entry.dir[segment] = openFlags.directory
58
+ ? { dir: {} }
59
+ : { source: new Uint8Array([]) };
60
+ }
61
+ else {
62
+ entry = entry.dir[segment];
63
+ }
64
+ subpath = subpath.slice(segmentIdx + 1);
65
+ } while (segmentIdx !== -1);
66
+ if (!entry) {
67
+ throw "no-entry";
68
+ }
69
+ return entry;
70
+ }
71
+ function getSource(fileEntry) {
72
+ if (typeof fileEntry.source === "string") {
73
+ fileEntry.source = new TextEncoder().encode(fileEntry.source);
74
+ }
75
+ return fileEntry.source;
76
+ }
77
+ class DirectoryEntryStream {
78
+ idx = 0;
79
+ entries = [];
80
+ static _create(entries) {
81
+ const stream = new DirectoryEntryStream();
82
+ stream.entries = entries;
83
+ return stream;
84
+ }
85
+ readDirectoryEntry() {
86
+ if (this.idx === this.entries.length) {
87
+ return undefined;
88
+ }
89
+ const [name, entry] = this.entries[this.idx];
90
+ this.idx += 1;
91
+ return {
92
+ name,
93
+ type: entry.dir ? "directory" : "regular-file",
94
+ };
95
+ }
96
+ }
97
+ const descriptorEntryStreamCreate = DirectoryEntryStream._create;
98
+ // @ts-expect-error - Deleting static method
99
+ delete DirectoryEntryStream._create;
100
+ class Descriptor {
101
+ #stream;
102
+ #entry;
103
+ #mtime = 0;
104
+ _getEntry(descriptor) {
105
+ return descriptor.#entry;
106
+ }
107
+ static _create(entry, isStream) {
108
+ const descriptor = new Descriptor();
109
+ if (isStream) {
110
+ descriptor.#stream = entry;
111
+ }
112
+ else {
113
+ descriptor.#entry = entry;
114
+ }
115
+ return descriptor;
116
+ }
117
+ readViaStream(_offset) {
118
+ const source = getSource(this.#entry);
119
+ let offset = Number(_offset);
120
+ return inputStreamCreate({
121
+ blockingRead(len) {
122
+ if (offset === source.byteLength) {
123
+ throw { tag: "closed" };
124
+ }
125
+ const bytes = source.slice(offset, offset + Number(len));
126
+ offset += bytes.byteLength;
127
+ return bytes;
128
+ },
129
+ });
130
+ }
131
+ writeViaStream(_offset) {
132
+ const entry = this.#entry;
133
+ let offset = Number(_offset);
134
+ return outputStreamCreate({
135
+ write(buf) {
136
+ const src = entry.source;
137
+ const newSource = new Uint8Array(buf.byteLength + src.byteLength);
138
+ newSource.set(src, 0);
139
+ newSource.set(buf, offset);
140
+ offset += buf.byteLength;
141
+ entry.source = newSource;
142
+ },
143
+ });
144
+ }
145
+ appendViaStream() {
146
+ console.log(`[filesystem] APPEND STREAM`);
147
+ return {};
148
+ }
149
+ advise(offset, length, advice) {
150
+ console.log(`[filesystem] ADVISE`, offset, length, advice);
151
+ }
152
+ syncData() {
153
+ console.log(`[filesystem] SYNC DATA`);
154
+ }
155
+ getFlags() {
156
+ console.log(`[filesystem] FLAGS FOR`);
157
+ return {};
158
+ }
159
+ getType() {
160
+ if (this.#stream) {
161
+ return "fifo";
162
+ }
163
+ if (this.#entry.dir) {
164
+ return "directory";
165
+ }
166
+ if (this.#entry.source) {
167
+ return "regular-file";
168
+ }
169
+ return "unknown";
170
+ }
171
+ setSize(size) {
172
+ console.log(`[filesystem] SET SIZE`, size);
173
+ }
174
+ setTimes(dataAccessTimestamp, dataModificationTimestamp) {
175
+ console.log(`[filesystem] SET TIMES`, dataAccessTimestamp, dataModificationTimestamp);
176
+ }
177
+ read(length, offset) {
178
+ const source = getSource(this.#entry);
179
+ const off = coerceToSafeIntegerNumber(offset);
180
+ const len = coerceToSafeIntegerNumber(length);
181
+ const result = [
182
+ source.slice(off, off + len),
183
+ off + len >= source.byteLength,
184
+ ];
185
+ return result;
186
+ }
187
+ write(buffer, offset) {
188
+ if (offset !== 0n) {
189
+ throw "invalid-seek";
190
+ }
191
+ this.#entry.source = buffer;
192
+ return BigInt(buffer.byteLength);
193
+ }
194
+ readDirectory() {
195
+ if (!this.#entry?.dir) {
196
+ throw "bad-descriptor";
197
+ }
198
+ return descriptorEntryStreamCreate(Object.entries(this.#entry.dir).sort(([a], [b]) => (a > b ? 1 : -1)));
199
+ }
200
+ sync() {
201
+ console.log(`[filesystem] SYNC`);
202
+ }
203
+ createDirectoryAt(path) {
204
+ const entry = getChildEntry(this.#entry, path, {
205
+ create: true,
206
+ directory: true,
207
+ });
208
+ if (entry.source) {
209
+ throw "exist";
210
+ }
211
+ }
212
+ stat() {
213
+ let type = "unknown";
214
+ let size = 0n;
215
+ if (this.#entry.source) {
216
+ type = "regular-file";
217
+ const source = getSource(this.#entry);
218
+ size = BigInt(source.byteLength);
219
+ }
220
+ else if (this.#entry.dir) {
221
+ type = "directory";
222
+ }
223
+ return {
224
+ type,
225
+ linkCount: 0n,
226
+ size,
227
+ dataAccessTimestamp: timeZero,
228
+ dataModificationTimestamp: timeZero,
229
+ statusChangeTimestamp: timeZero,
230
+ };
231
+ }
232
+ statAt(_pathFlags, path) {
233
+ const entry = getChildEntry(this.#entry, path, {
234
+ create: false,
235
+ directory: false,
236
+ });
237
+ let type = "unknown";
238
+ let size = 0n;
239
+ if (entry.source) {
240
+ type = "regular-file";
241
+ const source = getSource(entry);
242
+ size = BigInt(source.byteLength);
243
+ }
244
+ else if (entry.dir) {
245
+ type = "directory";
246
+ }
247
+ return {
248
+ type,
249
+ linkCount: 0n,
250
+ size,
251
+ dataAccessTimestamp: timeZero,
252
+ dataModificationTimestamp: timeZero,
253
+ statusChangeTimestamp: timeZero,
254
+ };
255
+ }
256
+ setTimesAt() {
257
+ console.log(`[filesystem] SET TIMES AT`);
258
+ }
259
+ linkAt() {
260
+ console.log(`[filesystem] LINK AT`);
261
+ }
262
+ openAt(_pathFlags, path, openFlags, _flags) {
263
+ const childEntry = getChildEntry(this.#entry, path, openFlags);
264
+ return descriptorCreate(childEntry);
265
+ }
266
+ readlinkAt(_path) {
267
+ console.log(`[filesystem] READLINK AT`);
268
+ return "";
269
+ }
270
+ removeDirectoryAt() {
271
+ console.log(`[filesystem] REMOVE DIR AT`);
272
+ }
273
+ renameAt() {
274
+ console.log(`[filesystem] RENAME AT`);
275
+ }
276
+ symlinkAt() {
277
+ console.log(`[filesystem] SYMLINK AT`);
278
+ }
279
+ unlinkFileAt() {
280
+ console.log(`[filesystem] UNLINK FILE AT`);
281
+ }
282
+ isSameObject(other) {
283
+ return other === this;
284
+ }
285
+ metadataHash() {
286
+ let upper = 0n;
287
+ upper += BigInt(this.#mtime);
288
+ return { upper, lower: 0n };
289
+ }
290
+ metadataHashAt(_pathFlags, _path) {
291
+ return this.metadataHash();
292
+ }
293
+ }
294
+ const descriptorGetEntry = Descriptor.prototype._getEntry;
295
+ // @ts-expect-error - Deleting prototype method
296
+ delete Descriptor.prototype._getEntry;
297
+ const descriptorCreate = Descriptor._create;
298
+ // @ts-expect-error - Deleting static method
299
+ delete Descriptor._create;
300
+ let _preopens = [[descriptorCreate(_fileData), "/"]];
301
+ let _rootPreopen = _preopens[0];
302
+ export const preopens = {
303
+ getDirectories() {
304
+ return _preopens;
305
+ },
306
+ };
307
+ /**
308
+ * Replace all preopens with the given set.
309
+ * @param preopensConfig - Map of virtual paths to file data entries
310
+ */
311
+ export function _setPreopens(preopensConfig) {
312
+ _preopens = [];
313
+ for (const [virtualPath, fileData] of Object.entries(preopensConfig)) {
314
+ _addPreopen(virtualPath, fileData);
315
+ }
316
+ }
317
+ /**
318
+ * Add a single preopen mapping.
319
+ * @param virtualPath - The virtual path visible to the guest
320
+ * @param fileData - The file data object representing the directory
321
+ */
322
+ export function _addPreopen(virtualPath, fileData) {
323
+ const descriptor = descriptorCreate(fileData);
324
+ _preopens.push([descriptor, virtualPath]);
325
+ if (virtualPath === "/") {
326
+ _rootPreopen = [descriptor, virtualPath];
327
+ }
328
+ }
329
+ /**
330
+ * Clear all preopens, giving the guest no filesystem access.
331
+ *
332
+ * This functionality exists mostly to maintain backwards compatibility. Prefer setting preopens
333
+ * via `WASIShim` rather than making top level changes to preopens using these functions.
334
+ */
335
+ export function _clearPreopens() {
336
+ _preopens = [];
337
+ _rootPreopen = null;
338
+ }
339
+ /**
340
+ * Get current preopens configuration.
341
+ * @returns Array of [descriptor, virtualPath] pairs
342
+ */
343
+ export function _getPreopens() {
344
+ return [..._preopens];
345
+ }
346
+ /**
347
+ * Create a preopen descriptor for a host path.
348
+ * This is used internally to create isolated preopen instances.
349
+ * @param hostPreopen - The host filesystem path
350
+ * @returns A preopen descriptor
351
+ */
352
+ export function _createPreopenDescriptor(hostPreopen) {
353
+ _fileData.dir = {
354
+ [hostPreopen]: {},
355
+ };
356
+ return descriptorCreate(_fileData);
357
+ }
358
+ export const types = {
359
+ Descriptor,
360
+ DirectoryEntryStream,
361
+ filesystemErrorCode: (err) => {
362
+ let message;
363
+ if ("payload" in err) {
364
+ message = err.payload;
365
+ }
366
+ else if ("message" in err) {
367
+ message = err.message;
368
+ }
369
+ return convertFsError(message);
370
+ },
371
+ };
372
+ function convertFsError(e) {
373
+ switch (e.code) {
374
+ case "EACCES":
375
+ return "access";
376
+ case "EAGAIN":
377
+ case "EWOULDBLOCK":
378
+ return "would-block";
379
+ case "EALREADY":
380
+ return "already";
381
+ case "EBADF":
382
+ return "bad-descriptor";
383
+ case "EBUSY":
384
+ return "busy";
385
+ case "EDEADLK":
386
+ return "deadlock";
387
+ case "EDQUOT":
388
+ return "quota";
389
+ case "EEXIST":
390
+ return "exist";
391
+ case "EFBIG":
392
+ return "file-too-large";
393
+ case "EILSEQ":
394
+ return "illegal-byte-sequence";
395
+ case "EINPROGRESS":
396
+ return "in-progress";
397
+ case "EINTR":
398
+ return "interrupted";
399
+ case "EINVAL":
400
+ return "invalid";
401
+ case "EIO":
402
+ return "io";
403
+ case "EISDIR":
404
+ return "is-directory";
405
+ case "ELOOP":
406
+ return "loop";
407
+ case "EMLINK":
408
+ return "too-many-links";
409
+ case "EMSGSIZE":
410
+ return "message-size";
411
+ case "ENAMETOOLONG":
412
+ return "name-too-long";
413
+ case "ENODEV":
414
+ return "no-device";
415
+ case "ENOENT":
416
+ return "no-entry";
417
+ case "ENOLCK":
418
+ return "no-lock";
419
+ case "ENOMEM":
420
+ return "insufficient-memory";
421
+ case "ENOSPC":
422
+ return "insufficient-space";
423
+ case "ENOTDIR":
424
+ case "ERR_FS_EISDIR":
425
+ return "not-directory";
426
+ case "ENOTEMPTY":
427
+ return "not-empty";
428
+ case "ENOTRECOVERABLE":
429
+ return "not-recoverable";
430
+ case "ENOTSUP":
431
+ return "unsupported";
432
+ case "ENOTTY":
433
+ return "no-tty";
434
+ // windows gives this error for badly structured `//` reads
435
+ // this seems like a slightly better error than unknown given
436
+ // that it's a common footgun
437
+ case -4094:
438
+ case "ENXIO":
439
+ return "no-such-device";
440
+ case "EOVERFLOW":
441
+ return "overflow";
442
+ case "EPERM":
443
+ return "not-permitted";
444
+ case "EPIPE":
445
+ return "pipe";
446
+ case "EROFS":
447
+ return "read-only";
448
+ case "ESPIPE":
449
+ return "invalid-seek";
450
+ case "ETXTBSY":
451
+ return "text-file-busy";
452
+ case "EXDEV":
453
+ return "cross-device";
454
+ case "UNKNOWN":
455
+ switch (e.errno) {
456
+ case -4094:
457
+ return "no-such-device";
458
+ default:
459
+ throw e;
460
+ }
461
+ default:
462
+ throw e;
463
+ }
464
+ }
@@ -0,0 +1,4 @@
1
+ import type { incomingHandler as IncomingHandlerNamespace, outgoingHandler as OutgoingHandlerNamespace, types as TypesNamespace } from "../../types/http.js";
2
+ export declare const outgoingHandler: typeof OutgoingHandlerNamespace;
3
+ export declare const incomingHandler: typeof IncomingHandlerNamespace;
4
+ export declare const types: typeof TypesNamespace;