diff --git a/.gitignore b/.gitignore index 4da4d5f62..2d76af62f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ /obj /dist /test/output -/jsct.sh +/jco.sh diff --git a/EXAMPLE.md b/EXAMPLE.md index 7aad7bf66..6000573be 100644 --- a/EXAMPLE.md +++ b/EXAMPLE.md @@ -1,6 +1,6 @@ -## JSCT Example Workflow +## jco Example Workflow -Given an existing Wasm Component, `jsct` provides the tooling necessary to work with this Component fully natively in JS. +Given an existing Wasm Component, `jco` provides the tooling necessary to work with this Component fully natively in JS. For an example, consider a Component `cowsay.wasm`: @@ -14,13 +14,12 @@ Where we would like to use and run this Component in a JS environment. As a first step, we might like to look instead this binary black box of a Component and see what it actually does. -To do this, we can use `jsct wit` to extract the "WIT world" of the Component ([WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) is the typing language used for defining Components). +To do this, we can use `jco wit` to extract the "WIT world" of the Component ([WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) is the typing language used for defining Components). ```shell -> jsct wit cowsay.wasm - -world component { - default export interface { +> jco wit cowsay.wasm +world cowsay { + export cow: interface { enum cows { default, cheese, @@ -34,23 +33,21 @@ world component { ... } - cow-say: func(text: string, cow: option) -> string + say: func(text: string, cow: option) -> string } } ``` -From the above we can see that this Component exports an interface with a single function export, `cow-say`, which takes -as input a string, an optional cow, and returns a string. +From the above we can see that this Component exports a `cow` interface with a single function export, `say`, taking as input a string, an optional cow, and returning a string. -Alternatively `jsct print cowsay.wasm -o out.wat` would output the full concrete Wasm WAT to inspect the Component, -with all the implementation details (don't forget the `-o` flag...). +Alternatively `jco print cowsay.wasm -o out.wat` would output the full concrete Wasm WAT to inspect the Component, with all the implementation details (don't forget the `-o` flag...). ### Transpiling to JS -To execute the Component in a JS environment, use the `jsct transpile` command to generate the JS for the Component: +To execute the Component in a JS environment, use the `jco transpile` command to generate the JS for the Component: ```shell -> jsct transpile cowsay.wasm --minify -o cowsay +> jco transpile cowsay.wasm --minify -o cowsay Transpiled JS Component Files: @@ -63,9 +60,9 @@ Now the Component can be directly imported and used as an ES module: test.mjs ```js -import { cowSay } from './cowsay/cowsay.js'; +import { cow } from './cowsay/cowsay.js'; -console.log(cowSay('Hello Wasm Components!')); +console.log(cow.say('Hello Wasm Components!')); ``` The above JavaScript can be executed in Node.js: diff --git a/README.md b/README.md index a05c7c389..570d366e4 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,38 @@
-

js-component-tools

+

jco

- JavaScript tooling for working with WebAssembly Components + JavaScript component toolchain for working with WebAssembly Components

A Bytecode Alliance project

- build status + build status

