@bytecodealliance/preview2-shim 0.17.1 → 0.17.3

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 (67) hide show
  1. package/lib/browser/cli.js +91 -94
  2. package/lib/browser/clocks.js +30 -29
  3. package/lib/browser/filesystem.js +298 -251
  4. package/lib/browser/http.js +129 -128
  5. package/lib/browser/index.js +8 -16
  6. package/lib/browser/io.js +143 -135
  7. package/lib/browser/random.js +44 -42
  8. package/lib/browser/sockets.js +68 -166
  9. package/lib/common/instantiation.js +127 -0
  10. package/lib/io/calls.js +7 -5
  11. package/lib/io/worker-http.js +175 -157
  12. package/lib/io/worker-io.js +402 -386
  13. package/lib/io/worker-socket-tcp.js +271 -219
  14. package/lib/io/worker-socket-udp.js +494 -429
  15. package/lib/io/worker-sockets.js +276 -262
  16. package/lib/io/worker-thread.js +946 -815
  17. package/lib/nodejs/cli.js +64 -63
  18. package/lib/nodejs/clocks.js +51 -45
  19. package/lib/nodejs/filesystem.js +788 -654
  20. package/lib/nodejs/http.js +693 -617
  21. package/lib/nodejs/index.js +8 -16
  22. package/lib/nodejs/random.js +32 -28
  23. package/lib/nodejs/sockets.js +538 -474
  24. package/lib/synckit/index.js +94 -85
  25. package/package.json +9 -5
  26. package/types/cli.d.ts +11 -23
  27. package/types/clocks.d.ts +2 -5
  28. package/types/filesystem.d.ts +2 -5
  29. package/types/http.d.ts +3 -7
  30. package/types/index.d.ts +6 -15
  31. package/types/instantiation.d.ts +112 -0
  32. package/types/interfaces/wasi-cli-environment.d.ts +21 -22
  33. package/types/interfaces/wasi-cli-exit.d.ts +5 -6
  34. package/types/interfaces/wasi-cli-run.d.ts +5 -6
  35. package/types/interfaces/wasi-cli-stderr.d.ts +3 -5
  36. package/types/interfaces/wasi-cli-stdin.d.ts +3 -5
  37. package/types/interfaces/wasi-cli-stdout.d.ts +3 -5
  38. package/types/interfaces/wasi-cli-terminal-input.d.ts +5 -3
  39. package/types/interfaces/wasi-cli-terminal-output.d.ts +5 -3
  40. package/types/interfaces/wasi-cli-terminal-stderr.d.ts +7 -9
  41. package/types/interfaces/wasi-cli-terminal-stdin.d.ts +7 -9
  42. package/types/interfaces/wasi-cli-terminal-stdout.d.ts +7 -9
  43. package/types/interfaces/wasi-clocks-monotonic-clock.d.ts +24 -26
  44. package/types/interfaces/wasi-clocks-wall-clock.d.ts +23 -24
  45. package/types/interfaces/wasi-filesystem-preopens.d.ts +6 -8
  46. package/types/interfaces/wasi-filesystem-types.d.ts +34 -33
  47. package/types/interfaces/wasi-http-incoming-handler.d.ts +16 -19
  48. package/types/interfaces/wasi-http-outgoing-handler.d.ts +18 -23
  49. package/types/interfaces/wasi-http-types.d.ts +49 -38
  50. package/types/interfaces/wasi-io-error.d.ts +5 -3
  51. package/types/interfaces/wasi-io-poll.d.ts +27 -25
  52. package/types/interfaces/wasi-io-streams.d.ts +24 -21
  53. package/types/interfaces/wasi-random-insecure-seed.d.ts +21 -22
  54. package/types/interfaces/wasi-random-insecure.d.ts +19 -20
  55. package/types/interfaces/wasi-random-random.d.ts +23 -24
  56. package/types/interfaces/wasi-sockets-instance-network.d.ts +6 -8
  57. package/types/interfaces/wasi-sockets-ip-name-lookup.d.ts +32 -34
  58. package/types/interfaces/wasi-sockets-network.d.ts +5 -3
  59. package/types/interfaces/wasi-sockets-tcp-create-socket.d.ts +28 -33
  60. package/types/interfaces/wasi-sockets-tcp.d.ts +17 -23
  61. package/types/interfaces/wasi-sockets-udp-create-socket.d.ts +28 -33
  62. package/types/interfaces/wasi-sockets-udp.d.ts +20 -17
  63. package/types/io.d.ts +3 -7
  64. package/types/random.d.ts +3 -7
  65. package/types/sockets.d.ts +7 -15
  66. package/types/wasi-cli-command.d.ts +29 -29
  67. package/types/wasi-http-proxy.d.ts +13 -13
