@bytecodealliance/preview2-shim 0.0.1
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 +39 -0
- package/http/error.js +11 -0
- package/http/make-request.js +29 -0
- package/package.json +28 -0
- package/types/index.d.ts +9 -0
- package/types/wasi-clocks.d.ts +11 -0
- package/types/wasi-default-clocks.d.ts +6 -0
- package/types/wasi-exit.d.ts +3 -0
- package/types/wasi-filesystem.d.ts +150 -0
- package/types/wasi-http.d.ts +55 -0
- package/types/wasi-io.d.ts +10 -0
- package/types/wasi-poll.d.ts +4 -0
- package/types/wasi-random.d.ts +3 -0
- package/types/wasi-stderr.d.ts +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# WASI Preview2 JavaScript Shim
|
|
2
|
+
|
|
3
|
+
_**Experimental**_ shim modules for the [WASI Preview2](https://github.com/bytecodealliance/preview2-prototyping) component interfaces in JS environments.
|
|
4
|
+
|
|
5
|
+
Currently supports Node.js and browser versions, but alternative implementations for any JS environments can be supported.
|
|
6
|
+
|
|
7
|
+
## Implementation Status
|
|
8
|
+
|
|
9
|
+
| Interface | Node.js |Browser |
|
|
10
|
+
| --------------- | ---------------------:|---------------------:|
|
|
11
|
+
| Command | :x: | :x: |
|
|
12
|
+
| Default Clocks | :heavy_check_mark: | :heavy_check_mark: |
|
|
13
|
+
| DNS | :x: | :x: |
|
|
14
|
+
| Environment | :x: | :x: |
|
|
15
|
+
| Exit | :heavy_check_mark: | :heavy_check_mark: |
|
|
16
|
+
| Filesystem | :x: | :x: |
|
|
17
|
+
| Http | Experimental | Experimental |
|
|
18
|
+
| IO | Partial | Partial |
|
|
19
|
+
| IP | :x: | :x: |
|
|
20
|
+
| Logging | :heavy_check_mark: | :heavy_check_mark: |
|
|
21
|
+
| Monotonic Clock | Missing `resolution` | Missing `resolution` |
|
|
22
|
+
| Net | :x: | :x: |
|
|
23
|
+
| Poll | :x: | :x: |
|
|
24
|
+
| Random | :heavy_check_mark: | :heavy_check_mark: |
|
|
25
|
+
| Stderr | :heavy_check_mark: | :heavy_check_mark: |
|
|
26
|
+
| TCP | :x: | :x: |
|
|
27
|
+
| Timezone | :x: | :x: |
|
|
28
|
+
| Wall Clock | Missing `resolution` | Missing `resolution` |
|
|
29
|
+
|
|
30
|
+
# License
|
|
31
|
+
|
|
32
|
+
This project is licensed under the Apache 2.0 license with the LLVM exception.
|
|
33
|
+
See [LICENSE](LICENSE) for more details.
|
|
34
|
+
|
|
35
|
+
### Contribution
|
|
36
|
+
|
|
37
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
38
|
+
for inclusion in this project by you, as defined in the Apache-2.0 license,
|
|
39
|
+
shall be licensed as above, without any additional terms or conditions.
|
package/http/error.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class UnexpectedError extends Error {
|
|
2
|
+
/** @type { import("../types/wasi-http").HttpErrorUnexpectedError } */
|
|
3
|
+
payload;
|
|
4
|
+
constructor(message = "unexpected-error") {
|
|
5
|
+
super(message);
|
|
6
|
+
this.payload = {
|
|
7
|
+
tag: "unexpected-error",
|
|
8
|
+
val: message,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { runAsWorker } from "synckit";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {import("../types/wasi-http").Request} req
|
|
5
|
+
* @returns {Promise<string>}
|
|
6
|
+
*/
|
|
7
|
+
async function makeRequest(req) {
|
|
8
|
+
try {
|
|
9
|
+
let headers = new Headers(req.headers);
|
|
10
|
+
const resp = await fetch(req.uri, {
|
|
11
|
+
method: req.method.toString(),
|
|
12
|
+
headers,
|
|
13
|
+
body: req.body.length > 0 ? req.body : undefined,
|
|
14
|
+
});
|
|
15
|
+
let arrayBuffer = await resp.arrayBuffer();
|
|
16
|
+
return JSON.stringify({
|
|
17
|
+
status: resp.status,
|
|
18
|
+
headers: resp.headers,
|
|
19
|
+
body:
|
|
20
|
+
arrayBuffer.byteLength > 0
|
|
21
|
+
? Buffer.from(arrayBuffer).toString("base64")
|
|
22
|
+
: undefined,
|
|
23
|
+
});
|
|
24
|
+
} catch (err) {
|
|
25
|
+
return err.message;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
runAsWorker(makeRequest);
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bytecodealliance/preview2-shim",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "WASI Preview2 shim in JavaScript environments",
|
|
5
|
+
"author": "Guy Bedford, Eduardo Rodrigues<16357187+eduardomourar@users.noreply.github.com>",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./*": {
|
|
9
|
+
"types": "./types/*.js",
|
|
10
|
+
"node": "./lib/nodejs/*.js",
|
|
11
|
+
"default": "./lib/browser/*.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "mocha -u tdd test/test.js --timeout 10000"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"index.js",
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"browser/",
|
|
21
|
+
"http/",
|
|
22
|
+
"nodejs/",
|
|
23
|
+
"types/"
|
|
24
|
+
],
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"mocha": "^10.2.0"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * as clocks from "./types/wasi-clocks";
|
|
2
|
+
export * as defaultClocks from "./types/wasi-default-clocks";
|
|
3
|
+
export * as exit from "./types/wasi-exit";
|
|
4
|
+
export * as filesystem from "./types/wasi-filesystem";
|
|
5
|
+
export * as io from "./types/wasi-io";
|
|
6
|
+
export * as logging from "./types/wasi-logging";
|
|
7
|
+
export * as poll from "./types/wasi-poll";
|
|
8
|
+
export * as random from "./types/wasi-random";
|
|
9
|
+
export * as stderr from "./types/wasi-stderr";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type MonotonicClock = number;
|
|
2
|
+
export type Instant = bigint;
|
|
3
|
+
export type WallClock = number;
|
|
4
|
+
export interface Datetime {
|
|
5
|
+
seconds: bigint,
|
|
6
|
+
nanoseconds: number,
|
|
7
|
+
}
|
|
8
|
+
export namespace WasiClocks {
|
|
9
|
+
export function monotonicClockNow(clock: MonotonicClock): Instant;
|
|
10
|
+
export function wallClockNow(clock: WallClock): Datetime;
|
|
11
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export type Descriptor = number;
|
|
2
|
+
export type Filesize = bigint;
|
|
3
|
+
export type InputStream = InputStream;
|
|
4
|
+
/**
|
|
5
|
+
* # Variants
|
|
6
|
+
*
|
|
7
|
+
* ## `"access"`
|
|
8
|
+
*
|
|
9
|
+
* ## `"again"`
|
|
10
|
+
*
|
|
11
|
+
* ## `"already"`
|
|
12
|
+
*
|
|
13
|
+
* ## `"badf"`
|
|
14
|
+
*
|
|
15
|
+
* ## `"busy"`
|
|
16
|
+
*
|
|
17
|
+
* ## `"deadlk"`
|
|
18
|
+
*
|
|
19
|
+
* ## `"dquot"`
|
|
20
|
+
*
|
|
21
|
+
* ## `"exist"`
|
|
22
|
+
*
|
|
23
|
+
* ## `"fbig"`
|
|
24
|
+
*
|
|
25
|
+
* ## `"ilseq"`
|
|
26
|
+
*
|
|
27
|
+
* ## `"inprogress"`
|
|
28
|
+
*
|
|
29
|
+
* ## `"intr"`
|
|
30
|
+
*
|
|
31
|
+
* ## `"inval"`
|
|
32
|
+
*
|
|
33
|
+
* ## `"io"`
|
|
34
|
+
*
|
|
35
|
+
* ## `"isdir"`
|
|
36
|
+
*
|
|
37
|
+
* ## `"loop"`
|
|
38
|
+
*
|
|
39
|
+
* ## `"mlink"`
|
|
40
|
+
*
|
|
41
|
+
* ## `"msgsize"`
|
|
42
|
+
*
|
|
43
|
+
* ## `"nametoolong"`
|
|
44
|
+
*
|
|
45
|
+
* ## `"nodev"`
|
|
46
|
+
*
|
|
47
|
+
* ## `"noent"`
|
|
48
|
+
*
|
|
49
|
+
* ## `"nolck"`
|
|
50
|
+
*
|
|
51
|
+
* ## `"nomem"`
|
|
52
|
+
*
|
|
53
|
+
* ## `"nospc"`
|
|
54
|
+
*
|
|
55
|
+
* ## `"nosys"`
|
|
56
|
+
*
|
|
57
|
+
* ## `"notdir"`
|
|
58
|
+
*
|
|
59
|
+
* ## `"notempty"`
|
|
60
|
+
*
|
|
61
|
+
* ## `"notrecoverable"`
|
|
62
|
+
*
|
|
63
|
+
* ## `"notsup"`
|
|
64
|
+
*
|
|
65
|
+
* ## `"notty"`
|
|
66
|
+
*
|
|
67
|
+
* ## `"nxio"`
|
|
68
|
+
*
|
|
69
|
+
* ## `"overflow"`
|
|
70
|
+
*
|
|
71
|
+
* ## `"perm"`
|
|
72
|
+
*
|
|
73
|
+
* ## `"pipe"`
|
|
74
|
+
*
|
|
75
|
+
* ## `"rofs"`
|
|
76
|
+
*
|
|
77
|
+
* ## `"spipe"`
|
|
78
|
+
*
|
|
79
|
+
* ## `"txtbsy"`
|
|
80
|
+
*
|
|
81
|
+
* ## `"xdev"`
|
|
82
|
+
*/
|
|
83
|
+
export type Errno = 'access' | 'again' | 'already' | 'badf' | 'busy' | 'deadlk' | 'dquot' | 'exist' | 'fbig' | 'ilseq' | 'inprogress' | 'intr' | 'inval' | 'io' | 'isdir' | 'loop' | 'mlink' | 'msgsize' | 'nametoolong' | 'nodev' | 'noent' | 'nolck' | 'nomem' | 'nospc' | 'nosys' | 'notdir' | 'notempty' | 'notrecoverable' | 'notsup' | 'notty' | 'nxio' | 'overflow' | 'perm' | 'pipe' | 'rofs' | 'spipe' | 'txtbsy' | 'xdev';
|
|
84
|
+
export type OutputStream = OutputStream;
|
|
85
|
+
export type DirEntryStream = number;
|
|
86
|
+
export type Device = bigint;
|
|
87
|
+
export type Inode = bigint;
|
|
88
|
+
/**
|
|
89
|
+
* # Variants
|
|
90
|
+
*
|
|
91
|
+
* ## `"unknown"`
|
|
92
|
+
*
|
|
93
|
+
* ## `"block-device"`
|
|
94
|
+
*
|
|
95
|
+
* ## `"character-device"`
|
|
96
|
+
*
|
|
97
|
+
* ## `"directory"`
|
|
98
|
+
*
|
|
99
|
+
* ## `"fifo"`
|
|
100
|
+
*
|
|
101
|
+
* ## `"symbolic-link"`
|
|
102
|
+
*
|
|
103
|
+
* ## `"regular-file"`
|
|
104
|
+
*
|
|
105
|
+
* ## `"socket"`
|
|
106
|
+
*/
|
|
107
|
+
export type DescriptorType = 'unknown' | 'block-device' | 'character-device' | 'directory' | 'fifo' | 'symbolic-link' | 'regular-file' | 'socket';
|
|
108
|
+
export type Linkcount = bigint;
|
|
109
|
+
export type Datetime = Datetime;
|
|
110
|
+
export interface DescriptorStat {
|
|
111
|
+
dev: Device,
|
|
112
|
+
ino: Inode,
|
|
113
|
+
type: DescriptorType,
|
|
114
|
+
nlink: Linkcount,
|
|
115
|
+
size: Filesize,
|
|
116
|
+
atim: Datetime,
|
|
117
|
+
mtim: Datetime,
|
|
118
|
+
ctim: Datetime,
|
|
119
|
+
}
|
|
120
|
+
export interface AtFlags {
|
|
121
|
+
symlinkFollow?: boolean,
|
|
122
|
+
}
|
|
123
|
+
export interface OFlags {
|
|
124
|
+
create?: boolean,
|
|
125
|
+
directory?: boolean,
|
|
126
|
+
excl?: boolean,
|
|
127
|
+
trunc?: boolean,
|
|
128
|
+
}
|
|
129
|
+
export interface DescriptorFlags {
|
|
130
|
+
read?: boolean,
|
|
131
|
+
write?: boolean,
|
|
132
|
+
dsync?: boolean,
|
|
133
|
+
nonblock?: boolean,
|
|
134
|
+
rsync?: boolean,
|
|
135
|
+
sync?: boolean,
|
|
136
|
+
}
|
|
137
|
+
export interface Mode {
|
|
138
|
+
readable?: boolean,
|
|
139
|
+
writeable?: boolean,
|
|
140
|
+
executable?: boolean,
|
|
141
|
+
}
|
|
142
|
+
export namespace WasiFilesystem {
|
|
143
|
+
export function readViaStream(fd: Descriptor, offset: Filesize): InputStream;
|
|
144
|
+
export function writeViaStream(fd: Descriptor, offset: Filesize): OutputStream;
|
|
145
|
+
export function appendViaStream(fd: Descriptor): OutputStream;
|
|
146
|
+
export function closeDirEntryStream(s: DirEntryStream): void;
|
|
147
|
+
export function stat(fd: Descriptor): DescriptorStat;
|
|
148
|
+
export function openAt(fd: Descriptor, atFlags: AtFlags, path: string, oFlags: OFlags, flags: DescriptorFlags, mode: Mode): Descriptor;
|
|
149
|
+
export function close(fd: Descriptor): void;
|
|
150
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Variants
|
|
3
|
+
*
|
|
4
|
+
* ## `"get"`
|
|
5
|
+
*
|
|
6
|
+
* ## `"post"`
|
|
7
|
+
*
|
|
8
|
+
* ## `"put"`
|
|
9
|
+
*
|
|
10
|
+
* ## `"delete"`
|
|
11
|
+
*
|
|
12
|
+
* ## `"patch"`
|
|
13
|
+
*
|
|
14
|
+
* ## `"head"`
|
|
15
|
+
*
|
|
16
|
+
* ## `"options"`
|
|
17
|
+
*/
|
|
18
|
+
export type Method = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options';
|
|
19
|
+
export type Uri = string;
|
|
20
|
+
export type Headers = [string, string][];
|
|
21
|
+
export type Params = [string, string][];
|
|
22
|
+
export type Body = Uint8Array;
|
|
23
|
+
export interface Request {
|
|
24
|
+
method: Method,
|
|
25
|
+
uri: Uri,
|
|
26
|
+
headers: Headers,
|
|
27
|
+
params: Params,
|
|
28
|
+
body?: Body,
|
|
29
|
+
}
|
|
30
|
+
export type HttpStatus = number;
|
|
31
|
+
export interface Response {
|
|
32
|
+
status: HttpStatus,
|
|
33
|
+
headers?: Headers,
|
|
34
|
+
body?: Body,
|
|
35
|
+
}
|
|
36
|
+
export type HttpError = HttpErrorInvalidUrl | HttpErrorTimeoutError | HttpErrorProtocolError | HttpErrorUnexpectedError;
|
|
37
|
+
export interface HttpErrorInvalidUrl {
|
|
38
|
+
tag: 'invalid-url',
|
|
39
|
+
val: string,
|
|
40
|
+
}
|
|
41
|
+
export interface HttpErrorTimeoutError {
|
|
42
|
+
tag: 'timeout-error',
|
|
43
|
+
val: string,
|
|
44
|
+
}
|
|
45
|
+
export interface HttpErrorProtocolError {
|
|
46
|
+
tag: 'protocol-error',
|
|
47
|
+
val: string,
|
|
48
|
+
}
|
|
49
|
+
export interface HttpErrorUnexpectedError {
|
|
50
|
+
tag: 'unexpected-error',
|
|
51
|
+
val: string,
|
|
52
|
+
}
|
|
53
|
+
export namespace WasiHttp {
|
|
54
|
+
export function send(req: Request): Response;
|
|
55
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type InputStream = number;
|
|
2
|
+
export interface StreamError {
|
|
3
|
+
}
|
|
4
|
+
export type OutputStream = number;
|
|
5
|
+
export namespace WasiIo {
|
|
6
|
+
export function read(src: InputStream, len: bigint): [Uint8Array | ArrayBuffer, boolean];
|
|
7
|
+
export function write(dst: OutputStream, buf: Uint8Array): bigint;
|
|
8
|
+
export function dropInputStream(f: InputStream): void;
|
|
9
|
+
export function dropOutputStream(f: OutputStream): void;
|
|
10
|
+
}
|