Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
src
test
README.md
jest.config.js
package-lock.json
package.json
rollup.config.js
tsconfig.json

README.md

@wasmer/wasi

Isomorphic Javascript library for interacting with WASI Modules in Node.js and the Browser. 📚

Table of Contents

Features

This project is forked from node-wasi, a Node implementation made by Gus Caplan. 🙏😄 It uses the same API than the future WASI integration in Node, to help transition to it once it becomes available in Node.

However, @wasmer/wasi is focused on:

  • Bringing WASI to an Isomorphic context (Node.js and the Browser) 🖥️
  • Make it easy to plug in different filesystems (via wasmfs) 📂
  • Make it type-safe using Typescript 👷
  • Pure JavaScript implementation (no Native bindings needed) 🚀
  • ~ 15KB minified + gzipped 📦

Installation

For instaling @wasmer/wasi, just run this command in your shell:

npm install --save @wasmer/wasi

Quick Start

This quick start is for browsers. For node, WasmFs is not required

import { WASI } from "@wasmer/wasi";
import { WasmFs } from "@wasmer/wasmfs";

// Instantiate a new WASI Instance
const wasmFs = new WasmFs();
let wasi = new WASI({
  args: [],
  env: {},
  bindings: {
    ...WASI.defaultBindings,
    fs: wasmFs.fs
  }
});

const startWasiTask = async () => {
  // Fetch our Wasm File
  const response = await fetch("./my-wasi-module.wasm");
  const responseArrayBuffer = await response.arrayBuffer();

  // Instantiate the WebAssembly file
  const wasm_bytes = new Uint8Array(responseArrayBuffer).buffer;
  let { instance } = await WebAssembly.instantiate(wasm_bytes, {
    wasi_unstable: wasi.wasiImport
  });

  // Start the WebAssembly WASI instance!
  wasi.start(instance);

  // Output what's inside of /dev/stdout!
  const stdout = await wasmFs.getStdOut();
  console.log(stdout);
};
startWasiTask();

For a larger end-to-end example, please see the wasm-terminal package.

Reference API

new WASI(wasiConfigObject)

Constructs a new WASI instance.

The Config object is is as follows:

let myWASIInstance = new WASI({
  // OPTIONAL: The pre-opened dirctories
  preopenDirectories: {},

  // OPTIONAL: The environment vars
  env: {},

  // OPTIONAL: The arguments provided
  args: [],

  // OPTIONAL: The environment bindings (fs, path),
  // useful for using WASI in diferent environments
  // such as Node.js, Browsers, ...
  bindings: {
    // hrtime: WASI.defaultConfig.bindings.hrtime,
    // exit: WASI.defaultConfig.bindings.exit,
    // kill: WASI.defaultConfig.bindings.kill,
    // randomFillSync: WASI.defaultConfig.bindings.randomFillSync,
    // isTTY: WASI.defaultConfig.bindings.isTTY,
    // fs: WASI.defaultConfig.bindings.fs,
    // path: WASI.defaultConfig.bindings.path,
    ...WASI.defaultConfig.bindings
  }
});

And returns a WASI Instance:

console.log(myWASIInstance);
/*

Would Output:

{
  memory: WebAssembly.Memory;
  view: DataView;
  FD_MAP: Map<number, File>;
  exports: Exports; // WASI API to be imported in the importObject on instantiation.
  bindings: WASIBindings;
  start: (wasmInstance: WebAssembly.Instance) => void; // Function that takes in a WASI WebAssembly Instance and starts it.
}
*/

WASI.defaultBindings

The default bindings for the environment that are set on the bindings property of the constructor config object. This is useful for use cases like, you want to plugin in your own file system. For example:

const myFs = require("fs");

let wasi = new WASI({
  preopenDirectories: {},
  env: {},
  args: [],
  bindings: {
    fs: myFs,
    ...WASI.defaultBindings
  }
});

Contributing

This project follows the all-contributors specification.

Contributions of any kind are welcome! 👍

You can’t perform that action at this time.