@@ -3,54 +3,56 @@ const MAX_BYTES = 65536;
3
3
  let insecureRandomValue1, insecureRandomValue2;
4
4
 
5
5
  export const insecure = {
6
- getInsecureRandomBytes (len) {
7
- return random.getRandomBytes(len);
8
- },
9
- getInsecureRandomU64 () {
10
- return random.getRandomU64();
11
- }
6
+ getInsecureRandomBytes(len) {
7
+ return random.getRandomBytes(len);
8
+ },
9
+ getInsecureRandomU64() {
10
+ return random.getRandomU64();
11
+ },
12
12
  };
13
13
 
14
14
  let insecureSeedValue1, insecureSeedValue2;
15
15
 
16
16
  export const insecureSeed = {
17
- insecureSeed () {
18
- if (insecureSeedValue1 === undefined) {
19
- insecureSeedValue1 = random.getRandomU64();
20
- insecureSeedValue2 = random.getRandomU64();
21
- }
22
- return [insecureSeedValue1, insecureSeedValue2];
23
- }
17
+ insecureSeed() {
18
+ if (insecureSeedValue1 === undefined) {
19
+ insecureSeedValue1 = random.getRandomU64();
20
+ insecureSeedValue2 = random.getRandomU64();
21
+ }
22
+ return [insecureSeedValue1, insecureSeedValue2];
23
+ },
24
24
  };
25
25
 
26
26
  export const random = {
27
- getRandomBytes(len) {
28
- const bytes = new Uint8Array(Number(len));
29
-
30
- if (len > MAX_BYTES) {
31
- // this is the max bytes crypto.getRandomValues
32
- // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
33
- for (var generated = 0; generated < len; generated += MAX_BYTES) {
34
- // buffer.slice automatically checks if the end is past the end of
35
- // the buffer so we don't have to here
36
- crypto.getRandomValues(bytes.subarray(generated, generated + MAX_BYTES));
37
- }
38
- } else {
39
- crypto.getRandomValues(bytes);
40
- }
41
-
42
- return bytes;
43
- },
44
-
45
- getRandomU64 () {
46
- return crypto.getRandomValues(new BigUint64Array(1))[0];
47
- },
48
-
49
- insecureRandom () {
50
- if (insecureRandomValue1 === undefined) {
51
- insecureRandomValue1 = random.getRandomU64();
52
- insecureRandomValue2 = random.getRandomU64();
53
- }
54
- return [insecureRandomValue1, insecureRandomValue2];
55
- }
27
+ getRandomBytes(len) {
28
+ const bytes = new Uint8Array(Number(len));
29
+
30
+ if (len > MAX_BYTES) {
31
+ // this is the max bytes crypto.getRandomValues
32
+ // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
33
+ for (var generated = 0; generated < len; generated += MAX_BYTES) {
34
+ // buffer.slice automatically checks if the end is past the end of
35
+ // the buffer so we don't have to here
36
+ crypto.getRandomValues(
37
+ bytes.subarray(generated, generated + MAX_BYTES)
38
+ );
39
+ }
40
+ } else {
41
+ crypto.getRandomValues(bytes);
42
+ }
43
+
44
+ return bytes;
45
+ },
46
+
47
+ getRandomU64() {
48
+ return crypto.getRandomValues(new BigUint64Array(1))[0];
49
+ },
50
+
51
+ insecureRandom() {
52
+ if (insecureRandomValue1 === undefined) {
53
+ insecureRandomValue1 = random.getRandomU64();
54
+ insecureRandomValue2 = random.getRandomU64();
55
+ }
56
+ return [insecureRandomValue1, insecureRandomValue2];
57
+ },
56
58
  };
@@ -1,186 +1,88 @@
1
1
  export const instanceNetwork = {
2
- instanceNetwork () {
3
- console.log(`[sockets] instance network`);
4
- }
2
+ instanceNetwork() {
3
+ console.log(`[sockets] instance network`);
4
+ },
5
5
  };
6
6
 
7
7
  export const ipNameLookup = {
8
- dropResolveAddressStream () {
9
-
10
- },
11
- subscribe () {
12
-
13
- },
14
- resolveAddresses () {
15
-
16
- },
17
- resolveNextAddress () {
18
-
19
- },
20
- nonBlocking () {
21
-
22
- },
23
- setNonBlocking () {
24
-
25
- },
8
+ dropResolveAddressStream() {},
9
+ subscribe() {},
10
+ resolveAddresses() {},
11
+ resolveNextAddress() {},
12
+ nonBlocking() {},
13
+ setNonBlocking() {},
26
14
  };
