@bytecodealliance/jco 0.14.0 → 0.14.2

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/src/cmd/run.js CHANGED
@@ -10,7 +10,54 @@ import c from 'chalk-template';
10
10
  export async function run (componentPath, args, opts) {
11
11
  // Ensure that `args` is an array
12
12
  args = [...args];
13
+ return runComponent(componentPath, args, opts, `
14
+ if (!mod.run || !mod.run.run) {
15
+ console.error('Not a valid command component to execute.');
16
+ process.exit(1);
17
+ }
18
+ try {
19
+ mod.run.run();
20
+ // for stdout flushing
21
+ await new Promise(resolve => setTimeout(resolve));
22
+ process.exit(0);
23
+ }
24
+ catch (e) {
25
+ console.error(e);
26
+ process.exit(1);
27
+ }
28
+ `);
29
+ }
30
+
31
+ export async function serve (componentPath, args, opts) {
32
+ let tryFindPort = false;
33
+ let { port, host } = opts;
34
+ if (port === undefined) {
35
+ tryFindPort = true;
36
+ port = '8000';
37
+ }
38
+ // Ensure that `args` is an array
39
+ args = [...args];
40
+ return runComponent(componentPath, args, opts, `
41
+ import { HTTPServer } from '@bytecodealliance/preview2-shim/http';
42
+ const server = new HTTPServer(mod.incomingHandler);
43
+ ${tryFindPort ? `
44
+ let port = ${port};
45
+ while (true) {
46
+ try {
47
+ server.listen(port, ${JSON.stringify(host)});
48
+ break;
49
+ } catch (e) {
50
+ if (e.code !== 'EADDRINUSE')
51
+ throw e;
52
+ }
53
+ port++;
54
+ }
55
+ ` : `server.listen(${port}, ${JSON.stringify(host)})`}
56
+ console.error(\`Server listening on \${port}...\`);
57
+ `);
58
+ }
13
59
 
