@bytecodealliance/jco 1.8.1 → 1.10.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.
- package/README.md +1 -0
- package/lib/wasi_snapshot_preview1.command.wasm +0 -0
- package/lib/wasi_snapshot_preview1.reactor.wasm +0 -0
- package/obj/interfaces/local-wasm-tools-tools.d.ts +1 -0
- package/obj/interfaces/wasi-cli-terminal-input.d.ts +4 -0
- package/obj/interfaces/wasi-cli-terminal-output.d.ts +4 -0
- package/obj/interfaces/wasi-filesystem-types.d.ts +8 -0
- package/obj/interfaces/wasi-io-error.d.ts +4 -0
- package/obj/interfaces/wasi-io-streams.d.ts +8 -0
- package/obj/js-component-bindgen-component.core.wasm +0 -0
- package/obj/js-component-bindgen-component.core2.wasm +0 -0
- package/obj/js-component-bindgen-component.d.ts +16 -0
- package/obj/js-component-bindgen-component.js +546 -404
- package/obj/wasm-tools.core.wasm +0 -0
- package/obj/wasm-tools.core2.wasm +0 -0
- package/obj/wasm-tools.js +447 -390
- package/package.json +6 -6
- package/src/cmd/componentize.d.ts.map +1 -1
- package/src/cmd/componentize.js +1 -0
- package/src/cmd/opt.d.ts +7 -2
- package/src/cmd/opt.d.ts.map +1 -1
- package/src/cmd/opt.js +196 -82
- package/src/cmd/run.js +3 -3
- package/src/cmd/transpile.d.ts +15 -0
- package/src/cmd/transpile.d.ts.map +1 -1
- package/src/cmd/transpile.js +63 -0
- package/src/common.d.ts +2 -2
- package/src/common.d.ts.map +1 -1
- package/src/jco.js +26 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytecodealliance/jco",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "JavaScript tooling for working with WebAssembly Components",
|
|
5
5
|
"author": "Guy Bedford",
|
|
6
6
|
"bin": {
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
},
|
|
25
25
|
"type": "module",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@bytecodealliance/componentize-js": "^0.
|
|
27
|
+
"@bytecodealliance/componentize-js": "^0.17.0",
|
|
28
28
|
"@bytecodealliance/preview2-shim": "^0.17.1",
|
|
29
|
-
"binaryen": "^
|
|
29
|
+
"binaryen": "^122.0.0",
|
|
30
30
|
"chalk-template": "^1",
|
|
31
31
|
"commander": "^12",
|
|
32
32
|
"mkdirp": "^3",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"eslint": "^9.9.0",
|
|
41
41
|
"mime": "^4.0.4",
|
|
42
42
|
"mocha": "^10.7.0",
|
|
43
|
-
"puppeteer": "^
|
|
43
|
+
"puppeteer": "^24.0.1",
|
|
44
44
|
"typescript": "^5.5.4"
|
|
45
45
|
},
|
|
46
46
|
"repository": {
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"build:release": "cargo xtask build release",
|
|
63
63
|
"build:types:preview2-shim": "cargo xtask generate wasi-types",
|
|
64
64
|
"lint": "eslint -c eslintrc.cjs src/**/*.js packages/*/lib/**/*.js",
|
|
65
|
-
"test:lts": "mocha -u tdd test/test.js --timeout
|
|
66
|
-
"test": "node --stack-trace-limit=100 node_modules/mocha/bin/mocha.js -u tdd test/test.js --timeout
|
|
65
|
+
"test:lts": "mocha -u tdd test/test.js --timeout 240000",
|
|
66
|
+
"test": "node --experimental-wasm-jspi --stack-trace-limit=100 node_modules/mocha/bin/mocha.js -u tdd test/test.js --timeout 240000",
|
|
67
67
|
"prepublishOnly": "cargo xtask build release && npm run test"
|
|
68
68
|
},
|
|
69
69
|
"files": [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentize.d.ts","sourceRoot":"","sources":["componentize.js"],"names":[],"mappings":"AAIA,
|
|
1
|
+
{"version":3,"file":"componentize.d.ts","sourceRoot":"","sources":["componentize.js"],"names":[],"mappings":"AAIA,sEAkBC"}
|
package/src/cmd/componentize.js
CHANGED
|
@@ -10,6 +10,7 @@ export async function componentize (jsSource, opts) {
|
|
|
10
10
|
const source = await readFile(jsSource, 'utf8');
|
|
11
11
|
const { component } = await componentizeFn(source, {
|
|
12
12
|
enableAot: opts.aot,
|
|
13
|
+
wevalBin: opts.wevalBin,
|
|
13
14
|
sourceName: basename(jsSource),
|
|
14
15
|
witPath: resolve(opts.wit),
|
|
15
16
|
worldName: opts.worldName,
|
package/src/cmd/opt.d.ts
CHANGED
|
@@ -2,10 +2,15 @@ export function opt(componentPath: any, opts: any, program: any): Promise<void>;
|
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
4
|
* @param {Uint8Array} componentBytes
|
|
5
|
-
* @param {{ quiet: boolean, optArgs?: string[] }}
|
|
5
|
+
* @param {{ quiet: boolean, asyncify?: boolean, optArgs?: string[], noVerify?: boolean }} opts?
|
|
6
6
|
* @returns {Promise<{ component: Uint8Array, compressionInfo: { beforeBytes: number, afterBytes: number }[] >}
|
|
7
7
|
*/
|
|
8
|
-
export function optimizeComponent(componentBytes: Uint8Array, opts:
|
|
8
|
+
export function optimizeComponent(componentBytes: Uint8Array, opts: {
|
|
9
|
+
quiet: boolean;
|
|
10
|
+
asyncify?: boolean;
|
|
11
|
+
optArgs?: string[];
|
|
12
|
+
noVerify?: boolean;
|
|
13
|
+
}): Promise<{
|
|
9
14
|
component: Uint8Array;
|
|
10
15
|
compressionInfo: {
|
|
11
16
|
beforeBytes: number;
|
package/src/cmd/opt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opt.d.ts","sourceRoot":"","sources":["opt.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opt.d.ts","sourceRoot":"","sources":["opt.js"],"names":[],"mappings":"AAgBA,gFA2CC;AAgBD;;;;;GAKG;AACH,kDAJW,UAAU,QACV;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5E,OAAO,CAAC;IAAE,SAAS,EAAE,UAAU,CAAC;IAAC,eAAe,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAA,CAAE,CAkK7G"}
|
package/src/cmd/opt.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import { $init, tools } from
|
|
1
|
+
import { $init, tools } from "../../obj/wasm-tools.js";
|
|
2
2
|
const { metadataShow, print } = tools;
|
|
3
|
-
import { writeFile } from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import c from
|
|
6
|
-
import {
|
|
7
|
-
|
|
3
|
+
import { writeFile } from "fs/promises";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import c from "chalk-template";
|
|
6
|
+
import {
|
|
7
|
+
readFile,
|
|
8
|
+
sizeStr,
|
|
9
|
+
fixedDigitDisplay,
|
|
10
|
+
table,
|
|
11
|
+
spawnIOTmp,
|
|
12
|
+
setShowSpinner,
|
|
13
|
+
getShowSpinner,
|
|
14
|
+
} from "../common.js";
|
|
15
|
+
import ora from "#ora";
|
|
8
16
|
|
|
9
|
-
export async function opt
|
|
17
|
+
export async function opt(componentPath, opts, program) {
|
|
10
18
|
await $init;
|
|
11
|
-
const varIdx = program.parent.rawArgs.indexOf(
|
|
12
|
-
if (varIdx !== -1)
|
|
13
|
-
opts.optArgs = program.parent.rawArgs.slice(varIdx + 1);
|
|
19
|
+
const varIdx = program.parent.rawArgs.indexOf("--");
|
|
20
|
+
if (varIdx !== -1) opts.optArgs = program.parent.rawArgs.slice(varIdx + 1);
|
|
14
21
|
const componentBytes = await readFile(componentPath);
|
|
15
22
|
|
|
16
23
|
if (!opts.quiet) setShowSpinner(true);
|
|
@@ -19,128 +26,235 @@ export async function opt (componentPath, opts, program) {
|
|
|
19
26
|
|
|
20
27
|
await writeFile(opts.output, component);
|
|
21
28
|
|
|
22
|
-
let totalBeforeBytes = 0,
|
|
29
|
+
let totalBeforeBytes = 0,
|
|
30
|
+
totalAfterBytes = 0;
|
|
23
31
|
|
|
24
32
|
if (!opts.quiet)
|
|
25
33
|
console.log(c`
|
|
26
34
|
{bold Optimized WebAssembly Component Internal Core Modules:}
|
|
27
35
|
|
|
28
|
-
${table(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
${table(
|
|
37
|
+
[
|
|
38
|
+
...compressionInfo.map(({ beforeBytes, afterBytes }, i) => {
|
|
39
|
+
totalBeforeBytes += beforeBytes;
|
|
40
|
+
totalAfterBytes += afterBytes;
|
|
41
|
+
return [
|
|
42
|
+
` - Core Module ${i + 1}: `,
|
|
43
|
+
sizeStr(beforeBytes),
|
|
44
|
+
" -> ",
|
|
45
|
+
c`{cyan ${sizeStr(afterBytes)}} `,
|
|
46
|
+
`(${fixedDigitDisplay((afterBytes / beforeBytes) * 100, 2)}%)`,
|
|
47
|
+
];
|
|
48
|
+
}),
|
|
49
|
+
["", "", "", "", ""],
|
|
50
|
+
[
|
|
51
|
+
` = Total: `,
|
|
52
|
+
`${sizeStr(totalBeforeBytes)}`,
|
|
53
|
+
` => `,
|
|
54
|
+
c`{cyan ${sizeStr(totalAfterBytes)}} `,
|
|
55
|
+
`(${fixedDigitDisplay((totalAfterBytes / totalBeforeBytes) * 100, 2)}%)`,
|
|
56
|
+
],
|
|
57
|
+
],
|
|
58
|
+
[, , , , "right"]
|
|
59
|
+
)}`);
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @param {
|
|
50
|
-
* @
|
|
63
|
+
* Counts the byte length for the LEB128 encoding of a number.
|
|
64
|
+
* @param {number} val
|
|
65
|
+
* @returns {number}
|
|
66
|
+
*/
|
|
67
|
+
function byteLengthLEB128(val) {
|
|
68
|
+
let len = 0;
|
|
69
|
+
do {
|
|
70
|
+
val >>>= 7;
|
|
71
|
+
len++;
|
|
72
|
+
} while (val !== 0);
|
|
73
|
+
return len;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {Uint8Array} componentBytes
|
|
79
|
+
* @param {{ quiet: boolean, asyncify?: boolean, optArgs?: string[], noVerify?: boolean }} opts?
|
|
51
80
|
* @returns {Promise<{ component: Uint8Array, compressionInfo: { beforeBytes: number, afterBytes: number }[] >}
|
|
52
81
|
*/
|
|
53
|
-
export async function optimizeComponent
|
|
82
|
+
export async function optimizeComponent(componentBytes, opts) {
|
|
54
83
|
await $init;
|
|
55
84
|
const showSpinner = getShowSpinner();
|
|
56
85
|
let spinner;
|
|
57
86
|
try {
|
|
58
|
-
|
|
87
|
+
let componentMetadata = metadataShow(componentBytes);
|
|
88
|
+
componentMetadata.forEach((metadata, index) => {
|
|
89
|
+
// add index to the metadata object
|
|
90
|
+
metadata.index = index;
|
|
91
|
+
const size = metadata.range[1] - metadata.range[0];
|
|
92
|
+
// compute previous LEB128 encoding length
|
|
93
|
+
metadata.prevLEBLen = byteLengthLEB128(size);
|
|
94
|
+
});
|
|
95
|
+
const coreModules = componentMetadata
|
|
96
|
+
.filter(({ metaType }) => metaType.tag === "module");
|
|
59
97
|
|
|
98
|
+
// log number of core Wasm modules to be run with wasm-opt
|
|
60
99
|
let completed = 0;
|
|
61
|
-
const spinnerText = () =>
|
|
100
|
+
const spinnerText = () =>
|
|
101
|
+
c`{cyan ${completed} / ${coreModules.length}} Running Binaryen on WebAssembly Component Internal Core Modules \n`;
|
|
62
102
|
if (showSpinner) {
|
|
63
103
|
spinner = ora({
|
|
64
|
-
color:
|
|
65
|
-
spinner:
|
|
104
|
+
color: "cyan",
|
|
105
|
+
spinner: "bouncingBar",
|
|
66
106
|
}).start();
|
|
67
107
|
spinner.text = spinnerText();
|
|
68
108
|
}
|
|
69
109
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
110
|
+
// gather the options for wasm-opt. optionally, adding the asyncify flag
|
|
111
|
+
const args = opts?.optArgs ?
|
|
112
|
+
[...opts.optArgs] :
|
|
113
|
+
['-Oz', '--low-memory-unused', '--enable-bulk-memory', '--strip-debug'];
|
|
114
|
+
if (opts?.asyncify) args.push('--asyncify');
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
// process core Wasm modules with wasm-opt
|
|
118
|
+
await Promise.all(
|
|
119
|
+
coreModules.map(async (metadata) => {
|
|
120
|
+
if (metadata.metaType.tag === "module") {
|
|
121
|
+
// store the wasm-opt processed module in the metadata
|
|
122
|
+
metadata.optimized = await wasmOpt(
|
|
123
|
+
componentBytes.subarray(metadata.range[0], metadata.range[1]),
|
|
124
|
+
args);
|
|
125
|
+
|
|
126
|
+
// compute the size change, including the change to
|
|
127
|
+
// the LEB128 encoding of the size change
|
|
128
|
+
const prevModuleSize = metadata.range[1] - metadata.range[0];
|
|
129
|
+
const newModuleSize = metadata.optimized.byteLength;
|
|
130
|
+
metadata.newLEBLen = byteLengthLEB128(newModuleSize);
|
|
131
|
+
metadata.sizeChange = newModuleSize - prevModuleSize;
|
|
132
|
+
|
|
133
|
+
if (spinner) {
|
|
134
|
+
completed++;
|
|
135
|
+
spinner.text = spinnerText();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}));
|
|
139
|
+
|
|
140
|
+
// organize components in modules into tree parent and children
|
|
141
|
+
const nodes = componentMetadata.slice(1);
|
|
142
|
+
const getChildren = (parentIndex) => {
|
|
143
|
+
const children = [];
|
|
144
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
145
|
+
const metadata = nodes[i];
|
|
146
|
+
if (metadata.parentIndex === parentIndex) {
|
|
147
|
+
nodes.splice(i, 1); // remove from nodes
|
|
148
|
+
i--;
|
|
149
|
+
metadata.children = getChildren(metadata.index);
|
|
150
|
+
metadata.sizeChange = metadata.children
|
|
151
|
+
.reduce((total, {prevLEBLen, newLEBLen, sizeChange}) => {
|
|
152
|
+
return sizeChange ?
|
|
153
|
+
total + sizeChange + newLEBLen - prevLEBLen :
|
|
154
|
+
total;
|
|
155
|
+
},
|
|
156
|
+
metadata.sizeChange || 0);
|
|
157
|
+
const prevSize = metadata.range[1] - metadata.range[0];
|
|
158
|
+
metadata.newLEBLen = byteLengthLEB128(prevSize + metadata.sizeChange);
|
|
159
|
+
children.push(metadata);
|
|
160
|
+
}
|
|
75
161
|
}
|
|
76
|
-
return
|
|
77
|
-
}
|
|
162
|
+
return children;
|
|
163
|
+
};
|
|
164
|
+
const componentTree = getChildren(0);
|
|
78
165
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
166
|
+
// compute the total size change in the component binary
|
|
167
|
+
const sizeChange = componentTree
|
|
168
|
+
.reduce((total, {prevLEBLen, newLEBLen, sizeChange}) => {
|
|
169
|
+
return total + (sizeChange || 0) + newLEBLen - prevLEBLen;
|
|
170
|
+
}, 0);
|
|
84
171
|
|
|
85
|
-
|
|
86
|
-
|
|
172
|
+
let outComponentBytes = new Uint8Array(
|
|
173
|
+
componentBytes.byteLength + sizeChange);
|
|
174
|
+
let nextReadPos = 0, nextWritePos = 0;
|
|
87
175
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
176
|
+
const write = ({prevLEBLen, range, optimized, children, sizeChange}) => {
|
|
177
|
+
// write from the last read to the LEB byte start
|
|
178
|
+
outComponentBytes.set(
|
|
179
|
+
componentBytes.subarray(nextReadPos, range[0] - prevLEBLen),
|
|
180
|
+
nextWritePos
|
|
181
|
+
);
|
|
182
|
+
nextWritePos += range[0] - prevLEBLen - nextReadPos;
|
|
91
183
|
|
|
92
|
-
//
|
|
93
|
-
let val =
|
|
184
|
+
// write the new LEB bytes
|
|
185
|
+
let val = range[1] - range[0] + sizeChange;
|
|
94
186
|
do {
|
|
95
|
-
const byte = val &
|
|
187
|
+
const byte = val & 0x7f;
|
|
96
188
|
val >>>= 7;
|
|
97
189
|
outComponentBytes[nextWritePos++] = val === 0 ? byte : byte | 0x80;
|
|
98
190
|
} while (val !== 0);
|
|
99
191
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
192
|
+
if (optimized) {
|
|
193
|
+
// write the core module
|
|
194
|
+
outComponentBytes.set(optimized, nextWritePos);
|
|
195
|
+
nextReadPos = range[1];
|
|
196
|
+
nextWritePos += optimized.byteLength;
|
|
197
|
+
} else if (children.length > 0) {
|
|
198
|
+
// write child components / modules
|
|
199
|
+
nextReadPos = range[0];
|
|
200
|
+
children.forEach(write);
|
|
201
|
+
} else {
|
|
202
|
+
// write component
|
|
203
|
+
outComponentBytes.set(
|
|
204
|
+
componentBytes.subarray(range[0], range[1]),
|
|
205
|
+
nextWritePos
|
|
206
|
+
);
|
|
207
|
+
nextReadPos = range[1];
|
|
208
|
+
nextWritePos += range[1] - range[0];
|
|
209
|
+
}
|
|
210
|
+
};
|
|
106
211
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
nextReadPos += componentBytes.byteLength - nextReadPos;
|
|
212
|
+
// write each top-level component / module
|
|
213
|
+
componentTree.forEach(write);
|
|
110
214
|
|
|
111
|
-
|
|
215
|
+
// write remaining
|
|
216
|
+
outComponentBytes.set(
|
|
217
|
+
componentBytes.subarray(nextReadPos),
|
|
218
|
+
nextWritePos
|
|
219
|
+
);
|
|
112
220
|
|
|
113
221
|
// verify it still parses ok
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
222
|
+
if (!opts?.noVerify) {
|
|
223
|
+
try {
|
|
224
|
+
await print(outComponentBytes);
|
|
225
|
+
} catch (e) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Internal error performing optimization.\n${e.message}`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
118
230
|
}
|
|
119
231
|
|
|
120
232
|
return {
|
|
121
233
|
component: outComponentBytes,
|
|
122
|
-
compressionInfo: coreModules.map((
|
|
234
|
+
compressionInfo: coreModules.map(({range, optimized}) => ({
|
|
235
|
+
beforeBytes: range[1] - range[0],
|
|
236
|
+
afterBytes: optimized?.byteLength,
|
|
237
|
+
})),
|
|
123
238
|
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (spinner)
|
|
127
|
-
spinner.stop();
|
|
239
|
+
} finally {
|
|
240
|
+
if (spinner) spinner.stop();
|
|
128
241
|
}
|
|
129
242
|
}
|
|
130
243
|
|
|
131
244
|
/**
|
|
132
|
-
* @param {Uint8Array} source
|
|
245
|
+
* @param {Uint8Array} source
|
|
246
|
+
* @param {Array<string>} args
|
|
133
247
|
* @returns {Promise<Uint8Array>}
|
|
134
248
|
*/
|
|
135
|
-
async function wasmOpt(source, args
|
|
136
|
-
const wasmOptPath = fileURLToPath(
|
|
249
|
+
async function wasmOpt(source, args) {
|
|
250
|
+
const wasmOptPath = fileURLToPath(
|
|
251
|
+
import.meta.resolve("binaryen/bin/wasm-opt")
|
|
252
|
+
);
|
|
137
253
|
|
|
138
254
|
try {
|
|
139
|
-
return await spawnIOTmp(wasmOptPath, source, [
|
|
140
|
-
...args, '-o'
|
|
141
|
-
]);
|
|
255
|
+
return await spawnIOTmp(wasmOptPath, source, [...args, "-o"]);
|
|
142
256
|
} catch (e) {
|
|
143
|
-
if (e.toString().includes(
|
|
257
|
+
if (e.toString().includes("BasicBlock requested"))
|
|
144
258
|
return wasmOpt(source, args);
|
|
145
259
|
throw e;
|
|
146
260
|
}
|
package/src/cmd/run.js
CHANGED
|
@@ -40,8 +40,8 @@ export async function serve (componentPath, args, opts) {
|
|
|
40
40
|
return runComponent(componentPath, args, opts, `
|
|
41
41
|
import { HTTPServer } from '@bytecodealliance/preview2-shim/http';
|
|
42
42
|
const server = new HTTPServer(mod.incomingHandler);
|
|
43
|
-
${tryFindPort ? `
|
|
44
43
|
let port = ${port};
|
|
44
|
+
${tryFindPort ? `
|
|
45
45
|
while (true) {
|
|
46
46
|
try {
|
|
47
47
|
server.listen(port, ${JSON.stringify(host)});
|
|
@@ -52,8 +52,8 @@ export async function serve (componentPath, args, opts) {
|
|
|
52
52
|
}
|
|
53
53
|
port++;
|
|
54
54
|
}
|
|
55
|
-
` : `server.listen(
|
|
56
|
-
console.error(\`Server listening on
|
|
55
|
+
` : `server.listen(port, ${JSON.stringify(host)})`}
|
|
56
|
+
console.error(\`Server listening on port...\`);
|
|
57
57
|
`);
|
|
58
58
|
}
|
|
59
59
|
|
package/src/cmd/transpile.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function types(witPath: any, opts: any): Promise<void>;
|
|
2
|
+
export function guestTypes(witPath: any, opts: any): Promise<void>;
|
|
2
3
|
/**
|
|
3
4
|
* @param {string} witPath
|
|
4
5
|
* @param {{
|
|
@@ -6,8 +7,12 @@ export function types(witPath: any, opts: any): Promise<void>;
|
|
|
6
7
|
* worldName?: string,
|
|
7
8
|
* instantiation?: 'async' | 'sync',
|
|
8
9
|
* tlaCompat?: bool,
|
|
10
|
+
* asyncMode?: string,
|
|
11
|
+
* asyncImports?: string[],
|
|
12
|
+
* asyncExports?: string[],
|
|
9
13
|
* outDir?: string,
|
|
10
14
|
* features?: string[] | 'all',
|
|
15
|
+
* guest?: bool,
|
|
11
16
|
* }} opts
|
|
12
17
|
* @returns {Promise<{ [filename: string]: Uint8Array }>}
|
|
13
18
|
*/
|
|
@@ -16,8 +21,12 @@ export function typesComponent(witPath: string, opts: {
|
|
|
16
21
|
worldName?: string;
|
|
17
22
|
instantiation?: "async" | "sync";
|
|
18
23
|
tlaCompat?: bool;
|
|
24
|
+
asyncMode?: string;
|
|
25
|
+
asyncImports?: string[];
|
|
26
|
+
asyncExports?: string[];
|
|
19
27
|
outDir?: string;
|
|
20
28
|
features?: string[] | "all";
|
|
29
|
+
guest?: bool;
|
|
21
30
|
}): Promise<{
|
|
22
31
|
[filename: string]: Uint8Array;
|
|
23
32
|
}>;
|
|
@@ -30,6 +39,9 @@ export function transpile(componentPath: any, opts: any, program: any): Promise<
|
|
|
30
39
|
* instantiation?: 'async' | 'sync',
|
|
31
40
|
* importBindings?: 'js' | 'optimized' | 'hybrid' | 'direct-optimized',
|
|
32
41
|
* map?: Record<string, string>,
|
|
42
|
+
* asyncMode?: string,
|
|
43
|
+
* asyncImports?: string[],
|
|
44
|
+
* asyncExports?: string[],
|
|
33
45
|
* validLiftingOptimization?: bool,
|
|
34
46
|
* tracing?: bool,
|
|
35
47
|
* nodejsCompat?: bool,
|
|
@@ -51,6 +63,9 @@ export function transpileComponent(component: Uint8Array, opts?: {
|
|
|
51
63
|
instantiation?: "async" | "sync";
|
|
52
64
|
importBindings?: "js" | "optimized" | "hybrid" | "direct-optimized";
|
|
53
65
|
map?: Record<string, string>;
|
|
66
|
+
asyncMode?: string;
|
|
67
|
+
asyncImports?: string[];
|
|
68
|
+
asyncExports?: string[];
|
|
54
69
|
validLiftingOptimization?: bool;
|
|
55
70
|
tracing?: bool;
|
|
56
71
|
nodejsCompat?: bool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["transpile.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["transpile.js"],"names":[],"mappings":"AAgCA,8DAGC;AAED,mEAGC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wCAfW,MAAM,QACN;IACN,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC5B,KAAK,CAAC,EAAE,IAAI,CAAC;CACd,GACS,OAAO,CAAC;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,CAAC,CA8CvD;AAkBD,sFA8BC;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,8CAzBW,UAAU,SACV;IACN,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,GAAG,kBAAkB,CAAC;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,wBAAwB,CAAC,EAAE,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,EAAE,CAAC,EAAE,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,iBAAiB,CAAC,EAAE,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,sBAAsB,CAAC,EAAE,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GACS,OAAO,CAAC;IAAE,KAAK,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,EAAE,CAAA;CAAE,CAAC,CAgTnI"}
|
package/src/cmd/transpile.js
CHANGED
|
@@ -14,11 +14,32 @@ import { platform } from 'node:process';
|
|
|
14
14
|
|
|
15
15
|
const isWindows = platform === 'win32';
|
|
16
16
|
|
|
17
|
+
const ASYNC_WASI_IMPORTS = [
|
|
18
|
+
"wasi:io/poll#poll",
|
|
19
|
+
"wasi:io/poll#[method]pollable.block",
|
|
20
|
+
"wasi:io/streams#[method]input-stream.blocking-read",
|
|
21
|
+
"wasi:io/streams#[method]input-stream.blocking-skip",
|
|
22
|
+
"wasi:io/streams#[method]output-stream.blocking-flush",
|
|
23
|
+
"wasi:io/streams#[method]output-stream.blocking-write-and-flush",
|
|
24
|
+
"wasi:io/streams#[method]output-stream.blocking-write-zeroes-and-flush",
|
|
25
|
+
"wasi:io/streams#[method]output-stream.blocking-splice",
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const ASYNC_WASI_EXPORTS = [
|
|
29
|
+
"wasi:cli/run#run",
|
|
30
|
+
"wasi:http/incoming-handler#handle",
|
|
31
|
+
];
|
|
32
|
+
|
|
17
33
|
export async function types (witPath, opts) {
|
|
18
34
|
const files = await typesComponent(witPath, opts);
|
|
19
35
|
await writeFiles(files, opts.quiet ? false : 'Generated Type Files');
|
|
20
36
|
}
|
|
21
37
|
|
|
38
|
+
export async function guestTypes (witPath, opts) {
|
|
39
|
+
const files = await typesComponent(witPath, { ...opts, guest: true });
|
|
40
|
+
await writeFiles(files, opts.quiet ? false : 'Generated Guest Typescript Definition Files (.d.ts)');
|
|
41
|
+
}
|
|
42
|
+
|
|
22
43
|
/**
|
|
23
44
|
* @param {string} witPath
|
|
24
45
|
* @param {{
|
|
@@ -26,8 +47,12 @@ export async function types (witPath, opts) {
|
|
|
26
47
|
* worldName?: string,
|
|
27
48
|
* instantiation?: 'async' | 'sync',
|
|
28
49
|
* tlaCompat?: bool,
|
|
50
|
+
* asyncMode?: string,
|
|
51
|
+
* asyncImports?: string[],
|
|
52
|
+
* asyncExports?: string[],
|
|
29
53
|
* outDir?: string,
|
|
30
54
|
* features?: string[] | 'all',
|
|
55
|
+
* guest?: bool,
|
|
31
56
|
* }} opts
|
|
32
57
|
* @returns {Promise<{ [filename: string]: Uint8Array }>}
|
|
33
58
|
*/
|
|
@@ -51,12 +76,29 @@ export async function typesComponent (witPath, opts) {
|
|
|
51
76
|
features = { tag: 'list', val: opts.feature };
|
|
52
77
|
}
|
|
53
78
|
|
|
79
|
+
if (opts.asyncWasiImports)
|
|
80
|
+
opts.asyncImports = ASYNC_WASI_IMPORTS.concat(opts.asyncImports || []);
|
|
81
|
+
if (opts.asyncWasiExports)
|
|
82
|
+
opts.asyncExports = ASYNC_WASI_EXPORTS.concat(opts.asyncExports || []);
|
|
83
|
+
|
|
84
|
+
const asyncMode = !opts.asyncMode || opts.asyncMode === 'sync' ?
|
|
85
|
+
null :
|
|
86
|
+
{
|
|
87
|
+
tag: opts.asyncMode,
|
|
88
|
+
val: {
|
|
89
|
+
imports: opts.asyncImports || [],
|
|
90
|
+
exports: opts.asyncExports || [],
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
54
94
|
return Object.fromEntries(generateTypes(name, {
|
|
55
95
|
wit: { tag: 'path', val: (isWindows ? '//?/' : '') + resolve(witPath) },
|
|
56
96
|
instantiation,
|
|
57
97
|
tlaCompat: opts.tlaCompat ?? false,
|
|
58
98
|
world: opts.worldName,
|
|
59
99
|
features,
|
|
100
|
+
guest: opts.guest ?? false,
|
|
101
|
+
asyncMode,
|
|
60
102
|
}).map(([name, file]) => [`${outDir}${name}`, file]));
|
|
61
103
|
}
|
|
62
104
|
|
|
@@ -98,6 +140,12 @@ export async function transpile (componentPath, opts, program) {
|
|
|
98
140
|
opts.name = basename(componentPath.slice(0, -extname(componentPath).length || Infinity));
|
|
99
141
|
if (opts.map)
|
|
100
142
|
opts.map = Object.fromEntries(opts.map.map(mapping => mapping.split('=')));
|
|
143
|
+
|
|
144
|
+
if (opts.asyncWasiImports)
|
|
145
|
+
opts.asyncImports = ASYNC_WASI_IMPORTS.concat(opts.asyncImports || []);
|
|
146
|
+
if (opts.asyncWasiExports)
|
|
147
|
+
opts.asyncExports = ASYNC_WASI_EXPORTS.concat(opts.asyncExports || []);
|
|
148
|
+
|
|
101
149
|
const { files } = await transpileComponent(component, opts);
|
|
102
150
|
await writeFiles(files, opts.quiet ? false : 'Transpiled JS Component Files');
|
|
103
151
|
}
|
|
@@ -126,6 +174,9 @@ async function wasm2Js (source) {
|
|
|
126
174
|
* instantiation?: 'async' | 'sync',
|
|
127
175
|
* importBindings?: 'js' | 'optimized' | 'hybrid' | 'direct-optimized',
|
|
128
176
|
* map?: Record<string, string>,
|
|
177
|
+
* asyncMode?: string,
|
|
178
|
+
* asyncImports?: string[],
|
|
179
|
+
* asyncExports?: string[],
|
|
129
180
|
* validLiftingOptimization?: bool,
|
|
130
181
|
* tracing?: bool,
|
|
131
182
|
* nodejsCompat?: bool,
|
|
@@ -148,6 +199,7 @@ export async function transpileComponent (component, opts = {}) {
|
|
|
148
199
|
|
|
149
200
|
let spinner;
|
|
150
201
|
const showSpinner = getShowSpinner();
|
|
202
|
+
|
|
151
203
|
if (opts.optimize) {
|
|
152
204
|
if (showSpinner) setShowSpinner(true);
|
|
153
205
|
({ component } = await optimizeComponent(component, opts));
|
|
@@ -176,10 +228,21 @@ export async function transpileComponent (component, opts = {}) {
|
|
|
176
228
|
instantiation = { tag: 'async' };
|
|
177
229
|
}
|
|
178
230
|
|
|
231
|
+
const asyncMode = !opts.asyncMode || opts.asyncMode === 'sync' ?
|
|
232
|
+
null :
|
|
233
|
+
{
|
|
234
|
+
tag: opts.asyncMode,
|
|
235
|
+
val: {
|
|
236
|
+
imports: opts.asyncImports || [],
|
|
237
|
+
exports: opts.asyncExports || [],
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
179
241
|
let { files, imports, exports } = generate(component, {
|
|
180
242
|
name: opts.name ?? 'component',
|
|
181
243
|
map: Object.entries(opts.map ?? {}),
|
|
182
244
|
instantiation,
|
|
245
|
+
asyncMode,
|
|
183
246
|
importBindings: opts.importBindings ? { tag: opts.importBindings } : null,
|
|
184
247
|
validLiftingOptimization: opts.validLiftingOptimization ?? false,
|
|
185
248
|
tracing: opts.tracing ?? false,
|
package/src/common.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export function table(data: any, align?: any[]): string;
|
|
|
9
9
|
* The new directory is created using `fsPromises.mkdtemp()`.
|
|
10
10
|
*/
|
|
11
11
|
export function getTmpDir(): Promise<string>;
|
|
12
|
-
export function spawnIOTmp(cmd: any, input: any, args: any): Promise<Buffer
|
|
12
|
+
export function spawnIOTmp(cmd: any, input: any, args: any): Promise<Buffer<ArrayBufferLike>>;
|
|
13
13
|
export const isWindows: boolean;
|
|
14
14
|
export { readFileCli as readFile };
|
|
15
|
-
declare function readFileCli(file: any, encoding: any): Promise<Buffer
|
|
15
|
+
declare function readFileCli(file: any, encoding: any): Promise<Buffer<ArrayBufferLike>>;
|
|
16
16
|
//# sourceMappingURL=common.d.ts.map
|
package/src/common.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["common.js"],"names":[],"mappings":"AAWA,+CAEC;AACD,0CAIC;AAED,0CAOC;AAED,mEAaC;AAED,wDAcC;AAED;;;;GAIG;AACH,6CAEC;AAYD,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["common.js"],"names":[],"mappings":"AAWA,+CAEC;AACD,0CAIC;AAED,0CAOC;AAED,mEAaC;AAED,wDAcC;AAED;;;;GAIG;AACH,6CAEC;AAYD,8FA8BC;AArGD,gCAA8C;;AA6D9C,yFAOC"}
|