27
15
 
28
16
  export const network = {
29
- dropNetwork () {
30
-
31
- }
17
+ dropNetwork() {},
32
18
  };
33
19
 
34
20
  export const tcpCreateSocket = {
35
- createTcpSocket () {
36
-
37
- }
21
+ createTcpSocket() {},
38
22
  };
39
23
 
40
24
  export const tcp = {
41
- subscribe () {
42
-
43
- },
44
- dropTcpSocket() {
45
-
46
- },
47
- bind() {
48
-
49
- },
50
- connect() {
51
-
52
- },
53
- listen() {
54
-
55
- },
56
- accept() {
57
-
58
- },
59
- localAddress() {
60
-
61
- },
62
- remoteAddress() {
63
-
64
- },
65
- addressFamily() {
66
-
67
- },
68
- setListenBacklogSize() {
69
-
70
- },
71
- keepAlive() {
72
-
73
- },
74
- setKeepAlive() {
75
-
76
- },
77
- noDelay() {
78
-
79
- },
80
- setNoDelay() {
81
-
82
- },
83
- unicastHopLimit() {
84
-
85
- },
86
- setUnicastHopLimit() {
87
-
88
- },
89
- receiveBufferSize() {
90
-
91
- },
92
- setReceiveBufferSize() {
93
-
94
- },
95
- sendBufferSize() {
96
-
97
- },
98
- setSendBufferSize() {
99
-
100
- },
101
- nonBlocking() {
102
-
103
- },
104
- setNonBlocking() {
105
-
106
- },
107
- shutdown() {
108
-
109
- }
25
+ subscribe() {},
26
+ dropTcpSocket() {},
27
+ bind() {},
28
+ connect() {},
29
+ listen() {},
30
+ accept() {},
31
+ localAddress() {},
32
+ remoteAddress() {},
33
+ addressFamily() {},
34
+ setListenBacklogSize() {},
35
+ keepAlive() {},
36
+ setKeepAlive() {},
37
+ noDelay() {},
38
+ setNoDelay() {},
39
+ unicastHopLimit() {},
40
+ setUnicastHopLimit() {},
41
+ receiveBufferSize() {},
42
+ setReceiveBufferSize() {},
43
+ sendBufferSize() {},
44
+ setSendBufferSize() {},
45
+ nonBlocking() {},
46
+ setNonBlocking() {},
47
+ shutdown() {},
110
48
  };
111
49
 
112
50
  export const udp = {
113
- subscribe () {
114
-
115
- },
116
-
117
- dropUdpSocket () {
118
-
119
- },
120
-
121
- bind () {
122
-
123
- },
124
-
125
- connect () {
126
-
127
- },
128
-
129
- receive () {
130
-
131
- },
132
-
133
- send () {
134
-
135
- },
136
-
137
- localAddress () {
138
-
139
- },
140
-
141
- remoteAddress () {
142
-
143
- },
144
-
145
- addressFamily () {
146
-
147
- },
148
-
149
- unicastHopLimit () {
150
-
151
- },
152
-
153
- setUnicastHopLimit () {
154
-
155
- },
156
-
157
- receiveBufferSize () {
158
-
159
- },
160
-
161
- setReceiveBufferSize () {
162
-
163
- },
164
-
165
- sendBufferSize () {
166
-
167
- },
168
-
169
- setSendBufferSize () {
170
-
171
- },
172
-
173
- nonBlocking () {
174
-
175
- },
176
-
177
- setNonBlocking () {
178
-
179
- }
51
+ subscribe() {},
52
+
53
+ dropUdpSocket() {},
54
+
55
+ bind() {},
56
+
57
+ connect() {},
58
+
59
+ receive() {},
60
+
61
+ send() {},
62
+
63
+ localAddress() {},
64
+
65
+ remoteAddress() {},
66
+
67
+ addressFamily() {},
68
+
69
+ unicastHopLimit() {},
70
+
71
+ setUnicastHopLimit() {},
72
+
73
+ receiveBufferSize() {},
74
+
75
+ setReceiveBufferSize() {},
76
+
77
+ sendBufferSize() {},
78
+
79
+ setSendBufferSize() {},
80
+
81
+ nonBlocking() {},
82
+
83
+ setNonBlocking() {},
180
84
  };
