@bytecodealliance/jco 1.11.3-rc.1 → 1.12.0-rc.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/obj/js-component-bindgen-component.core.wasm +0 -0
- package/obj/js-component-bindgen-component.js +53 -53
- package/obj/wasm-tools.js +53 -53
- package/package.json +3 -3
- package/src/cmd/componentize.js +13 -0
- package/src/cmd/transpile.js +9 -171
- package/src/cmd/types.d.ts +33 -0
- package/src/cmd/types.js +147 -0
- package/src/common.d.ts +3 -0
- package/src/common.d.ts.map +1 -1
- package/src/common.js +41 -3
- package/src/jco.js +20 -2
|
Binary file
|
|
@@ -21,44 +21,30 @@ const { InputStream,
|
|
|
21
21
|
OutputStream } = streams;
|
|
22
22
|
const { getRandomBytes } = random;
|
|
23
23
|
|
|
24
|
-
const base64Compile = str => WebAssembly.compile(typeof Buffer !== 'undefined' ? Buffer.from(str, 'base64') : Uint8Array.from(atob(str), b => b.charCodeAt(0)));
|
|
25
|
-
|
|
26
|
-
class ComponentError extends Error {
|
|
27
|
-
constructor (value) {
|
|
28
|
-
const enumerable = typeof value !== 'string';
|
|
29
|
-
super(enumerable ? `${String(value)} (see error.payload)` : value);
|
|
30
|
-
Object.defineProperty(this, 'payload', { value, enumerable });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let curResourceBorrows = [];
|
|
35
|
-
|
|
36
24
|
let dv = new DataView(new ArrayBuffer());
|
|
37
25
|
const dataView = mem => dv.buffer === mem.buffer ? dv : dv = new DataView(mem.buffer);
|
|
38
26
|
|
|
39
|
-
const
|
|
40
|
-
let _fs;
|
|
41
|
-
async function fetchCompile (url) {
|
|
42
|
-
if (isNode) {
|
|
43
|
-
_fs = _fs || await import('node:fs/promises');
|
|
44
|
-
return WebAssembly.compile(await _fs.readFile(url));
|
|
45
|
-
}
|
|
46
|
-
return fetch(url).then(WebAssembly.compileStreaming);
|
|
47
|
-
}
|
|
27
|
+
const toUint64 = val => BigInt.asUintN(64, BigInt(val));
|
|
48
28
|
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
if (e instanceof Error) throw e;
|
|
52
|
-
return e;
|
|
29
|
+
function toUint32(val) {
|
|
30
|
+
return val >>> 0;
|
|
53
31
|
}
|
|
54
32
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const instantiateCore = WebAssembly.instantiate;
|
|
33
|
+
const utf8Decoder = new TextDecoder();
|
|
58
34
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
35
|
+
const utf8Encoder = new TextEncoder();
|
|
36
|
+
let utf8EncodedLen = 0;
|
|
37
|
+
function utf8Encode(s, realloc, memory) {
|
|
38
|
+
if (typeof s !== 'string') throw new TypeError('expected a string');
|
|
39
|
+
if (s.length === 0) {
|
|
40
|
+
utf8EncodedLen = 0;
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
let buf = utf8Encoder.encode(s);
|
|
44
|
+
let ptr = realloc(0, 0, 1, buf.length);
|
|
45
|
+
new Uint8Array(memory.buffer).set(buf, ptr);
|
|
46
|
+
utf8EncodedLen = buf.length;
|
|
47
|
+
return ptr;
|
|
62
48
|
}
|
|
63
49
|
|
|
64
50
|
const T_FLAG = 1 << 30;
|
|
@@ -87,6 +73,25 @@ function rscTableRemove (table, handle) {
|
|
|
87
73
|
return { rep, scope, own };
|
|
88
74
|
}
|
|
89
75
|
|
|
76
|
+
let curResourceBorrows = [];
|
|
77
|
+
|
|
78
|
+
const _debugLog = (...args) => {
|
|
79
|
+
if (!globalThis?.process?.env?.JCO_DEBUG) { return; }
|
|
80
|
+
console.debug(...args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const base64Compile = str => WebAssembly.compile(typeof Buffer !== 'undefined' ? Buffer.from(str, 'base64') : Uint8Array.from(atob(str), b => b.charCodeAt(0)));
|
|
84
|
+
|
|
85
|
+
const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
|
|
86
|
+
let _fs;
|
|
87
|
+
async function fetchCompile (url) {
|
|
88
|
+
if (isNode) {
|
|
89
|
+
_fs = _fs || await import('node:fs/promises');
|
|
90
|
+
return WebAssembly.compile(await _fs.readFile(url));
|
|
91
|
+
}
|
|
92
|
+
return fetch(url).then(WebAssembly.compileStreaming);
|
|
93
|
+
}
|
|
94
|
+
|
|
90
95
|
const symbolCabiDispose = Symbol.for('cabiDispose');
|
|
91
96
|
|
|
92
97
|
const symbolRscHandle = Symbol('handle');
|
|
@@ -95,34 +100,29 @@ const symbolRscRep = Symbol.for('cabiRep');
|
|
|
95
100
|
|
|
96
101
|
const symbolDispose = Symbol.dispose || Symbol.for('dispose');
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
throw new TypeError('Wasm uninitialized use `await $init` first');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const toUint64 = val => BigInt.asUintN(64, BigInt(val));
|
|
103
|
+
const handleTables = [];
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
class ComponentError extends Error {
|
|
106
|
+
constructor (value) {
|
|
107
|
+
const enumerable = typeof value !== 'string';
|
|
108
|
+
super(enumerable ? `${String(value)} (see error.payload)` : value);
|
|
109
|
+
Object.defineProperty(this, 'payload', { value, enumerable });
|
|
110
|
+
}
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
|
|
113
|
+
function getErrorPayload(e) {
|
|
114
|
+
if (e && hasOwnProperty.call(e, 'payload')) return e.payload;
|
|
115
|
+
if (e instanceof Error) throw e;
|
|
116
|
+
return e;
|
|
117
|
+
}
|
|
109
118
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
function utf8Encode(s, realloc, memory) {
|
|
113
|
-
if (typeof s !== 'string') throw new TypeError('expected a string');
|
|
114
|
-
if (s.length === 0) {
|
|
115
|
-
utf8EncodedLen = 0;
|
|
116
|
-
return 1;
|
|
117
|
-
}
|
|
118
|
-
let buf = utf8Encoder.encode(s);
|
|
119
|
-
let ptr = realloc(0, 0, 1, buf.length);
|
|
120
|
-
new Uint8Array(memory.buffer).set(buf, ptr);
|
|
121
|
-
utf8EncodedLen = buf.length;
|
|
122
|
-
return ptr;
|
|
119
|
+
function throwUninitialized() {
|
|
120
|
+
throw new TypeError('Wasm uninitialized use `await $init` first');
|
|
123
121
|
}
|
|
124
122
|
|
|
125
|
-
const
|
|
123
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
124
|
+
|
|
125
|
+
const instantiateCore = WebAssembly.instantiate;
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
let exports0;
|
package/obj/wasm-tools.js
CHANGED
|
@@ -21,44 +21,30 @@ const { InputStream,
|
|
|
21
21
|
OutputStream } = streams;
|
|
22
22
|
const { getRandomBytes } = random;
|
|
23
23
|
|
|
24
|
-
const base64Compile = str => WebAssembly.compile(typeof Buffer !== 'undefined' ? Buffer.from(str, 'base64') : Uint8Array.from(atob(str), b => b.charCodeAt(0)));
|
|
25
|
-
|
|
26
|
-
class ComponentError extends Error {
|
|
27
|
-
constructor (value) {
|
|
28
|
-
const enumerable = typeof value !== 'string';
|
|
29
|
-
super(enumerable ? `${String(value)} (see error.payload)` : value);
|
|
30
|
-
Object.defineProperty(this, 'payload', { value, enumerable });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let curResourceBorrows = [];
|
|
35
|
-
|
|
36
24
|
let dv = new DataView(new ArrayBuffer());
|
|
37
25
|
const dataView = mem => dv.buffer === mem.buffer ? dv : dv = new DataView(mem.buffer);
|
|
38
26
|
|
|
39
|
-
const
|
|
40
|
-
let _fs;
|
|
41
|
-
async function fetchCompile (url) {
|
|
42
|
-
if (isNode) {
|
|
43
|
-
_fs = _fs || await import('node:fs/promises');
|
|
44
|
-
return WebAssembly.compile(await _fs.readFile(url));
|
|
45
|
-
}
|
|
46
|
-
return fetch(url).then(WebAssembly.compileStreaming);
|
|
47
|
-
}
|
|
27
|
+
const toUint64 = val => BigInt.asUintN(64, BigInt(val));
|
|
48
28
|
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
if (e instanceof Error) throw e;
|
|
52
|
-
return e;
|
|
29
|
+
function toUint32(val) {
|
|
30
|
+
return val >>> 0;
|
|
53
31
|
}
|
|
54
32
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const instantiateCore = WebAssembly.instantiate;
|
|
33
|
+
const utf8Decoder = new TextDecoder();
|
|
58
34
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
35
|
+
const utf8Encoder = new TextEncoder();
|
|
36
|
+
let utf8EncodedLen = 0;
|
|
37
|
+
function utf8Encode(s, realloc, memory) {
|
|
38
|
+
if (typeof s !== 'string') throw new TypeError('expected a string');
|
|
39
|
+
if (s.length === 0) {
|
|
40
|
+
utf8EncodedLen = 0;
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
let buf = utf8Encoder.encode(s);
|
|
44
|
+
let ptr = realloc(0, 0, 1, buf.length);
|
|
45
|
+
new Uint8Array(memory.buffer).set(buf, ptr);
|
|
46
|
+
utf8EncodedLen = buf.length;
|
|
47
|
+
return ptr;
|
|
62
48
|
}
|
|
63
49
|
|
|
64
50
|
const T_FLAG = 1 << 30;
|
|
@@ -87,6 +73,25 @@ function rscTableRemove (table, handle) {
|
|
|
87
73
|
return { rep, scope, own };
|
|
88
74
|
}
|
|
89
75
|
|
|
76
|
+
let curResourceBorrows = [];
|
|
77
|
+
|
|
78
|
+
const _debugLog = (...args) => {
|
|
79
|
+
if (!globalThis?.process?.env?.JCO_DEBUG) { return; }
|
|
80
|
+
console.debug(...args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const base64Compile = str => WebAssembly.compile(typeof Buffer !== 'undefined' ? Buffer.from(str, 'base64') : Uint8Array.from(atob(str), b => b.charCodeAt(0)));
|
|
84
|
+
|
|
85
|
+
const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
|
|
86
|
+
let _fs;
|
|
87
|
+
async function fetchCompile (url) {
|
|
88
|
+
if (isNode) {
|
|
89
|
+
_fs = _fs || await import('node:fs/promises');
|
|
90
|
+
return WebAssembly.compile(await _fs.readFile(url));
|
|
91
|
+
}
|
|
92
|
+
return fetch(url).then(WebAssembly.compileStreaming);
|
|
93
|
+
}
|
|
94
|
+
|
|
90
95
|
const symbolCabiDispose = Symbol.for('cabiDispose');
|
|
91
96
|
|
|
92
97
|
const symbolRscHandle = Symbol('handle');
|
|
@@ -95,34 +100,29 @@ const symbolRscRep = Symbol.for('cabiRep');
|
|
|
95
100
|
|
|
96
101
|
const symbolDispose = Symbol.dispose || Symbol.for('dispose');
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
throw new TypeError('Wasm uninitialized use `await $init` first');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const toUint64 = val => BigInt.asUintN(64, BigInt(val));
|
|
103
|
+
const handleTables = [];
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
class ComponentError extends Error {
|
|
106
|
+
constructor (value) {
|
|
107
|
+
const enumerable = typeof value !== 'string';
|
|
108
|
+
super(enumerable ? `${String(value)} (see error.payload)` : value);
|
|
109
|
+
Object.defineProperty(this, 'payload', { value, enumerable });
|
|
110
|
+
}
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
|
|
113
|
+
function getErrorPayload(e) {
|
|
114
|
+
if (e && hasOwnProperty.call(e, 'payload')) return e.payload;
|
|
115
|
+
if (e instanceof Error) throw e;
|
|
116
|
+
return e;
|
|
117
|
+
}
|
|
109
118
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
function utf8Encode(s, realloc, memory) {
|
|
113
|
-
if (typeof s !== 'string') throw new TypeError('expected a string');
|
|
114
|
-
if (s.length === 0) {
|
|
115
|
-
utf8EncodedLen = 0;
|
|
116
|
-
return 1;
|
|
117
|
-
}
|
|
118
|
-
let buf = utf8Encoder.encode(s);
|
|
119
|
-
let ptr = realloc(0, 0, 1, buf.length);
|
|
120
|
-
new Uint8Array(memory.buffer).set(buf, ptr);
|
|
121
|
-
utf8EncodedLen = buf.length;
|
|
122
|
-
return ptr;
|
|
119
|
+
function throwUninitialized() {
|
|
120
|
+
throw new TypeError('Wasm uninitialized use `await $init` first');
|
|
123
121
|
}
|
|
124
122
|
|
|
125
|
-
const
|
|
123
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
124
|
+
|
|
125
|
+
const instantiateCore = WebAssembly.instantiate;
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
let exports0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytecodealliance/jco",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0-rc.1",
|
|
4
4
|
"description": "JavaScript tooling for working with WebAssembly Components",
|
|
5
5
|
"homepage": "https://github.com/bytecodealliance/jco#readme",
|
|
6
6
|
"author": "Guy Bedford",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"prepack": "cargo xtask build release"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@bytecodealliance/componentize-js": "^0.
|
|
69
|
+
"@bytecodealliance/componentize-js": "^0.18.3",
|
|
70
70
|
"@bytecodealliance/preview2-shim": "^0.17.2",
|
|
71
71
|
"binaryen": "^123.0.0",
|
|
72
72
|
"chalk-template": "^1",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"puppeteer": "^24.0.1",
|
|
91
91
|
"semver": "^7.7.1",
|
|
92
92
|
"smol-toml": "^1.3.1",
|
|
93
|
-
"typescript": "^5.
|
|
93
|
+
"typescript": "^5.8.3",
|
|
94
94
|
"vitest": "^3.0.7"
|
|
95
95
|
}
|
|
96
96
|
}
|
package/src/cmd/componentize.js
CHANGED
|
@@ -28,7 +28,20 @@ export async function componentize(jsSource, opts) {
|
|
|
28
28
|
enableFeatures: opts.enable,
|
|
29
29
|
preview2Adapter: opts.preview2Adapter,
|
|
30
30
|
debugBuild: opts.debugStarlingmonkeyBuild,
|
|
31
|
+
debug: {
|
|
32
|
+
bindings: opts.debugBindings,
|
|
33
|
+
bindingsDir: opts.debugBindingsDir,
|
|
34
|
+
binary: opts.debugBinary,
|
|
35
|
+
binaryPath: opts.debugBinaryPath,
|
|
36
|
+
enableWizerLogging: opts.debugEnableWizerLogging,
|
|
37
|
+
},
|
|
31
38
|
});
|
|
39
|
+
if (result.debug) {
|
|
40
|
+
console.error(
|
|
41
|
+
c`{cyan DEBUG} Debug output\n${JSON.stringify(debug, null, 2)}\n`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
32
45
|
component = result.component;
|
|
33
46
|
} catch (err) {
|
|
34
47
|
// Detect package resolution issues that usually mean a misconfigured "witPath"
|
package/src/cmd/transpile.js
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
import { platform } from 'node:process';
|
|
2
|
-
import {
|
|
3
|
-
import { mkdir } from 'node:fs/promises';
|
|
4
|
-
import { dirname, extname, basename, resolve } from 'node:path';
|
|
2
|
+
import { extname, basename, resolve } from 'node:path';
|
|
5
3
|
|
|
6
4
|
import c from 'chalk-template';
|
|
7
5
|
import { minify } from 'terser';
|
|
8
6
|
import { fileURLToPath } from 'url';
|
|
9
7
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
generateTypes,
|
|
14
|
-
} from '../../obj/js-component-bindgen-component.js';
|
|
8
|
+
import { optimizeComponent } from './opt.js';
|
|
9
|
+
|
|
10
|
+
import { $init, generate } from '../../obj/js-component-bindgen-component.js';
|
|
15
11
|
import {
|
|
16
12
|
readFile,
|
|
17
|
-
sizeStr,
|
|
18
|
-
table,
|
|
19
13
|
spawnIOTmp,
|
|
20
14
|
setShowSpinner,
|
|
21
15
|
getShowSpinner,
|
|
16
|
+
writeFiles,
|
|
17
|
+
ASYNC_WASI_IMPORTS,
|
|
18
|
+
ASYNC_WASI_EXPORTS,
|
|
22
19
|
} from '../common.js';
|
|
23
|
-
import { optimizeComponent } from './opt.js';
|
|
24
20
|
import { $init as wasmToolsInit, tools } from '../../obj/wasm-tools.js';
|
|
25
21
|
const { componentEmbed, componentNew } = tools;
|
|
26
22
|
|
|
@@ -28,166 +24,8 @@ import ora from '#ora';
|
|
|
28
24
|
|
|
29
25
|
const isWindows = platform === 'win32';
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'wasi:io/poll#[method]pollable.block',
|
|
34
|
-
'wasi:io/streams#[method]input-stream.blocking-read',
|
|
35
|
-
'wasi:io/streams#[method]input-stream.blocking-skip',
|
|
36
|
-
'wasi:io/streams#[method]output-stream.blocking-flush',
|
|
37
|
-
'wasi:io/streams#[method]output-stream.blocking-write-and-flush',
|
|
38
|
-
'wasi:io/streams#[method]output-stream.blocking-write-zeroes-and-flush',
|
|
39
|
-
'wasi:io/streams#[method]output-stream.blocking-splice',
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
const ASYNC_WASI_EXPORTS = [
|
|
43
|
-
'wasi:cli/run#run',
|
|
44
|
-
'wasi:http/incoming-handler#handle',
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
export async function types(witPath, opts) {
|
|
48
|
-
const files = await typesComponent(witPath, opts);
|
|
49
|
-
await writeFiles(files, opts.quiet ? false : 'Generated Type Files');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export async function guestTypes(witPath, opts) {
|
|
53
|
-
const files = await typesComponent(witPath, { ...opts, guest: true });
|
|
54
|
-
await writeFiles(
|
|
55
|
-
files,
|
|
56
|
-
opts.quiet
|
|
57
|
-
? false
|
|
58
|
-
: 'Generated Guest Typescript Definition Files (.d.ts)'
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @param {string} witPath
|
|
64
|
-
* @param {{
|
|
65
|
-
* name?: string,
|
|
66
|
-
* worldName?: string,
|
|
67
|
-
* instantiation?: 'async' | 'sync',
|
|
68
|
-
* tlaCompat?: bool,
|
|
69
|
-
* asyncMode?: string,
|
|
70
|
-
* asyncImports?: string[],
|
|
71
|
-
* asyncExports?: string[],
|
|
72
|
-
* outDir?: string,
|
|
73
|
-
* allFeatures?: bool,
|
|
74
|
-
* feature?: string[] | 'all', // backwards compat
|
|
75
|
-
* features?: string[] | 'all',
|
|
76
|
-
* asyncWasiImports?: string[],
|
|
77
|
-
* asyncWasiExports?: string[],
|
|
78
|
-
* guest?: bool,
|
|
79
|
-
* }} opts
|
|
80
|
-
* @returns {Promise<{ [filename: string]: Uint8Array }>}
|
|
81
|
-
*/
|
|
82
|
-
export async function typesComponent(witPath, opts) {
|
|
83
|
-
await $init;
|
|
84
|
-
const name =
|
|
85
|
-
opts.name ||
|
|
86
|
-
(opts.worldName
|
|
87
|
-
? opts.worldName.split(':').pop().split('/').pop()
|
|
88
|
-
: basename(witPath.slice(0, -extname(witPath).length || Infinity)));
|
|
89
|
-
let instantiation;
|
|
90
|
-
if (opts.instantiation) {
|
|
91
|
-
instantiation = { tag: opts.instantiation };
|
|
92
|
-
}
|
|
93
|
-
let outDir = (opts.outDir ?? '').replace(/\\/g, '/');
|
|
94
|
-
if (!outDir.endsWith('/') && outDir !== '') {
|
|
95
|
-
outDir += '/';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
let features = null;
|
|
99
|
-
if (opts.allFeatures) {
|
|
100
|
-
features = { tag: 'all' };
|
|
101
|
-
} else if (Array.isArray(opts.feature)) {
|
|
102
|
-
features = { tag: 'list', val: opts.feature };
|
|
103
|
-
} else if (Array.isArray(opts.features)) {
|
|
104
|
-
features = { tag: 'list', val: opts.features };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (opts.asyncWasiImports) {
|
|
108
|
-
opts.asyncImports = ASYNC_WASI_IMPORTS.concat(opts.asyncImports || []);
|
|
109
|
-
}
|
|
110
|
-
if (opts.asyncWasiExports) {
|
|
111
|
-
opts.asyncExports = ASYNC_WASI_EXPORTS.concat(opts.asyncExports || []);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const asyncMode =
|
|
115
|
-
!opts.asyncMode || opts.asyncMode === 'sync'
|
|
116
|
-
? null
|
|
117
|
-
: {
|
|
118
|
-
tag: opts.asyncMode,
|
|
119
|
-
val: {
|
|
120
|
-
imports: opts.asyncImports || [],
|
|
121
|
-
exports: opts.asyncExports || [],
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
let types;
|
|
126
|
-
const absWitPath = resolve(witPath);
|
|
127
|
-
try {
|
|
128
|
-
types = generateTypes(name, {
|
|
129
|
-
wit: { tag: 'path', val: (isWindows ? '//?/' : '') + absWitPath },
|
|
130
|
-
instantiation,
|
|
131
|
-
tlaCompat: opts.tlaCompat ?? false,
|
|
132
|
-
world: opts.worldName,
|
|
133
|
-
features,
|
|
134
|
-
guest: opts.guest ?? false,
|
|
135
|
-
asyncMode,
|
|
136
|
-
}).map(([name, file]) => [`${outDir}${name}`, file]);
|
|
137
|
-
} catch (err) {
|
|
138
|
-
if (err.toString().includes('does not match previous package name')) {
|
|
139
|
-
const hint = await printWITLayoutHint(absWitPath);
|
|
140
|
-
if (err.message) {
|
|
141
|
-
err.message += `\n${hint}`;
|
|
142
|
-
}
|
|
143
|
-
throw err;
|
|
144
|
-
}
|
|
145
|
-
throw err;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return Object.fromEntries(types);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Print a hint about WIT folder layout
|
|
153
|
-
*
|
|
154
|
-
* @param {(string, any) => void} consoleFn
|
|
155
|
-
*/
|
|
156
|
-
async function printWITLayoutHint(witPath) {
|
|
157
|
-
const pathMeta = await stat(witPath);
|
|
158
|
-
let output = '\n';
|
|
159
|
-
if (!pathMeta.isFile() && !pathMeta.isDirectory()) {
|
|
160
|
-
output += c`{yellow.bold warning} The supplited WIT path [${witPath}] is neither a file or directory.\n`;
|
|
161
|
-
return output;
|
|
162
|
-
}
|
|
163
|
-
const ftype = pathMeta.isDirectory() ? 'directory' : 'file';
|
|
164
|
-
output += c`{yellow.bold warning} Your WIT ${ftype} [${witPath}] may be laid out incorrectly\n`;
|
|
165
|
-
output += c`{yellow.bold warning} Keep in mind the following rules:\n`;
|
|
166
|
-
output += c`{yellow.bold warning} - Top level WIT files are in the same package (i.e. "ns:pkg" in "wit/*.wit")\n`;
|
|
167
|
-
output += c`{yellow.bold warning} - All package dependencies should be in "wit/deps" (i.e. "some:dep" in "wit/deps/some-dep.wit"\n`;
|
|
168
|
-
return output;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async function writeFiles(files, summaryTitle) {
|
|
172
|
-
await Promise.all(
|
|
173
|
-
Object.entries(files).map(async ([name, file]) => {
|
|
174
|
-
await mkdir(dirname(name), { recursive: true });
|
|
175
|
-
await writeFile(name, file);
|
|
176
|
-
})
|
|
177
|
-
);
|
|
178
|
-
if (!summaryTitle) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
console.log(c`
|
|
182
|
-
{bold ${summaryTitle}:}
|
|
183
|
-
|
|
184
|
-
${table(
|
|
185
|
-
Object.entries(files).map(([name, source]) => [
|
|
186
|
-
c` - {italic ${name}} `,
|
|
187
|
-
c`{black.italic ${sizeStr(source.length)}}`,
|
|
188
|
-
])
|
|
189
|
-
)}`);
|
|
190
|
-
}
|
|
27
|
+
// These re-exports exist to avoid breaking backwards compatibility
|
|
28
|
+
export { types, guestTypes, typesComponent } from './types.js';
|
|
191
29
|
|
|
192
30
|
export async function transpile(witPath, opts, program) {
|
|
193
31
|
const varIdx = program?.parent.rawArgs.indexOf('--');
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function types(witPath: any, opts: any): Promise<void>;
|
|
2
|
+
export function guestTypes(witPath: any, opts: any): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} witPath
|
|
5
|
+
* @param {{
|
|
6
|
+
* name?: string,
|
|
7
|
+
* worldName?: string,
|
|
8
|
+
* instantiation?: 'async' | 'sync',
|
|
9
|
+
* tlaCompat?: bool,
|
|
10
|
+
* asyncMode?: string,
|
|
11
|
+
* asyncImports?: string[],
|
|
12
|
+
* asyncExports?: string[],
|
|
13
|
+
* outDir?: string,
|
|
14
|
+
* features?: string[] | 'all',
|
|
15
|
+
* guest?: bool,
|
|
16
|
+
* }} opts
|
|
17
|
+
* @returns {Promise<{ [filename: string]: Uint8Array }>}
|
|
18
|
+
*/
|
|
19
|
+
export function typesComponent(witPath: string, opts: {
|
|
20
|
+
name?: string;
|
|
21
|
+
worldName?: string;
|
|
22
|
+
instantiation?: "async" | "sync";
|
|
23
|
+
tlaCompat?: boolean;
|
|
24
|
+
asyncMode?: string;
|
|
25
|
+
asyncImports?: string[];
|
|
26
|
+
asyncExports?: string[];
|
|
27
|
+
outDir?: string;
|
|
28
|
+
features?: string[] | "all";
|
|
29
|
+
guest?: boolean;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
[filename: string]: Uint8Array;
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
package/src/cmd/types.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { platform } from 'node:process';
|
|
2
|
+
import { stat } from 'node:fs/promises';
|
|
3
|
+
import { extname, basename, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
import c from 'chalk-template';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
$init,
|
|
9
|
+
generateTypes,
|
|
10
|
+
} from '../../obj/js-component-bindgen-component.js';
|
|
11
|
+
import {
|
|
12
|
+
writeFiles,
|
|
13
|
+
ASYNC_WASI_IMPORTS,
|
|
14
|
+
ASYNC_WASI_EXPORTS,
|
|
15
|
+
} from '../common.js';
|
|
16
|
+
|
|
17
|
+
const isWindows = platform === 'win32';
|
|
18
|
+
|
|
19
|
+
export async function types(witPath, opts) {
|
|
20
|
+
const files = await typesComponent(witPath, opts);
|
|
21
|
+
await writeFiles(files, opts.quiet ? false : 'Generated Type Files');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function guestTypes(witPath, opts) {
|
|
25
|
+
const files = await typesComponent(witPath, { ...opts, guest: true });
|
|
26
|
+
await writeFiles(
|
|
27
|
+
files,
|
|
28
|
+
opts.quiet
|
|
29
|
+
? false
|
|
30
|
+
: 'Generated Guest Typescript Definition Files (.d.ts)'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} witPath
|
|
36
|
+
* @param {{
|
|
37
|
+
* name?: string,
|
|
38
|
+
* worldName?: string,
|
|
39
|
+
* instantiation?: 'async' | 'sync',
|
|
40
|
+
* tlaCompat?: bool,
|
|
41
|
+
* asyncMode?: string,
|
|
42
|
+
* asyncImports?: string[],
|
|
43
|
+
* asyncExports?: string[],
|
|
44
|
+
* outDir?: string,
|
|
45
|
+
* allFeatures?: bool,
|
|
46
|
+
* feature?: string[] | 'all', // backwards compat
|
|
47
|
+
* features?: string[] | 'all',
|
|
48
|
+
* asyncWasiImports?: string[],
|
|
49
|
+
* asyncWasiExports?: string[],
|
|
50
|
+
* guest?: bool,
|
|
51
|
+
* }} opts
|
|
52
|
+
* @returns {Promise<{ [filename: string]: Uint8Array }>}
|
|
53
|
+
*/
|
|
54
|
+
export async function typesComponent(witPath, opts) {
|
|
55
|
+
await $init;
|
|
56
|
+
const name =
|
|
57
|
+
opts.name ||
|
|
58
|
+
(opts.worldName
|
|
59
|
+
? opts.worldName.split(':').pop().split('/').pop()
|
|
60
|
+
: basename(witPath.slice(0, -extname(witPath).length || Infinity)));
|
|
61
|
+
let instantiation;
|
|
62
|
+
if (opts.instantiation) {
|
|
63
|
+
instantiation = { tag: opts.instantiation };
|
|
64
|
+
}
|
|
65
|
+
let outDir = (opts.outDir ?? '').replace(/\\/g, '/');
|
|
66
|
+
if (!outDir.endsWith('/') && outDir !== '') {
|
|
67
|
+
outDir += '/';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let features = null;
|
|
71
|
+
if (opts.allFeatures) {
|
|
72
|
+
features = { tag: 'all' };
|
|
73
|
+
} else if (Array.isArray(opts.feature)) {
|
|
74
|
+
features = { tag: 'list', val: opts.feature };
|
|
75
|
+
} else if (Array.isArray(opts.features)) {
|
|
76
|
+
features = { tag: 'list', val: opts.features };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (opts.asyncWasiImports) {
|
|
80
|
+
opts.asyncImports = ASYNC_WASI_IMPORTS.concat(opts.asyncImports || []);
|
|
81
|
+
}
|
|
82
|
+
if (opts.asyncWasiExports) {
|
|
83
|
+
opts.asyncExports = ASYNC_WASI_EXPORTS.concat(opts.asyncExports || []);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const asyncMode =
|
|
87
|
+
!opts.asyncMode || opts.asyncMode === 'sync'
|
|
88
|
+
? null
|
|
89
|
+
: {
|
|
90
|
+
tag: opts.asyncMode,
|
|
91
|
+
val: {
|
|
92
|
+
imports: opts.asyncImports || [],
|
|
93
|
+
exports: opts.asyncExports || [],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let types;
|
|
98
|
+
const absWitPath = resolve(witPath);
|
|
99
|
+
try {
|
|
100
|
+
types = generateTypes(name, {
|
|
101
|
+
wit: { tag: 'path', val: (isWindows ? '//?/' : '') + absWitPath },
|
|
102
|
+
instantiation,
|
|
103
|
+
tlaCompat: opts.tlaCompat ?? false,
|
|
104
|
+
world: opts.worldName,
|
|
105
|
+
features,
|
|
106
|
+
guest: opts.guest ?? false,
|
|
107
|
+
asyncMode,
|
|
108
|
+
}).map(([name, file]) => [`${outDir}${name}`, file]);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
if (err.toString().includes('does not match previous package name')) {
|
|
111
|
+
const hint = await printWITLayoutHint(absWitPath);
|
|
112
|
+
if (err.message) {
|
|
113
|
+
err.message += `\n${hint}`;
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return Object.fromEntries(types);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Print a hint about WIT folder layout
|
|
125
|
+
*
|
|
126
|
+
* @param {(string, any) => void} consoleFn
|
|
127
|
+
*/
|
|
128
|
+
async function printWITLayoutHint(witPath) {
|
|
129
|
+
const pathMeta = await stat(witPath);
|
|
130
|
+
let output = '\n';
|
|
131
|
+
if (!pathMeta.isFile() && !pathMeta.isDirectory()) {
|
|
132
|
+
output += c`{yellow.bold warning} The supplited WIT path [${witPath}] is neither a file or directory.\n`;
|
|
133
|
+
return output;
|
|
134
|
+
}
|
|
135
|
+
const ftype = pathMeta.isDirectory() ? 'directory' : 'file';
|
|
136
|
+
output += c`{yellow.bold warning} Your WIT ${ftype} [${witPath}] may be laid out incorrectly\n`;
|
|
137
|
+
output += c`{yellow.bold warning} Keep in mind the following rules:\n`;
|
|
138
|
+
output += c`{yellow.bold warning} - Top level WIT files are in the same package (i.e. "ns:pkg" in "wit/*.wit")\n`;
|
|
139
|
+
output += c`{yellow.bold warning} - All package dependencies should be in "wit/deps" (i.e. "some:dep" in "wit/deps/some-dep.wit"\n`;
|
|
140
|
+
return output;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// see: https://github.com/vitest-dev/vitest/issues/6953#issuecomment-2505310022
|
|
144
|
+
if (typeof __vite_ssr_import_meta__ !== 'undefined') {
|
|
145
|
+
__vite_ssr_import_meta__.resolve = (path) =>
|
|
146
|
+
'file://' + globalCreateRequire(import.meta.url).resolve(path);
|
|
147
|
+
}
|
package/src/common.d.ts
CHANGED
|
@@ -10,7 +10,10 @@ export function table(data: any, align?: any[]): string;
|
|
|
10
10
|
*/
|
|
11
11
|
export function getTmpDir(): Promise<string>;
|
|
12
12
|
export function spawnIOTmp(cmd: any, input: any, args: any): Promise<Buffer<ArrayBufferLike>>;
|
|
13
|
+
export function writeFiles(files: any, summaryTitle: any): Promise<void>;
|
|
13
14
|
export const isWindows: boolean;
|
|
15
|
+
export const ASYNC_WASI_IMPORTS: string[];
|
|
16
|
+
export const ASYNC_WASI_EXPORTS: string[];
|
|
14
17
|
export { readFileCli as readFile };
|
|
15
18
|
declare function readFileCli(file: any, encoding: any): Promise<Buffer<ArrayBufferLike>>;
|
|
16
19
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["common.js"],"names":[],"mappings":"AA4BA,+CAEC;AACD,0CAIC;AAED,0CASC;AAED,mEAcC;AAED,wDAoBC;AAED;;;;GAIG;AACH,6CAEC;AAWD,8FAiCC;AAED,yEAmBC;AArJD,gCAA8C;AAE9C,0CASE;AAEF,0CAGE;;AAsEF,yFAMC"}
|
package/src/common.js
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { normalize, resolve, sep } from 'node:path';
|
|
1
|
+
import { normalize, resolve, sep, dirname } from 'node:path';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
|
-
import { readFile, writeFile, rm, mkdtemp } from 'node:fs/promises';
|
|
3
|
+
import { readFile, writeFile, rm, mkdtemp, mkdir } from 'node:fs/promises';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { argv0 } from 'node:process';
|
|
6
|
-
import c from 'chalk-template';
|
|
7
6
|
import { platform } from 'node:process';
|
|
8
7
|
|
|
8
|
+
import c from 'chalk-template';
|
|
9
|
+
|
|
9
10
|
export const isWindows = platform === 'win32';
|
|
10
11
|
|
|
12
|
+
export const ASYNC_WASI_IMPORTS = [
|
|
13
|
+
'wasi:io/poll#poll',
|
|
14
|
+
'wasi:io/poll#[method]pollable.block',
|
|
15
|
+
'wasi:io/streams#[method]input-stream.blocking-read',
|
|
16
|
+
'wasi:io/streams#[method]input-stream.blocking-skip',
|
|
17
|
+
'wasi:io/streams#[method]output-stream.blocking-flush',
|
|
18
|
+
'wasi:io/streams#[method]output-stream.blocking-write-and-flush',
|
|
19
|
+
'wasi:io/streams#[method]output-stream.blocking-write-zeroes-and-flush',
|
|
20
|
+
'wasi:io/streams#[method]output-stream.blocking-splice',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export const ASYNC_WASI_EXPORTS = [
|
|
24
|
+
'wasi:cli/run#run',
|
|
25
|
+
'wasi:http/incoming-handler#handle',
|
|
26
|
+
];
|
|
27
|
+
|
|
11
28
|
let _showSpinner = false;
|
|
12
29
|
export function setShowSpinner(val) {
|
|
13
30
|
_showSpinner = val;
|
|
@@ -119,3 +136,24 @@ export async function spawnIOTmp(cmd, input, args) {
|
|
|
119
136
|
await rm(tmpDir, { recursive: true });
|
|
120
137
|
}
|
|
121
138
|
}
|
|
139
|
+
|
|
140
|
+
export async function writeFiles(files, summaryTitle) {
|
|
141
|
+
await Promise.all(
|
|
142
|
+
Object.entries(files).map(async ([name, file]) => {
|
|
143
|
+
await mkdir(dirname(name), { recursive: true });
|
|
144
|
+
await writeFile(name, file);
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
if (!summaryTitle) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
console.log(c`
|
|
151
|
+
{bold ${summaryTitle}:}
|
|
152
|
+
|
|
153
|
+
${table(
|
|
154
|
+
Object.entries(files).map(([name, source]) => [
|
|
155
|
+
c` - {italic ${name}} `,
|
|
156
|
+
c`{black.italic ${sizeStr(source.length)}}`,
|
|
157
|
+
])
|
|
158
|
+
)}`);
|
|
159
|
+
}
|
package/src/jco.js
CHANGED
|
@@ -4,7 +4,8 @@ import c from 'chalk-template';
|
|
|
4
4
|
import { program, Option } from 'commander';
|
|
5
5
|
|
|
6
6
|
import { opt } from './cmd/opt.js';
|
|
7
|
-
import { transpile
|
|
7
|
+
import { transpile } from './cmd/transpile.js';
|
|
8
|
+
import { types, guestTypes } from './cmd/types.js';
|
|
8
9
|
import { run as runCmd, serve as serveCmd } from './cmd/run.js';
|
|
9
10
|
import {
|
|
10
11
|
parse,
|
|
@@ -23,7 +24,7 @@ program
|
|
|
23
24
|
c`{bold jco - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`
|
|
24
25
|
)
|
|
25
26
|
.usage('<command> [options]')
|
|
26
|
-
.version('1.
|
|
27
|
+
.version('1.12.0-rc.1');
|
|
27
28
|
|
|
28
29
|
function myParseInt(value) {
|
|
29
30
|
return parseInt(value, 10);
|
|
@@ -68,6 +69,23 @@ program
|
|
|
68
69
|
'use a debug build of StarlingMonkey'
|
|
69
70
|
)
|
|
70
71
|
.requiredOption('-o, --out <out>', 'output component file')
|
|
72
|
+
.option(
|
|
73
|
+
'--debug-bindings',
|
|
74
|
+
'Output debug bindings and metadata during componentization (by default to stderr)'
|
|
75
|
+
)
|
|
76
|
+
.option(
|
|
77
|
+
'--debug-bindings-dir <dir>',
|
|
78
|
+
'Directory to which to output generated bindings and metadata'
|
|
79
|
+
)
|
|
80
|
+
.option(
|
|
81
|
+
'--debug-binary',
|
|
82
|
+
'Output binary (without component metadata) created during componentization (by default to tmp dir)'
|
|
83
|
+
)
|
|
84
|
+
.option(
|
|
85
|
+
'--debug-binary-path <path>',
|
|
86
|
+
'Path to which to write the generated debug binary'
|
|
87
|
+
)
|
|
88
|
+
.option('--debug-enable-wizer-logging', 'Enable wizer call debugging')
|
|
71
89
|
.action(asyncAction(componentize));
|
|
72
90
|
|
|
73
91
|
program
|