Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

easywasm/wasi

Repository files navigation

easywasi

A working, zero-dependency implementation of WASI preview1, with lots of filesystem options. It will work in places other than a browser, but that is the primary target. It's easy, light, simple, effortless to modify/extend, and should work with any WASI-enabled wasm and any modern js runtime.

If you need framebuffer/audio/input WASI devices, check out web-zen-dev.

install

Install into your bundled project with npm i @easywasm/wasi. You can also use it on the web, directly from cdn:

<script type="module">
 import WasiPreview1 from 'https://esm.sh/@easywasm/wasi'
</script>

And I like to use sourcemaps:

<script type="importmap">
 {
 "imports": {
 "@easywasm/wasi": "https://esm.sh/@easywasm/wasi",
 "fflatefs": "https://easywasm.github.io/wasi/fflatefs.js",
 "fflate": "https://esm.sh/fflate/esm/browser.js"
 }
 }
</script>
<script type="module">
 import { WasiPreview1 } from '@easywasm/wasi'
</script>

usage

You can use it without a filesystem, like this:

import WasiPreview1 from '@easywasm/wasi'
const wasi_snapshot_preview1 = new WasiPreview1()
const {
 instance: { exports }
} = await WebAssembly.instantiateStreaming(fetch('example.wasm'), {
 wasi_snapshot_preview1
 // your imports here
})
wasi_snapshot_preview1.start(exports)

To really unlock it's power, though, give it an fs instance.

I used to use zenfs, but it seems broken every time I try, now. I think they intend that you use packaging and stuff, but I just want to import functional things from the web/cdn. In my opinion it's non-functional.

Now, i use a much simpler approach:

import WasiPreview1 from 'https://esm.sh/@easywasm/wasi'
import fflatefs from 'fflatefs'
const fs = await fflatefs('fs.zip')
const wasi_snapshot_preview1 = new WasiPreview1({ fs })
const {
 instance: { exports }
} = await WebAssembly.instantiateStreaming(fetch('example.wasm'), {
 wasi_snapshot_preview1
 // your imports here
})
wasi_snapshot_preview1.start(exports)

This implements the bare-min statSync/readFileSync. If you want more functionality, implement more, but that is all you really need to read files.

Have a look in example to see how I fit it all together.

Keep in mind, you can easily override every function yourself, too, like if you want to implement the socket-API, which is the only thing I left out:

import { defs, WasiPreview1 } from '@easywasm/wasi'
class WasiPreview1WithSockets extends WasiPreview1 {
 constructor(options = {}) {
 super(options)
 // do something with options to setup socket
 }
 // obviously implement these however
 sock_accept(fd, flags) {
 return defs.ERRNO_NOSYS
 }
 sock_recv(fd, riData, riFlags) {
 return defs.ERRNO_NOSYS
 }
 sock_send(fd, siData, riFlags) {
 return defs.ERRNO_NOSYS
 }
 sock_shutdown(fd, how) {
 return defs.ERRNO_NOSYS
 }
}
// usage
const wasi_snapshot_preview1 = new WasiPreview1WithSockets({ fs })
const {
 instance: { exports }
} = await WebAssembly.instantiateStreaming(fetch('example.wasm'), {
 wasi_snapshot_preview1
})
wasi_snapshot_preview1.start(exports)

Have a look at WasiPreview1 to figure out how to implement it, if you want things to work differently.

inspiration

  • this article has some nice initial ideas
  • this article has some good WASI imeplentations
  • browser-wasi-shim has a very nice interface, and this is basically the same in JS, but using more extensible filesystem, and I improved a few little things.

About

A working, zero-dependency implementation of WASI preview1, with lots of filesystem options.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

AltStyle によって変換されたページ (->オリジナル) /