Wasmex.Components (wasmex v0.10.0)

This is the entry point to support for the WebAssembly Component Model.

The Component Model is a higher-level way to interact with WebAssembly modules that provides:

  • Better type safety through interface types
  • Standardized way to define imports and exports using WIT (WebAssembly Interface Types)
  • WASI support for system interface capabilities

Basic Usage

To use a WebAssembly component:

  1. Start a component instance:

    # Using raw bytes
    bytes = File.read!("path/to/component.wasm")
    {:ok, pid} = Wasmex.Components.start_link(%{bytes: bytes})
    
    # Using a file path
    {:ok, pid} = Wasmex.Components.start_link(%{path: "path/to/component.wasm"})
    
    # With WASI support
    {:ok, pid} = Wasmex.Components.start_link(%{
    path: "path/to/component.wasm",
    wasi: %Wasmex.Wasi.WasiP2Options{}
    })
    
    # With imports (host functions the component can call)
    {:ok, pid} = Wasmex.Components.start_link(%{
    bytes: bytes,
    imports: %{
     "host_function" => {:fn, &MyModule.host_function/1}
    }
    })
  2. Call exported functions:

    {:ok, result} = Wasmex.Components.call_function(pid, "exported_function", ["param1"])

Component Interface Types

The component model supports the following WIT (WebAssembly Interface Type) types:

Supported Types

  • Primitive Types

    • Integers: s8, s16, s32, s64, u8, u16, u32, u64
    • Floats: f32, f64
    • bool
    • string
    • char (maps to Elixir strings with a single character)
      char
      "A"  # or from a code point
      937  # Ω
  • Compound Types

    • record (maps to Elixir maps with atom keys)

      record point { x: u32, y: u32 }
      %{x: 1, y: 2}
    • list<T> (maps to Elixir lists)

      list<u32>
      [1, 2, 3]
    • tuple<T1, T2> (maps to Elixir tuples)

      tuple<u32, string>
      {1, "two"}
    • option<T> (maps to nil or the value)

      option<u32>
      nil  # or
      42
    • enum (maps to Elixir atoms)

      enum size { s, m, l }
      :s  # or :m or :l
    • variant (tagged unions, maps to atoms or tuples)

      variant filter { all, none, lt(u32) }
      :all     # variant without payload
      :none    # variant without payload
      {:lt, 7} # variant with payload
    • flags (maps to Elixir maps with boolean values)

      flags permission { read, write, exec }
      %{read: true, write: true, exec: false}
      # Note: When returned from WebAssembly, only the flags set to true are included
      # %{read: true, exec: true}
    • result<T, E> (maps to Elixir tuples with :ok/:error)

      result<u32, u32>
      {:ok, 42}      # success case
      {:error, 404}  # error case

Currently Unsupported Types

The following WIT type is not yet supported:

  • Resources

Support for the Component Model should be considered beta quality.

Options

The start_link/1 function accepts the following options:

  • :bytes - Raw WebAssembly component bytes (mutually exclusive with :path)
  • :path - Path to a WebAssembly component file (mutually exclusive with :bytes)
  • :wasi - Optional WASI configuration as Wasmex.Wasi.WasiP2Options struct for system interface capabilities
  • :imports - Optional map of host functions that can be called by the WebAssembly component
    • Keys are function names as strings
    • Values are tuples of {:fn, function} where function is the host function to call

Additionally, any standard GenServer options (like :name) are supported.

Examples

# With raw bytes
{:ok, pid} = Wasmex.Components.start_link(%{
  bytes: File.read!("component.wasm"),
  name: MyComponent
})

# With WASI configuration
{:ok, pid} = Wasmex.Components.start_link(%{
  path: "component.wasm",
  wasi: %Wasmex.Wasi.WasiP2Options{
    allow_http: true
  }
})

# With host functions
{:ok, pid} = Wasmex.Components.start_link(%{
  path: "component.wasm",
  imports: %{
    "log" => {:fn, &IO.puts/1},
    "add" => {:fn, fn(a, b) -> a + b end}
  }
})

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a new WebAssembly component instance.

Functions

call_function(pid, name, params, timeout \\ 5000)

@spec call_function(pid(), String.t() | atom(), [number()], pos_integer()) ::
  {:ok, [number()]} | {:error, any()}

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

Starts a new WebAssembly component instance.

Options

  • :bytes - Raw WebAssembly component bytes (mutually exclusive with :path)
  • :path - Path to a WebAssembly component file (mutually exclusive with :bytes)
  • :wasi - Optional WASI configuration as Wasmex.Wasi.WasiP2Options struct
  • :imports - Optional map of host functions that can be called by the component
  • Any standard GenServer options (like :name)

Returns

  • {:ok, pid} on success
  • {:error, reason} on failure