ericgregory / wit2wadm-ts

A TypeScript WebAssembly component that composes with the Rust-based WebAssembly component https://github.com/brooksmtownsend/wit2wadm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

wit2wadm TypeScript

This repository includes a Wasm component written in TypeScript that composes with the Rust component wit2wadm.

This is a general demonstration of composing components together in order to reuse functionality from different languages. I wrote a small library (wit2wadm) in Rust, and because that library is also compilable to a component it can be used by any other WebAssembly component. The below usage section walks through how you can build this TypeScript component and compose it with my Rust wit2wadm component as if it was a native TypeScript library.

Building

Prerequisites

Install Node dependencies and build the component:

# Install NPM dependencies
npm install
# Build the TypeScript component
wash build
# Build the wit2wadm component
wash build -p ./wit2wadm

Let's take a look at the two component's WIT interfaces:

➜ wash inspect --wit ./wit2wadm/build/wit2wadm_component_s.wasm

package root:component;

world root {
  import wasi:cli/environment@0.2.0;
  import wasi:cli/exit@0.2.0;
  import wasi:io/error@0.2.0;
  import wasi:io/streams@0.2.0;
  import wasi:cli/stdin@0.2.0;
  import wasi:cli/stdout@0.2.0;
  import wasi:cli/stderr@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:random/random@0.2.0;

  export wasmcloud:tools/convert;
}
➜ wash inspect --wit ./build/wit2wadm_ts_s.wasm

package root:component;

world root {
  import wasmcloud:tools/convert;

  export wasmcloud:tools/convert;
}

What we're going to be doing by composing these components together is connecting the export wasmcloud:tools/convert in the Rust component to the import wasmcloud:tools/component in the TypeScript component, and the final product is a single WebAssembly component.

wit2wasm architecture

Compose

Compose the component with the wit2wadm Rust component, satisfying the wasmcloud:tools/convert import in our WIT:

# Copy into current directory for simplicity
cp ./wit2wadm/build/wit2wadm_component_s.wasm ./wit2wadm.wasm
# Compose the components, the wit2wadm component export will satisfy the import of the TypeScript component
wasm-tools compose ./build/wit2wadm_ts_s.wasm --definitions ./wit2wadm.wasm > composed.wasm

Taking a look at our composed component, we can see that we've ended up with a combination of both components:

➜ wash inspect --wit ./composed.wasm

package root:component;

world root {
  import wasi:cli/environment@0.2.0;
  import wasi:cli/exit@0.2.0;
  import wasi:io/error@0.2.0;
  import wasi:io/streams@0.2.0;
  import wasi:cli/stdin@0.2.0;
  import wasi:cli/stdout@0.2.0;
  import wasi:cli/stderr@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:random/random@0.2.0;

  export wasmcloud:tools/convert;
}

Transpile and run in the web

Using jco, we can transpile this now composed component to run as a JavaScript module in the web.

# Transpile our composed component
jco transpile ./composed.wasm -o ./wit2wadm/docs/transpile --no-typescript

Currently, the wit2wadm website is configured to run the Rust component. Make one small change in the JavaScript to point at the TypeScript component instead under ./wit2wadm/docs/index.js

// File: wit2wadm/docs/index.js
// Change the import path
// import { convert } from "./transpile/wit2wadm_component.js";
import { convert } from "./transpile/composed.js";

Now serve the site:

➜ python3 -m http.server -d wit2wadm/docs

composed component

About

A TypeScript WebAssembly component that composes with the Rust-based WebAssembly component https://github.com/brooksmtownsend/wit2wadm


Languages

Language:TypeScript 100.0%