G'day! It's a bit hard to understand what this is, because there's a lot of other stuff in the space. What I've written here is a WASI runner for the browser. I've also hooked up a terminal and virtual FS to it. WASI (WebAssembly System Interface) is a standard aimed at writing portable WebAssembly binaries that can run on servers, embedded devices, or locally on your computer. It's not really aimed at the browser. I went through and implemented the whole standard in TypeScript - then built this interface around that implementation so I could play with it.
One really neat thing here is how easy it is to write Rust that targets WASI. If you're into Rust, I'd recommend looking at the source of the demos and then trying out your own WASI binaries.
I ask because you didn't write that. I was excited that you said " I went through and implemented the whole standard in TypeScript" since I have been working on that same code [1] as the core of this npm package https://www.npmjs.com/package/wasi-js
and I've found some subtle bugs in it. I was excited to find another implementation to compare, so maybe you also did something else? Thanks!
This is a very exciting space and I greatly appreciate your work.
That's not the WASI runtime being used in this playground. The one in this playground is @runno/wasi-motor (https://github.com/taybenlor/runno/tree/main/packages/wasi-m...). I haven't released it as an NPM package, but it's all MIT so feel free to copy it.
Score another point for memfs, the in-memory node.js fe impl (which if Im reading this right underpins your wasi fs impl). https://github.com/streamich/memfs
WHATWG recently took up File System Access spec as their FS spec. It both looks semi promising, but they seem to only care about & are only building specs for specifically emscripten wasm users. Only sync apis, only usable from dedicated workers... there's some hopes for more latter but feels super weird to see the web finally get fs access & have it be fast... but for it to be extremely odd shaped hand tailored to a very narrow class of use.
Will look at the FS spec. I would hope that it would be shaped in a way that makes sense for WASI (brief look seems like it is). I'd also love it to be something that makes sense from the JavaScript side as well.
There is the .wit in "component model" proposal that is actively developing. Could you explain how it's going to make different between your work here without the .wit and with the .wit files?
Very cool. This is super relevant to me, I've been porting Trealla Prolog to WASI recently[1] and I've been considering moving from wasmer-js to libapps/wasi-js-bindings. This looks like a nice alternative as well.
I tried running Trealla (you can grab a binary from here https://wapm.io/guregu/trealla) and it seems to work but it doesn't echo any of my input text. Does this have the terminal in raw mode by default? I'm curious how this works given that WASI lacks termios.h.
I always thought a "Steam for text games/CLI apps" would be super cool (ala webassembly.sh) but the WASI spec is missing a lot of terminal-related things: https://github.com/WebAssembly/WASI/issues/161
Oh awesome!! I've just added Trealla to my issues list to add it to Runno.
If you go into settings you can switch stdin echo on/off. I have stdio devices set up to return their file type as "Character Device" (see: https://github.com/taybenlor/runno/blob/main/packages/wasi-m...). It seems like some binaries handle this well and act like they are directly connected to the TTY (e.g. my quickjs example). Not sure how they determine that. I'm very much coming at this from a web-developer interested in WASI direction, and not from any experience with OSes or linux.
Thanks! This project is super cool. Looks like it is well on its way to replace the broken polyfill at https://wasi.dev.
That makes sense about the stdio file type. I will play around with it and see what I can do. I think I need to copy whatever QuickJS is doing :)
I'll keep an eye on your WASI runtime. I was just about to start hacking on the same thing. Dropped a comment in your issue about Trealla as well. Let's make WASI in the browser awesome!
webassembly.sh is the prior art in this area. It has a package manager that will install binaries automatically. It seems like a poor terminal implementation however, since it uses prompt() for user input. If you rehost it setting the headers described here [1] then the problem is fixed
Yeah absolutely. Webassembly.sh was a big inspiration for my original build for Runno (https://runno.dev). The `prompt` issue is caused by code-rot, it used to work but then stopped working after browsers standardised a workaround for Spectre vulnerabilities in `SharedArrayBuffer`. Runno uses some neat tricks to get around this even when `SharedArrayBuffer` isn't available.
Part of the reason I started working on this playground was because I felt like the Wasmer WASI runner didn't work in the ways I wanted it to. Having a full end-to-end understanding of my WASI implementation has really helped, and I'm looking forward to moving Runno over to my new WASI runtime.
What's super neat here is that I didn't have to build that. The WASI standard defines `fd_fdstat_get` which tells the binary the type of the file descriptor. For stdin/stdout/stderr I return that it is a "Character Device" (https://github.com/taybenlor/runno/blob/main/packages/wasi-m...). QuickJS understands that means it's running in a TTY and so it emits all the right characters to do colouring. XTerm.JS then interprets those characters and displays the appropriate colours.
One really neat thing here is how easy it is to write Rust that targets WASI. If you're into Rust, I'd recommend looking at the source of the demos and then trying out your own WASI binaries.
Here to answer questions if anyone has any!