Skip to content

Commit

Permalink
chore(examples): add examples (#507)
Browse files Browse the repository at this point in the history
* chore(examples): add examples

This commit adds examples to the jco, some of which are/will be
referenced from the component-model book (https://component-model.bytecodealliance.org/).

Signed-off-by: Victor Adossi <[email protected]>

* fix(examples): nodejs script target command chaining

Co-authored-by: Guy Bedford <[email protected]>

* refactor(examples): inline reverseAndUppercase() in component

Signed-off-by: Victor Adossi <[email protected]>

* refactor(examples): inline reverseString() in example

Signed-off-by: Victor Adossi <[email protected]>

---------

Signed-off-by: Victor Adossi <[email protected]>
Co-authored-by: Guy Bedford <[email protected]>
  • Loading branch information
vados-cosmonic and guybedford authored Oct 18, 2024
1 parent f0eabad commit 79f7995
Show file tree
Hide file tree
Showing 27 changed files with 5,443 additions and 0 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: examples

on:
pull_request:
branches:
- main

jobs:
test:
name: ${{ matrix.project.name }}
runs-on: ubuntu-latest
strategy:
matrix:
wac:
- version: 0.6.0
node:
- version: 22.5.1
project:
- name: add
dir: ./examples/components/add
- name: string-reverse
dir: ./examples/components/string-reverse
- name: string-reverse-upper
dir: ./examples/components/string-reverse-upper
is-composed: true
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # 4.2.0
with:
sparse-checkout: |
examples
- uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # 4.0.4
with:
node-version: ${{ matrix.node.version }}
cache: 'npm'

- name: install wac
if: ${{ matrix.project.is-composed }}
uses: jaxxstorm/action-install-gh-release@25d5e2dd555cd74f1fab9ac1e6ea117acde2c0c4 # 1.2.0
with:
repo: bytecodealliance/wac
tag: v${{ matrix.wac.version }}
extension-matching: disable
rename-to: wac
chmod: 0755

- name: install (${{ matrix.project.name }})
working-directory: ${{ matrix.project.dir }}
run: |
npm install
- name: build (${{ matrix.project.name }})
working-directory: ${{ matrix.project.dir }}
run: |
npm run build
- name: compose (${{ matrix.project.name }})
if: ${{ matrix.project.is-composed }}
working-directory: ${{ matrix.project.dir }}
run: |
npm run compose
- name: transpile (${{ matrix.project.name }})
working-directory: ${{ matrix.project.dir }}
run: |
npm run transpile
- name: run transpiled js (${{ matrix.project.name }})
if: ${{ matrix.project.composed }}
working-directory: ${{ matrix.project.dir }}
run: |
npm run transpiled-js
3 changes: 3 additions & 0 deletions examples/components/add/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
*.wasm
1 change: 1 addition & 0 deletions examples/components/add/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.5.1
91 changes: 91 additions & 0 deletions examples/components/add/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Simple WebAssembly `add` in JavaScript

This folder contains a simple Javascript project can built into a WebAssembly binary.

This is a [`node`][nodejs] CLI and browser based example implementation of running a component that exports the `reverse` interface from a JavaScript application.

It uses [`jco`][jco] to:

- Generate a WebAssembly component (`jco componentize`) that can be executed anywhere WebAssembly components run
- Generate JavaScript bindings (`jco transpile`) that execute the core functionality (in browser or compliant JS runtimes like NodeJS)

For another example of using `jco` with components in multiple environments, see the [`jco` example][docs-jco-example].

[nodejs]: https://nodejs.org
[jco]: https://bytecodealliance.github.io/jco/
[jco-example]: https://github.com/bytecodealliance/jco/blob/main/docs/src/example.md

# Component Interface

This component implements a simple [WebAssembly Interface Types ("WIT")][wit] interface:

```wit
package example:components;
world component {
export add: func(x: s32, y: s32) -> s32;
}
```

A component that implements the `component` world exports a single function called `add` which takes in two signed integers and produces a signed integer as a result.

> [!NOTE]
> You can read more about [the WIT syntax][wit] online.
[wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md

# Quickstart

## Dependencies

First, install required dependencies:

```console
npm install
```

> [!NOTE]
> As this is a regular NodeJS project, you can use your package manager of choice (e.g. `yarn`, `pnpm`)
At this point, since this project is *just* NodeJS, you could use the module from any NodeJS project or browser project where appropriate.

That said, we'll be focusing on building the JS code we've written so far into a WebAssembly binary, which can run *anywhere* WebAssembly runtimes are supported,
including in other languages, and the browser.

## Building the WebAssembly binary

We can build a WebAssembly binary out of this JS project with `jco`:

```console
npm run build
```

A WebAssembly binary will be written to `add.wasm`.

## Running the binary in NodeJS via transpilation

While somewhat redundant in this JS-native context, we can use our produced WebAssembly binary (which could be written in *any* programming language) from JS projects with `jco`.

The process we want `jco` to perform for us is "transpilation" -- converting a WebAssembly binary into a JS module that can be run on any JS runtime that supports WebAssembly:

```console
npm run transpile
```

Transpilation produces files in `dist/transpiled` that enable the WebAssembly component (`add.wasm`) to run in any compliant JS runtime:

```
dist
└── transpiled
├── add.core.wasm
├── add.d.ts
└── add.js
```

With this transpiled module available, we can now run native JS code *uses* the WebAssembly module:

```
npm run transpiled-js
```

See `run-transpiled.js` for the full code listing.
7 changes: 7 additions & 0 deletions examples/components/add/add.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* This Javascript will be interpreted by `jco` and turned into a
* WebAssembly binary with a single export (this `add` function).
*/
export function add(x, y) {
return x + y;
}
Loading

0 comments on commit 79f7995

Please sign in to comment.