60
+ async function runComponent (componentPath, args, opts, executor) {
14
61
  const jcoImport = opts.jcoImport ? resolve(opts.jcoImport) : null;
15
62
 
16
63
  const name = basename(componentPath.slice(0, -extname(componentPath).length || Infinity));
@@ -18,6 +65,7 @@ export async function run (componentPath, args, opts) {
18
65
  if (opts.jcoDir) {
19
66
  await mkdir(outDir, { recursive: true });
20
67
  }
68
+
21
69
  try {
22
70
  try {
23
71
  await transpile(componentPath, {
@@ -26,7 +74,8 @@ export async function run (componentPath, args, opts) {
26
74
  noTypescript: true,
27
75
  wasiShim: true,
28
76
  outDir,
29
- tracing: opts.jcoTrace
77
+ tracing: opts.jcoTrace,
78
+ map: opts.jcoMap
30
79
  });
31
80
  }
32
81
  catch (e) {
@@ -63,30 +112,11 @@ export async function run (componentPath, args, opts) {
63
112
  const runPath = resolve(outDir, '_run.js');
64
113
  await writeFile(runPath, `
65
114
  ${jcoImport ? `import ${JSON.stringify(pathToFileURL(jcoImport))}` : ''}
66
- function logInvalidCommand () {
67
- console.error('Not a valid command component to execute, make sure it was built to a command adapter and with the same version.');
68
- }
69
115
  try {
70
116
  process.argv[1] = "${name}";
71
- const mod = await import('./${name}.js');
72
- if (!mod.run || !mod.run.run) {
73
- logInvalidCommand();
74
- process.exit(1);
75
- }
76
- try {
77
- mod.run.run();
78
- // TODO: figure out stdout flush!
79
- setTimeout(() => {});
80
- }
81
- catch (e) {
82
- console.error(e);
83
- process.exit(1);
84
- }
85
- }
86
- catch (e) {
87
- logInvalidCommand();
88
- throw e;
89
- }
117
+ } catch {}
118
+ const mod = await import('./${name}.js');
119
+ ${executor}
90
120
  `);
91
121
 
92
122
  process.exitCode = await new Promise((resolve, reject) => {
@@ -102,4 +132,4 @@ export async function run (componentPath, args, opts) {
102
132
  await rm(outDir, { recursive: true });
103
133
  } catch {}
104
134
  }
105
- }
135
+ }
@@ -8,13 +8,13 @@ export function transpile(componentPath: any, opts: any, program: any): Promise<
8
8
  * map?: Record<string, string>,
9
9
  * validLiftingOptimization?: bool,
10
10
  * tracing?: bool,
11
- * noNodejsCompat?: bool,
11
+ * nodejsCompat?: bool,
12
12
  * tlaCompat?: bool,
13
13
  * base64Cutoff?: bool,
14
14
  * js?: bool,
15
15
  * minify?: bool,
16
16
  * optimize?: bool,
17
- * noNamespacedExports?: bool,
17
+ * namespacedExports?: bool,
18
18
  * optArgs?: string[],
19
19
  * }} opts
20
20
  * @returns {Promise<{ files: { [filename: string]: Uint8Array }, imports: string[], exports: [string, 'function' | 'instance'][] }>}
@@ -25,13 +25,13 @@ export function transpileComponent(component: Uint8Array, opts?: {
25
25
  map?: Record<string, string>;
26
26
  validLiftingOptimization?: bool;
27
27
  tracing?: bool;
28
- noNodejsCompat?: bool;
28
+ nodejsCompat?: bool;
29
29
  tlaCompat?: bool;
30
30
  base64Cutoff?: bool;
31
31
  js?: bool;
32
32
  minify?: bool;
33
33
  optimize?: bool;
34
- noNamespacedExports?: bool;
34
+ namespacedExports?: bool;
35
35
  optArgs?: string[];
36
36
  }): Promise<{
37
37
  files: {
@@ -1 +1 @@
1
- {"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["transpile.js"],"names":[],"mappings":"AAWA,sFA2BC;AAuBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,8CAlBW,UAAU;UAEV,MAAM;oBACI,OAAO,GAAG,MAAM;UAC1B,OAAO,MAAM,EAAE,MAAM,CAAC;;;;;;;;;;cAUlB,MAAM,EAAE;;;;;aAEoD,MAAM,EAAE;aAAW,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,EAAE;GA4IhI"}
1
+ {"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["transpile.js"],"names":[],"mappings":"AAWA,sFA2BC;AAuBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,8CAlBW,UAAU;UAEV,MAAM;oBACI,OAAO,GAAG,MAAM;UAC1B,OAAO,MAAM,EAAE,MAAM,CAAC;;;;;;;;;;cAUlB,MAAM,EAAE;;;;;aAEoD,MAAM,EAAE;aAAW,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,EAAE;GAmShI"}
@@ -81,7 +81,7 @@ async function wasm2Js (source) {
81
81
  */
82
82
  export async function transpileComponent (component, opts = {}) {
83
83
  await $init;
84
- if (opts.noWasiShim || opts.instantiation) opts.wasiShim = false;
84
+ if (opts.instantiation) opts.wasiShim = false;
85
85
 
86
86
  let spinner;
87
87
  const showSpinner = getShowSpinner();
@@ -97,8 +97,6 @@ export async function transpileComponent (component, opts = {}) {
97
97
  'wasi:filesystem/*': '@bytecodealliance/preview2-shim/filesystem#*',
98
98
  'wasi:http/*': '@bytecodealliance/preview2-shim/http#*',
99
99
  'wasi:io/*': '@bytecodealliance/preview2-shim/io#*',
100
- 'wasi:logging/*': '@bytecodealliance/preview2-shim/logging#*',
101
- 'wasi:poll/*': '@bytecodealliance/preview2-shim/poll#*',
102
100
  'wasi:random/*': '@bytecodealliance/preview2-shim/random#*',
103
101
  'wasi:sockets/*': '@bytecodealliance/preview2-shim/sockets#*',
104
102
  }, opts.map || {});
@@ -121,8 +119,8 @@ export async function transpileComponent (component, opts = {}) {
121
119
  instantiation,
122
120
  validLiftingOptimization: opts.validLiftingOptimization ?? false,
123
121
  tracing: opts.tracing ?? false,
124
- noNodejsCompat: !(opts.nodejsCompat ?? true),
125
- noTypescript: opts.noTypescript || false,
122
+ noNodejsCompat: opts.nodejsCompat === false,
123
+ noTypescript: opts.typescript === false,
126
124
  tlaCompat: opts.tlaCompat ?? false,
127
125
  base64Cutoff: opts.js ? 0 : opts.base64Cutoff ?? 5000,
128
126
  noNamespacedExports: opts.namespacedExports === false,
@@ -1 +1 @@
1
- {"version":3,"file":"wasm-tools.d.ts","sourceRoot":"","sources":["wasm-tools.js"],"names":[],"mappings":"AAOA,2DAKC;AAED,2DASC;AAED,kEASC;AAED,kEAsBC;AAED,oEAaC;AAED,iEAUC;AAED,kEAiCC"}
1
+ {"version":3,"file":"wasm-tools.d.ts","sourceRoot":"","sources":["wasm-tools.js"],"names":[],"mappings":"AAQA,2DAKC;AAED,2DASC;AAED,kEASC;AAED,kEAsBC;AAED,oEAaC;AAED,iEAUC;AAED,kEAiCC"}
package/src/jco.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { program, Option } from 'commander';
3
3
  import { opt } from './cmd/opt.js';
4
4
  import { transpile } from './cmd/transpile.js';
5
- import { run } from './cmd/run.js';
5
+ import { run as runCmd, serve as serveCmd } from './cmd/run.js';
6
6
  import { parse, print, componentNew, componentEmbed, metadataAdd, metadataShow, componentWit } from './cmd/wasm-tools.js';
7
7
  import { componentize } from './cmd/componentize.js';
8
8
  import c from 'chalk-template';
@@ -11,7 +11,7 @@ program
11
11
  .name('jco')
12
12
  .description(c`{bold jco - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`)
13
13
  .usage('<command> [options]')
14
- .version('0.14.0');
14
+ .version('0.14.2');
15
15
 
16
16
  function myParseInt(value) {
17
17
  return parseInt(value, 10);
@@ -52,15 +52,48 @@ program.command('transpile')
52
52
  .action(asyncAction(transpile));
53
53
 
54
54
  program.command('run')
55
- .description('Run a WebAssembly Command component')
55
+ .description('Run a WASI Command component')
56
56
  .usage('<command.wasm> <args...>')
57
57
  .helpOption(false)
58
- .argument('<command>', 'Wasm command binary to run')
58
+ .allowUnknownOption(true)
59
+ .allowExcessArguments(true)
60
+ .argument('<command>', 'WASI command binary to run')
59
61
  .option('--jco-dir <dir>', 'Instead of using a temporary dir, set the output directory for the run command')
60
62
  .option('--jco-trace', 'Enable call tracing')
61
63
  .option('--jco-import <module>', 'Custom module to import before the run executes to support custom environment setup')
62
- .argument('[args...]', 'Any CLI arguments to provide to the command')
63
- .action(asyncAction(run));
64
+ .option('--jco-map <mappings...>', 'specifier=./output custom mappings for the component imports')
65
+ .argument('[args...]', 'Any CLI arguments for the component')
66
+ .action(asyncAction(async function run (cmd, args, opts, command) {
67
+ // specially only allow help option in first position
68
+ if (cmd === '--help' || cmd === '-h') {
69
+ command.help();
70
+ } else {
71
+ return runCmd(cmd, args, opts);
72
+ }
73
+ }));
74
+
75
+ program.command('serve')
76
+ .description('Serve a WASI HTTP component')
77
+ .usage('<server.wasm> <args...>')
78
+ .helpOption(false)
79
+ .allowUnknownOption(true)
80
+ .allowExcessArguments(true)
81
+ .argument('<server>', 'WASI server binary to run')
82
+ .option('--port <number>')
83
+ .option('--host <host>')
84
+ .option('--jco-dir <dir>', 'Instead of using a temporary dir, set the output directory for the transpiled code')
85
+ .option('--jco-trace', 'Enable call tracing')
86
+ .option('--jco-import <module>', 'Custom module to import before the server executes to support custom environment setup')
87
+ .option('--jco-map <mappings...>', 'specifier=./output custom mappings for the component imports')
88
+ .argument('[args...]', 'Any CLI arguments for the component')
89
+ .action(asyncAction(async function serve (cmd, args, opts, command) {
90
+ // specially only allow help option in first position
91
+ if (cmd === '--help' || cmd === '-h') {
92
+ command.help();
93
+ } else {
94
+ return serveCmd(cmd, args, opts);
95
+ }
96
+ }));
64
97
 
65
98
  program.command('opt')
66
99
  .description('optimizes a Wasm component, including running wasm-opt Binaryen optimizations')
@@ -124,6 +157,8 @@ program.command('embed')
124
157
  .option('-m, --metadata <metadata...>', 'field=name[@version] producer metadata to add with the embedding')
125
158
  .action(asyncAction(componentEmbed));
126
159
 
160
+ program.showHelpAfterError();
161
+
127
162
  program.parse();
128
163
 
129
164
  function asyncAction (cmd) {