## Overview -JS Component Tools is a fully native JS tool for working with the emerging [WebAssembly Components](https://github.com/WebAssembly/component-model) specification in JavaScript. +`jco` is a fully native JS tool for working with the emerging [WebAssembly Components](https://github.com/WebAssembly/component-model) specification in JavaScript. Features include: * "Transpiling" Wasm Component binaries into ES modules that can run in any JS environment. * Optimization helpers for Components via Binaryen -* Component helpers available as a build of [Wasm Tools](https://github.com/bytecodealliance/wasm-tools). +* Component builds of [Wasm Tools](https://github.com/bytecodealliance/wasm-tools) helpers, available for use as a library or CLI commands for use in native JS environments. -This tool is designed primarily for working with already-created Component binaries, and not for creating Component binaries to begin with. For creating Components, see the [Cargo Component](https://github.com/bytecodealliance/cargo-Component) project for Rust and [Wit Bindgen](https://github.com/bytecodealliance/wit-bindgen) for various guest bindgen helpers. +For creating components, see the [Cargo Component](https://github.com/bytecodealliance/cargo-Component) project for Rust and [Wit Bindgen](https://github.com/bytecodealliance/wit-bindgen) for various guest bindgen helpers. > **Note**: This is an experimental project, no guarantees are provided for stability or support and breaking changes may be made in future. ## Installation ```shell -npm install js-component-tools +npm install @bytecodealliance/jco ``` -JS Component Tools can be used as either a library or as a CLI via the `jsct` CLI command. +jco can be used as either a library or as a CLI via the `jco` CLI command. ## Example @@ -95,10 +95,10 @@ Add new producer metadata to a component or core Wasm binary. ## CLI ```shell -Usage: jsct [options] +Usage: jco [options] -JSCT - WebAssembly JS Component Tools - JS Component Transpilation Bindgen & Wasm Tools for JS +jco - WebAssembly JS Component Tools + JS Component Bindgen & Wasm Tools for JS Options: -V, --version output the version number diff --git a/build-dist.sh b/build-dist.sh index a2f7c12b1..e277fe099 100755 --- a/build-dist.sh +++ b/build-dist.sh @@ -1,4 +1,4 @@ -./node_modules/.bin/ncc build src/jsct.js -o dist-cli +./node_modules/.bin/ncc build src/jco.js -o dist-cli chmod +x dist-cli/wasm2js dist-cli/wasm-opt echo {} > dist-cli/package.json mv dist-cli/index.js dist-cli/cli.mjs diff --git a/package.dist.json b/package.dist.json index c038944fd..aa4496c99 100644 --- a/package.dist.json +++ b/package.dist.json @@ -1,12 +1,12 @@ { - "name": "js-component-tools", + "name": "@bytecodealliance/jco", "description": "JavaScript tooling for working with WebAssembly Components", "version": "0.4.0", "exports": "./api.mjs", "types": "api.d.ts", "author": "Guy Bedford", "bin": { - "jsct": "cli.mjs" + "jco": "cli.mjs" }, "repository": { "type": "git", diff --git a/package.json b/package.json index 30f159cc9..800c31cab 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "js-component-tools", + "name": "@bytecodealliance/jco", "exports": { "test": "./src/api.js", "default": "./dist/api.mjs" @@ -25,16 +25,16 @@ "scripts": { "build": "npm run build:set-last && npm run build:dev && ./build-dist.sh", "build:self": "npm run build:set-self && npm run build:dev && ./build-dist.sh", - "build:set-last": "echo './node_modules/.bin/jsct $@' > jsct.sh && chmod +x jsct.sh", - "build:set-self": "echo './src/jsct.js $@' > jsct.sh && chmod +x jsct.sh", + "build:set-last": "echo './node_modules/.bin/jsct $@' > jco.sh && chmod +x jco.sh", + "build:set-self": "echo './src/jco.js $@' > jco.sh && chmod +x jco.sh", "build:dev": "npm run build:wasm && mkdir -p obj && npm run build:js-component-bindgen-component && npm run build:wasm-tools", "build:wasm": "cargo build --workspace --target wasm32-unknown-unknown --release", "build:js-component-bindgen-component": "npm run build:component:js-component-bindgen-component && npm run build:transpile:js-component-bindgen-component", "build:wasm-tools": "npm run build:component:wasm-tools && npm run build:transpile:wasm-tools", - "build:component:js-component-bindgen-component": "./jsct.sh new target/wasm32-unknown-unknown/release/js_component_bindgen_component.wasm -o obj/js-component-bindgen-component.wasm", - "build:component:wasm-tools": "./jsct.sh new target/wasm32-unknown-unknown/release/wasm_tools_js.wasm -o obj/wasm-tools.wasm", - "build:transpile:js-component-bindgen-component": "./jsct.sh transpile obj/js-component-bindgen-component.wasm --map console=../lib/console.js --out-dir obj", - "build:transpile:wasm-tools": "./jsct.sh transpile obj/wasm-tools.wasm --map console=../lib/console.js --out-dir obj", + "build:component:js-component-bindgen-component": "./jco.sh new target/wasm32-unknown-unknown/release/js_component_bindgen_component.wasm -o obj/js-component-bindgen-component.wasm", + "build:component:wasm-tools": "./jco.sh new target/wasm32-unknown-unknown/release/wasm_tools_js.wasm -o obj/wasm-tools.wasm", + "build:transpile:js-component-bindgen-component": "./jco.sh transpile obj/js-component-bindgen-component.wasm --map console=../lib/console.js --out-dir obj", + "build:transpile:wasm-tools": "./jco.sh transpile obj/wasm-tools.wasm --map console=../lib/console.js --out-dir obj", "lint": "eslint -c eslintrc.cjs src/**/*.js", "test": "mocha -u tdd test/test.js --timeout 120000", "test:dev": "mocha -u tdd test/test.js --timeout 120000 -n conditions=test" diff --git a/src/jsct.js b/src/jco.js similarity index 97% rename from src/jsct.js rename to src/jco.js index 0fd7af2e6..f994cefcb 100755 --- a/src/jsct.js +++ b/src/jco.js @@ -6,8 +6,8 @@ import { parse, print, componentNew, componentEmbed, metadataAdd, metadataShow, import c from 'chalk-template'; program - .name('jsct') - .description(c`{bold JSCT - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`) + .name('jco') + .description(c`{bold jco - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`) .usage(' [options]') .version('0.1.0'); diff --git a/test/cli.js b/test/cli.js index 1724ccc1c..e2bcd584b 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,6 +1,6 @@ import { deepStrictEqual, ok, strictEqual } from 'node:assert'; import { readFile, rm } from 'node:fs/promises'; -import { exec, jsctPath } from './helpers.js'; +import { exec, jcoPath } from './helpers.js'; import { tmpdir } from 'node:os'; import { resolve } from 'node:path'; @@ -20,7 +20,7 @@ export async function cliTest (fixtures) { test('Transpile', async () => { try { const name = 'flavorful'; - const { stderr } = await exec(jsctPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '-o', outDir); + const { stderr } = await exec(jcoPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '-o', outDir); strictEqual(stderr, ''); const source = await readFile(`${outDir}/${name}.js`); ok(source.toString().includes('export { exports')); @@ -33,7 +33,7 @@ export async function cliTest (fixtures) { test('Transpile & Optimize & Minify', async () => { try { const name = 'flavorful'; - const { stderr } = await exec(jsctPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '--valid-lifting-optimization', '--tla-compat', '--optimize', '--minify', '--base64-cutoff=0', '-o', outDir); + const { stderr } = await exec(jcoPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '--valid-lifting-optimization', '--tla-compat', '--optimize', '--minify', '--base64-cutoff=0', '-o', outDir); strictEqual(stderr, ''); const source = await readFile(`${outDir}/${name}.js`); ok(source.toString().includes('as exports,')); @@ -46,7 +46,7 @@ export async function cliTest (fixtures) { test('Transpile to JS', async () => { try { const name = 'flavorful'; - const { stderr } = await exec(jsctPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '--map', 'testwasi=./wasi.js', '--valid-lifting-optimization', '--tla-compat', '--js', '--base64-cutoff=0', '-o', outDir); + const { stderr } = await exec(jcoPath, 'transpile', `test/fixtures/${name}.component.wasm`, '--name', name, '--map', 'testwasi=./wasi.js', '--valid-lifting-optimization', '--tla-compat', '--js', '--base64-cutoff=0', '-o', outDir); strictEqual(stderr, ''); const source = await readFile(`${outDir}/${name}.js`, 'utf8'); ok(source.includes('./wasi.js')); @@ -62,7 +62,7 @@ export async function cliTest (fixtures) { test('Optimize', async () => { try { const component = await readFile(`test/fixtures/flavorful.component.wasm`); - const { stderr, stdout } = await exec(jsctPath, 'opt', `test/fixtures/flavorful.component.wasm`, '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'opt', `test/fixtures/flavorful.component.wasm`, '-o', outFile); strictEqual(stderr, ''); ok(stdout.includes('Core Module 1:')); const optimizedComponent = await readFile(outFile); @@ -75,16 +75,16 @@ export async function cliTest (fixtures) { test('Print & Parse', async () => { try { - const { stderr, stdout } = await exec(jsctPath, 'print', `test/fixtures/flavorful.component.wasm`); + const { stderr, stdout } = await exec(jcoPath, 'print', `test/fixtures/flavorful.component.wasm`); strictEqual(stderr, ''); strictEqual(stdout.slice(0, 10), '(component'); { - const { stderr, stdout } = await exec(jsctPath, 'print', `test/fixtures/flavorful.component.wasm`, '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'print', `test/fixtures/flavorful.component.wasm`, '-o', outFile); strictEqual(stderr, ''); strictEqual(stdout, ''); } { - const { stderr, stdout } = await exec(jsctPath, 'parse', outFile, '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'parse', outFile, '-o', outFile); strictEqual(stderr, ''); strictEqual(stdout, ''); ok(await readFile(outFile)); @@ -97,39 +97,39 @@ export async function cliTest (fixtures) { test('Wit & New', async () => { try { - const { stderr, stdout } = await exec(jsctPath, 'wit', `test/fixtures/flavorful.component.wasm`); + const { stderr, stdout } = await exec(jcoPath, 'wit', `test/fixtures/flavorful.component.wasm`); strictEqual(stderr, ''); ok(stdout.includes('world component {')); { - const { stderr, stdout } = await exec(jsctPath, 'wit', `test/fixtures/flavorful.component.wasm`, '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'wit', `test/fixtures/flavorful.component.wasm`, '-o', outFile); strictEqual(stderr, ''); strictEqual(stdout, ''); } { - const { stderr, stdout } = await exec(jsctPath, 'embed', '--dummy', '--wit', outFile, '-m', 'language=javascript', '-m', 'processed-by=dummy-gen@test', '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'embed', '--dummy', '--wit', outFile, '-m', 'language=javascript', '-m', 'processed-by=dummy-gen@test', '-o', outFile); strictEqual(stderr, ''); strictEqual(stdout, ''); } { - const { stderr, stdout } = await exec(jsctPath, 'print', outFile); + const { stderr, stdout } = await exec(jcoPath, 'print', outFile); strictEqual(stderr, ''); strictEqual(stdout.slice(0, 7), '(module'); } { - const { stderr, stdout } = await exec(jsctPath, 'new', outFile, '-o', outFile); + const { stderr, stdout } = await exec(jcoPath, 'new', outFile, '-o', outFile); strictEqual(stderr, ''); strictEqual(stdout, ''); } { - const { stderr, stdout } = await exec(jsctPath, 'print', outFile); + const { stderr, stdout } = await exec(jcoPath, 'print', outFile); strictEqual(stderr, ''); strictEqual(stdout.slice(0, 10), '(component'); } { - const { stdout, stderr } = await exec(jsctPath, 'metadata-show', outFile, '--json'); + const { stdout, stderr } = await exec(jcoPath, 'metadata-show', outFile, '--json'); strictEqual(stderr, ''); const meta = JSON.parse(stdout); deepStrictEqual(meta[0].metaType, { tag: 'component', val: 4 }); @@ -146,7 +146,7 @@ export async function cliTest (fixtures) { test('Component new adapt', async () => { try { - const { stderr } = await exec(jsctPath, + const { stderr } = await exec(jcoPath, 'new', 'test/fixtures/exitcode.wasm', '--adapt', @@ -154,7 +154,7 @@ export async function cliTest (fixtures) { '-o', outFile); strictEqual(stderr, ''); { - const { stderr, stdout } = await exec(jsctPath, 'print', outFile); + const { stderr, stdout } = await exec(jcoPath, 'print', outFile); strictEqual(stderr, ''); strictEqual(stdout.slice(0, 10), '(component'); } @@ -166,7 +166,7 @@ export async function cliTest (fixtures) { test('Extract metadata', async () => { try { - const { stdout, stderr } = await exec(jsctPath, + const { stdout, stderr } = await exec(jcoPath, 'metadata-show', 'test/fixtures/exitcode.wasm', '--json'); diff --git a/test/codegen.js b/test/codegen.js index 5315fc5f8..b784fd3d7 100644 --- a/test/codegen.js +++ b/test/codegen.js @@ -1,5 +1,5 @@ import { readFile } from 'node:fs/promises'; -import { exec, jsctPath } from './helpers.js'; +import { exec, jcoPath } from './helpers.js'; import { strictEqual } from 'node:assert'; const eslintPath = 'node_modules/.bin/eslint'; @@ -28,7 +28,7 @@ export async function codegenTest (fixtures) { const name = fixture.replace('.component.wasm', ''); test(`${fixture} transpile`, async () => { const flags = await readFlags(`test/runtime/${name}.ts`); - var { stderr } = await exec(jsctPath, 'transpile', `test/fixtures/${fixture}`, '--name', name, ...flags, '-o', `test/output/${name}`); + var { stderr } = await exec(jcoPath, 'transpile', `test/fixtures/${fixture}`, '--name', name, ...flags, '-o', `test/output/${name}`); strictEqual(stderr, ''); }); diff --git a/test/helpers.js b/test/helpers.js index 54b23c636..477da5fe7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -2,7 +2,7 @@ import { execArgv } from 'node:process'; import { spawn } from 'node:child_process'; export const dev = execArgv.includes('--conditions=test'); -export const jsctPath = dev ? 'src/jsct.js' : 'dist/cli.mjs'; +export const jcoPath = dev ? 'src/jco.js' : 'dist/cli.mjs'; export async function exec (cmd, ...args) { let stdout = '', stderr = '';