2 unstable releases

0.1.0 Apr 16, 2024
0.0.0 Apr 16, 2024

#1167 in WebAssembly

Download history 307/week @ 2024-04-15

307 downloads per month

Apache-2.0 WITH LLVM-exception

570KB
13K SLoC

WebAssembly Compositions (WAC)

A Bytecode Alliance project

A tool for composing WebAssembly components together.

build status Crates.io version Download docs.rs docs

Overview

wac is a tool for composing WebAssembly Components together.

The tool uses the WAC (pronounced "whack") language to define how components composed together.

The wac Language

The wac language is a declarative superset of wit for describing how components are composed together.

As an example, imagine two components name.wasm and greeter.wasm.

The wit for name.wasm is:

package example:name;

world name {
  /// Exporting a 'name' function that returns a name to greet.
  export name: func() -> string;
}

And the wit for greeter.wasm is:

package example:greeter;

world greeter {
  /// Importing a 'name' function that returns the name to greet.
  import name: func() -> string;
  /// Exporting a 'greet' function that returns a greeting using the name.
  export greet: func() -> string;
}

The following is an example of a wac file that composes these two components together by plugging name.wasm's "name" export into greeter.wasm's "name" import.

package example:composition;

// Instantiate the `name` component
let n = new example:name {};

// Instantiate the `greeter` component by plugging its `name`
// import with the `name` export of the `name` component.
let greeter = new example:greeter {
  name: n.name,
};

// Export the greet function from the greeter component
export greeter.greet;

The result of encoding this composition is a single component that does not import anything and only exports the "greet" function.

For a full description of the wac language see the language guide.

Installation

cargo install wac-cli

To enable support Warg component registries, specify the registry feature:

cargo install wac-cli --features registry

Usage

The wac CLI tool has three commands:

  • wac parse - Parses a composition into a JSON representation of the AST.
  • wac resolve - Resolves a composition into a JSON representation.
  • wac encode - Encodes a WAC source file as a WebAssembly component.

Encoding Compositions

To encode a composition, use the wac encode command:

wac encode -t input.wac

This will encode input.wac as a WebAssembly component and write the text representation of the component to stdout.

wac encode -o output.wasm input.wac

This will encode input.wac as a WebAssembly component named output.wasm.

Dependencies

By default, wac will create a component that embeds its dependencies (i.e. packages referenced in a WAC source file) inside of itself rather than importing those dependencies; to cause dependencies to be imported in the output component, use the --import-dependencies flag:

wac encode --import-dependencies -o output.wasm input.wac

Dependencies may be located within a deps subdirectory, with an expected structure of:

deps/
├─ <namespace>/
│  ├─ <package>.wasm

The dependency may be also be a WIT file or a directory containing a WIT package:

deps/
├─ <namespace>/
│  ├─ <package>/
│  │  ├─ a.wit
│  │  ├─ ...

The --deps-dir CLI option may be used to specify a different directory to search for dependencies.

The location of specific dependencies may also be specified with the --dep CLI option:

wac encode --dep foo:bar=./baz.wasm -o output.wasm input.wac

By default, dependencies must be binary-encoded WebAssembly components; to enable support for WAT files, use the wat build-time feature.

If the registry build-time feature is enabled, then dependencies may be automatically resolved from a Warg registry and do not need to exist in the deps subdirectory or specified via the --dep CLI option.

Dependencies

~17–34MB
~514K SLoC