181
85
 
182
86
  export const udpCreateSocket = {
183
- createUdpSocket () {
184
-
185
- }
87
+ createUdpSocket() {},
186
88
  };
@@ -0,0 +1,127 @@
1
+ import * as wasi from '@bytecodealliance/preview2-shim';
2
+
3
+ /**
4
+ * (EXPERIMENTAL) A class that holds WASI shims and can be used to configure
5
+ * an instantiation of a WebAssembly component transpiled with jco
6
+ * (i.e. via `jco transpile`).
7
+ *
8
+ * Normally, transpiled components contain mapping for WASI interfaces
9
+ * and/or imports that import the relevant packages (ex. `@bytecodealliance/preview2-shim/clocks`)
10
+ * from the right sources.
11
+ *
12
+ * This function makes use of the `WASIShim` object to provide an object that can be easily
13
+ * fed to the `instantiate` function produced by a transpiled component:
14
+ *
15
+ * ```js
16
+ * import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation"
17
+ * // ...
18
+ * import { instantiate } from "path/to/transpiled/component.js"
19
+ * // ...
20
+ * const component = await instantiate(null, new WASIShim().getImportObject())
21
+ * ```
22
+ *
23
+ * You can also replace imports that you'd like to override with custom implementations,
24
+ * by using the `WASIShim` object directly:
25
+ *
26
+ * ```js
27
+ * import { random } from "@bytecodealliance/preview2-shim"
28
+ * import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation"
29
+ * // ...
30
+ * import { instantiate } from "path/to/transpiled/component.js"
31
+ * // ...
32
+ * const customWASIShim = new WASIShim({
33
+ * random: {
34
+ * // For these two interfaces we re-use the default provided shim
35
+ * random: random.random,
36
+ * insecure-seed: random.insecureSeed,
37
+ * // For insecure, we can supply our own custom implementation
38
+ * insecure: {
39
+ * ...
40
+ * }
41
+ * }
42
+ * });
43
+ *
44
+ * const component = await instantiate(null, customWASIShim.getImportObject())
45
+ * ```
46
+ *
47
+ * Note that this object is similar but not identical to the Node `WASI` object --
48
+ * it is solely concerned with shimming of preview2 when dealing with a WebAssembly
49
+ * component transpiled by Jco. While this object *does* work with Node (and the browser)
50
+ * semantics are not the same as Node's `WASI` object.
51
+ *
52
+ * @class WASIShim
53
+ */
54
+ export class WASIShim {
55
+ /** Object that confirms to the shim interface for `wasi:cli` */
56
+ #cli;
57
+ /** Object that confirms to the shim interface for `wasi:filesystem` */
58
+ #filesystem;
59
+ /** Object that confirms to the shim interface for `wasi:io` */
60
+ #io;
61
+ /** Object that confirms to the shim interface for `wasi:random` */
62
+ #random;
63
+ /** Object that confirms to the shim interface for `wasi:clocks` */
64
+ #clocks;
65
+ /** Object that confirms to the shim interface for `wasi:sockets` */
66
+ #sockets;
67
+ /** Object that confirms to the shim interface for `wasi:http` */
68
+ #http;
69
+
70
+ constructor(shims) {
71
+ this.#cli = shims?.cli ?? wasi.cli;
72
+ this.#filesystem = shims?.filesystem ?? wasi.filesystem;
73
+ this.#io = shims?.io ?? wasi.io;
74
+ this.#random = shims?.random ?? wasi.random;
75
+ this.#clocks = shims?.clocks ?? wasi.clocks;
76
+ this.#sockets = shims?.sockets ?? wasi.sockets;
77
+ this.#http = shims?.http ?? wasi.http;
78
+ }
79
+
80
+ /**
81
+ * Generate an import object for the shim that can be used with
82
+ * functions like `instantiate` that are exposed from a transpiled
83
+ * WebAssembly component.
84
+ *
85
+ * @returns {object}
86
+ */
87
+ getImportObject() {
88
+ return {
89
+ 'wasi:cli/environment': this.#cli.environment,
90
+ 'wasi:cli/exit': this.#cli.exit,
91
+ 'wasi:cli/stderr': this.#cli.stderr,
92
+ 'wasi:cli/stdin': this.#cli.stdin,
93
+ 'wasi:cli/stdout': this.#cli.stdout,
94
+ 'wasi:cli/terminal-input': this.#cli.terminalInput,
95
+ 'wasi:cli/terminal-output': this.#cli.terminalOutput,
96
+ 'wasi:cli/terminal-stderr': this.#cli.terminalStderr,
97
+ 'wasi:cli/terminal-stdin': this.#cli.terminalStdin,
98
+ 'wasi:cli/terminal-stdout': this.#cli.terminalStdout,
99
+
100
+ 'wasi:sockets/instance-network': this.#sockets.instanceNetwork,
101
+ 'wasi:sockets/ip-name-lookup': this.#sockets.ipNameLookup,
102
+ 'wasi:sockets/network': this.#sockets.network,
103
+ 'wasi:sockets/tcp': this.#sockets.tcp,
104
+ 'wasi:sockets/tcp-create-socket': this.#sockets.tcpCreateSocket,
105
+ 'wasi:sockets/udp': this.#sockets.udp,
106
+ 'wasi:sockets/udp-create-socket': this.#sockets.udpCreateSocket,
107
+
108
+ 'wasi:filesystem/preopens': this.#filesystem.preopens,
109
+ 'wasi:filesystem/types': this.#filesystem.types,
110
+
111
+ 'wasi:io/error': this.#io.error,
112
+ 'wasi:io/poll': this.#io.poll,
113
+ 'wasi:io/streams': this.#io.streams,
114
+
115
+ 'wasi:random/random': this.#random.random,
116
+ 'wasi:random/insecure': this.#random.insecure,
117
+ 'wasi:random/insecure-seed': this.#random.insecureSeed,
118
+
119
+ 'wasi:clocks/monotonic-clock': this.#clocks.monotonicClock,
120
+ 'wasi:clocks/timezone': this.#clocks.timezone,
121
+ 'wasi:clocks/wall-clock': this.#clocks.wallClock,
122
+
123
+ 'wasi:http/types': this.#http.types,
124
+ 'wasi:http/outgoing-handler': this.#http.outgoingHandler,
125
+ };
126
+ }
127
+ }
package/lib/io/calls.js CHANGED
@@ -34,7 +34,7 @@ export const OUTPUT_STREAM_FLUSH = ++call_id << CALL_SHIFT;
34
34
  export const OUTPUT_STREAM_BLOCKING_FLUSH = ++call_id << CALL_SHIFT;
