@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.
- package/README.md +18 -18
- package/lib/browser/cli.js +71 -71
- package/lib/browser/clocks.js +34 -30
- package/lib/browser/config.js +3 -3
- package/lib/browser/environment.js +15 -15
- package/lib/browser/filesystem.js +382 -396
- package/lib/browser/http.js +683 -144
- package/lib/browser/index.js +7 -7
- package/lib/browser/io.js +199 -133
- package/lib/browser/random.js +42 -44
- package/lib/browser/sockets.js +52 -52
- package/lib/common/instantiation.js +147 -151
- package/lib/io/calls.js +7 -9
- package/lib/io/worker-http.js +167 -178
- package/lib/io/worker-io.js +338 -406
- package/lib/io/worker-socket-tcp.js +259 -271
- package/lib/io/worker-socket-udp.js +437 -491
- package/lib/io/worker-sockets.js +230 -251
- package/lib/io/worker-thread.js +774 -822
- package/lib/nodejs/cli.js +53 -65
- package/lib/nodejs/clocks.js +49 -52
- package/lib/nodejs/filesystem.js +726 -785
- package/lib/nodejs/http.js +651 -697
- package/lib/nodejs/index.js +7 -7
- package/lib/nodejs/io.js +1 -1
- package/lib/nodejs/random.js +32 -32
- package/lib/nodejs/sockets.js +468 -538
- package/lib/synckit/index.js +85 -94
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -13,24 +13,24 @@ Browser support is considered experimental, and not currently suitable for produ
|
|
|
13
13
|
An default instantiation object can be used via the `WASIShim` class in `@bytecodealliance/preview2-shim/instantiation`:
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import { WASIShim } from
|
|
16
|
+
import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation";
|
|
17
17
|
import type {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from
|
|
18
|
+
VersionedWASIImportObject,
|
|
19
|
+
WASIImportObject,
|
|
20
|
+
} from "@bytecodealliance/preview2-shim/instantiation";
|
|
21
21
|
|
|
22
22
|
const shim = new WASIShim();
|
|
23
23
|
|
|
24
24
|
const unversioned: WASIImportObject = shim.getImportObject();
|
|
25
25
|
// console.log('unversioned', unversioned);
|
|
26
26
|
unversioned satisfies WASIImportObject;
|
|
27
|
-
unversioned satisfies VersionedWASIImportObject<
|
|
27
|
+
unversioned satisfies VersionedWASIImportObject<"">;
|
|
28
28
|
|
|
29
|
-
const versioned: VersionedWASIImportObject<
|
|
30
|
-
|
|
29
|
+
const versioned: VersionedWASIImportObject<"0.2.3"> = shim.getImportObject({
|
|
30
|
+
asVersion: "0.2.3",
|
|
31
31
|
});
|
|
32
32
|
//console.log('versioned', versioned);
|
|
33
|
-
versioned satisfies VersionedWASIImportObject<
|
|
33
|
+
versioned satisfies VersionedWASIImportObject<"0.2.3">;
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
The import object generated by `getImportObject` can be easily used in `instantiate()` calls
|
|
@@ -62,27 +62,27 @@ sandboxing to restrict what guests can access.
|
|
|
62
62
|
The `WASIShim` class accepts a `sandbox` configuration option to control access:
|
|
63
63
|
|
|
64
64
|
```js
|
|
65
|
-
import { WASIShim } from
|
|
65
|
+
import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation";
|
|
66
66
|
|
|
67
67
|
// Fully sandboxed - no filesystem, network, or env access
|
|
68
68
|
const sandboxedShim = new WASIShim({
|
|
69
69
|
sandbox: {
|
|
70
|
-
preopens: {},
|
|
71
|
-
env: {},
|
|
72
|
-
args: [
|
|
73
|
-
enableNetwork: false,
|
|
74
|
-
}
|
|
70
|
+
preopens: {}, // No filesystem access
|
|
71
|
+
env: {}, // No environment variables
|
|
72
|
+
args: ["arg1"], // Custom arguments
|
|
73
|
+
enableNetwork: false, // Disable network access
|
|
74
|
+
},
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// Limited filesystem access - map virtual paths to host paths
|
|
78
78
|
const limitedShim = new WASIShim({
|
|
79
79
|
sandbox: {
|
|
80
80
|
preopens: {
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
"/data": "/tmp/guest-data", // Guest sees /data, maps to /tmp/guest-data
|
|
82
|
+
"/config": "/etc/app", // Guest sees /config, maps to /etc/app
|
|
83
83
|
},
|
|
84
|
-
env: {
|
|
85
|
-
}
|
|
84
|
+
env: { ENV1: "42" }, // Only expose specific env vars
|
|
85
|
+
},
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
const component = await instantiate(loader, sandboxedShim.getImportObject());
|
package/lib/browser/cli.js
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
import { streams } from
|
|
1
|
+
import { streams } from "./io.js";
|
|
2
2
|
const { InputStream, OutputStream } = streams;
|
|
3
3
|
|
|
4
|
-
export { _setEnv, _setArgs, environment } from
|
|
5
|
-
export { _setCwd } from
|
|
4
|
+
export { _setEnv, _setArgs, environment } from "./environment.js";
|
|
5
|
+
export { _setCwd } from "./config.js";
|
|
6
6
|
|
|
7
|
-
const symbolDispose = Symbol.dispose ?? Symbol.for(
|
|
7
|
+
const symbolDispose = Symbol.dispose ?? Symbol.for("dispose");
|
|
8
8
|
|
|
9
9
|
class ComponentExit extends Error {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
constructor(code) {
|
|
11
|
+
super(`Component exited ${code === 0 ? "successfully" : "with error"}`);
|
|
12
|
+
this.exitError = true;
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export const exit = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
exit(status) {
|
|
19
|
+
throw new ComponentExit(status.tag === "err" ? 1 : 0);
|
|
20
|
+
},
|
|
21
|
+
exitWithCode(code) {
|
|
22
|
+
throw new ComponentExit(code);
|
|
23
|
+
},
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @param {import('../common/io.js').InputStreamHandler} handler
|
|
28
28
|
*/
|
|
29
29
|
export function _setStdin(handler) {
|
|
30
|
-
|
|
30
|
+
stdinStream.handler = handler;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* @param {import('../common/io.js').OutputStreamHandler} handler
|
|
34
34
|
*/
|
|
35
35
|
export function _setStderr(handler) {
|
|
36
|
-
|
|
36
|
+
stderrStream.handler = handler;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* @param {import('../common/io.js').OutputStreamHandler} handler
|
|
40
40
|
*/
|
|
41
41
|
export function _setStdout(handler) {
|
|
42
|
-
|
|
42
|
+
stdoutStream.handler = handler;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const stdinStream = new InputStream({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
blockingRead(_len) {
|
|
47
|
+
// TODO
|
|
48
|
+
},
|
|
49
|
+
subscribe() {
|
|
50
|
+
// TODO
|
|
51
|
+
},
|
|
52
|
+
[symbolDispose]() {
|
|
53
|
+
// TODO
|
|
54
|
+
},
|
|
55
55
|
});
|
|
56
56
|
let textDecoder = new TextDecoder();
|
|
57
57
|
const stdoutStream = new OutputStream({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
write(contents) {
|
|
59
|
+
if (contents[contents.length - 1] == 10) {
|
|
60
|
+
// console.log already appends a new line
|
|
61
|
+
contents = contents.subarray(0, contents.length - 1);
|
|
62
|
+
}
|
|
63
|
+
console.log(textDecoder.decode(contents));
|
|
64
|
+
},
|
|
65
|
+
blockingFlush() {},
|
|
66
|
+
[symbolDispose]() {},
|
|
67
67
|
});
|
|
68
68
|
const stderrStream = new OutputStream({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
write(contents) {
|
|
70
|
+
if (contents[contents.length - 1] == 10) {
|
|
71
|
+
// console.error already appends a new line
|
|
72
|
+
contents = contents.subarray(0, contents.length - 1);
|
|
73
|
+
}
|
|
74
|
+
console.error(textDecoder.decode(contents));
|
|
75
|
+
},
|
|
76
|
+
blockingFlush() {},
|
|
77
|
+
[symbolDispose]() {},
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
export const stdin = {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
InputStream,
|
|
82
|
+
getStdin() {
|
|
83
|
+
return stdinStream;
|
|
84
|
+
},
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
export const stdout = {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
OutputStream,
|
|
89
|
+
getStdout() {
|
|
90
|
+
return stdoutStream;
|
|
91
|
+
},
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
export const stderr = {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
OutputStream,
|
|
96
|
+
getStderr() {
|
|
97
|
+
return stderrStream;
|
|
98
|
+
},
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
class TerminalInput {}
|
|
@@ -106,30 +106,30 @@ const terminalStderrInstance = new TerminalOutput();
|
|
|
106
106
|
const terminalStdinInstance = new TerminalInput();
|
|
107
107
|
|
|
108
108
|
export const terminalInput = {
|
|
109
|
-
|
|
109
|
+
TerminalInput,
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
export const terminalOutput = {
|
|
113
|
-
|
|
113
|
+
TerminalOutput,
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
export const terminalStderr = {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
TerminalOutput,
|
|
118
|
+
getTerminalStderr() {
|
|
119
|
+
return terminalStderrInstance;
|
|
120
|
+
},
|
|
121
121
|
};
|
|
122
122
|
|
|
123
123
|
export const terminalStdin = {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
TerminalInput,
|
|
125
|
+
getTerminalStdin() {
|
|
126
|
+
return terminalStdinInstance;
|
|
127
|
+
},
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
export const terminalStdout = {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
TerminalOutput,
|
|
132
|
+
getTerminalStdout() {
|
|
133
|
+
return terminalStdoutInstance;
|
|
134
|
+
},
|
|
135
135
|
};
|
package/lib/browser/clocks.js
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
|
+
import { poll } from "./io.js";
|
|
2
|
+
const { Pollable } = poll;
|
|
3
|
+
|
|
1
4
|
export const monotonicClock = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
resolution() {
|
|
6
|
+
// usually we dont get sub-millisecond accuracy in the browser
|
|
7
|
+
// Note: is there a better way to determine this?
|
|
8
|
+
return 1e6;
|
|
9
|
+
},
|
|
10
|
+
now() {
|
|
11
|
+
// performance.now() is in milliseconds, but we want nanoseconds
|
|
12
|
+
return BigInt(Math.floor(performance.now() * 1e6));
|
|
13
|
+
},
|
|
14
|
+
subscribeInstant(instant) {
|
|
15
|
+
instant = BigInt(instant);
|
|
16
|
+
const now = monotonicClock.now();
|
|
17
|
+
if (instant <= now) {
|
|
18
|
+
return new Pollable(new Promise((resolve) => setTimeout(resolve, 0)));
|
|
19
|
+
}
|
|
20
|
+
return monotonicClock.subscribeDuration(instant - now);
|
|
21
|
+
},
|
|
22
|
+
subscribeDuration(duration) {
|
|
23
|
+
duration = BigInt(duration);
|
|
24
|
+
const ms = duration <= 0n ? 0 : Number(duration / 1_000_000n);
|
|
25
|
+
return new Pollable(new Promise((resolve) => setTimeout(resolve, ms)));
|
|
26
|
+
},
|
|
23
27
|
};
|
|
24
28
|
|
|
25
29
|
export const wallClock = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
now() {
|
|
31
|
+
let now = Date.now(); // in milliseconds
|
|
32
|
+
const seconds = BigInt(Math.floor(now / 1e3));
|
|
33
|
+
const nanoseconds = (now % 1e3) * 1e6;
|
|
34
|
+
return { seconds, nanoseconds };
|
|
35
|
+
},
|
|
36
|
+
resolution() {
|
|
37
|
+
return { seconds: 0n, nanoseconds: 1e6 };
|
|
38
|
+
},
|
|
35
39
|
};
|
package/lib/browser/config.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { _setCwd as fsSetCwd } from
|
|
1
|
+
import { _setCwd as fsSetCwd } from "./config.js";
|
|
2
2
|
|
|
3
3
|
let _env = [],
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
_args = [],
|
|
5
|
+
_cwd = "/";
|
|
6
6
|
|
|
7
7
|
export function _setEnv(envObj) {
|
|
8
|
-
|
|
8
|
+
_env = Object.entries(envObj);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function _setArgs(args) {
|
|
12
|
-
|
|
12
|
+
_args = args;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function _setCwd(cwd) {
|
|
16
|
-
|
|
16
|
+
fsSetCwd((_cwd = cwd));
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const environment = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
getEnvironment() {
|
|
21
|
+
return _env;
|
|
22
|
+
},
|
|
23
|
+
getArguments() {
|
|
24
|
+
return _args;
|
|
25
|
+
},
|
|
26
|
+
initialCwd() {
|
|
27
|
+
return _cwd;
|
|
28
|
+
},
|
|
29
29
|
};
|