35
35
  export const OUTPUT_STREAM_WRITE_ZEROES = ++call_id << CALL_SHIFT;
36
36
  export const OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH =
37
- ++call_id << CALL_SHIFT;
37
+ ++call_id << CALL_SHIFT;
38
38
  export const OUTPUT_STREAM_SPLICE = ++call_id << CALL_SHIFT;
39
39
  export const OUTPUT_STREAM_BLOCKING_SPLICE = ++call_id << CALL_SHIFT;
40
40
  export const OUTPUT_STREAM_SUBSCRIBE = ++call_id << CALL_SHIFT;
@@ -103,7 +103,7 @@ export const SOCKET_UDP_SET_SEND_BUFFER_SIZE = ++call_id << CALL_SHIFT;
103
103
  export const SOCKET_UDP_SET_UNICAST_HOP_LIMIT = ++call_id << CALL_SHIFT;
104
104
  export const SOCKET_INCOMING_DATAGRAM_STREAM_RECEIVE = ++call_id << CALL_SHIFT;
105
105
  export const SOCKET_OUTGOING_DATAGRAM_STREAM_CHECK_SEND =
106
- ++call_id << CALL_SHIFT;
106
+ ++call_id << CALL_SHIFT;
107
107
  export const SOCKET_OUTGOING_DATAGRAM_STREAM_SEND = ++call_id << CALL_SHIFT;
108
108
  export const SOCKET_DATAGRAM_STREAM_SUBSCRIBE = ++call_id << CALL_SHIFT;
109
109
  export const SOCKET_DATAGRAM_STREAM_DISPOSE = ++call_id << CALL_SHIFT;
@@ -119,9 +119,11 @@ export const SOCKET_RESOLVE_ADDRESS_DISPOSE_REQUEST = ++call_id << CALL_SHIFT;
119
119
 
120
120
  export const reverseMap = {};
121
121
 
122
- import * as calls from "./calls.js";
122
+ import * as calls from './calls.js';
123
123
 
124
124
  for (const name of Object.getOwnPropertyNames(calls)) {
125
- if (name === "reverseMap") continue;
126
- reverseMap[calls[name]] = name;
125
+ if (name === 'reverseMap') {
126
+ continue;
127
+ }
128
+ reverseMap[calls[name]] = name;
127
129
  }