Open bcheidemann opened 1 year ago
I don't really have the expertise to make the best decision on this, I think. WASI does seem like a better approach than trying to tiptoe around the great mass of crates that won't ever be WASM-compatible, and your suggestion of at least trying it out on a branch and seeing what explodes seems like a great first step.
I don't really have the expertise to make the best decision on this, I think. WASI does seem like a better approach than trying to tiptoe around the great mass of crates that won't ever be WASM-compatible, and your suggestion of at least trying it out on a branch and seeing what explodes seems like a great first step.
@mpalmer I think that's a good approach :) I'll do some tinkering this weekend and see how I get on
I've had some success with compiling the binary to wasm32-wasi and consuming the resulting *.wasm
file from Node. It is able to log to stdout and stderr, and well as read the input file using the standard library, without any changes to the code (as are currently needed for JS support). However, I had some issues with the glob validation, which seemed to be unable to match files, and therefore always resulted in an error. Other than that issue, this seems like a promising direction for the CLI, but in order to support library usage (i.e. @action-validator/core), more investigation is needed. As I understand it, node-bindgen can be used with the wasm32-wasi compilation target and I did have some success with compiling trivial libraries, but ended up encountering a lot of nebulous build errors and haven't gotten close to being able to compile lib.rs to a usable "*.wasm" file.
Having done some more research into other options, the following may also be worth looking into:
As far as I know, these only target Node.js, and would rule out supporting other targets such as Deno, the browser, wasmtime etc. Maybe this is an acceptable trade-off if WASI is not yet a practical solution.
Following some discussion with @award28 and @mpalmer I am now leaning towards N-API as a solution to this problem and will re-focus my efforts in this direction.
Problem statement
The current implementation of
@action-validator/core
and@action-validator/cli
requires JS glue code for any kind of system access (e.g. network, filesystem, and even logging). This is not ideal since it means that certain crates are not (easily) usable by the WASM and for each case we need to find an alternative implementation for JS or use a different crate. This could result in an undue maintenance burden and the features supported by@action-validator/*
lagging behind the native binary.What is currently affected?
remote-checks
featurePossible solution (WASI)
WebAssembly System Interface (WASI) is a modular system interface for WASM which allows filesystem and network access directly from WASM code. Pivoting from WASM bindgen to using WASI has the following benefits:
WASI is currently well supported by RUST via the
wasm32-wasi
target and I have used it in a couple of smaller projects now with some success. I would suggest compiling to thewasm32-wasi
target and consuming the resulting*.wasm
binary usingwasi-js
, since this exposes the same API as is exposed by Node.js and Deno and can be easily removed in future when these APIs stabalise.Limitations (WASI)
The main limitation is that WASI is currently at the proposal stage and is not yet an official standard. Although relying on an unofficial standard isn't ideal, WASI seems to have a lot of momentum behind it and progress seems very unlikely to stall out.
@mpalmer I'd be interested to get your opinion on this? I think it would be worthwhile to at least do a PoC for this since it would likely solve the issue of supporting the
remote-checks
feature and glob validation with very little extra effort and reduce future maintenance burden of WASM/NPM support.Update (18/03/2023)
I had some difficulty trying to expose library methods to
@action-validator/core
using WASI. Having looked into alternatives, it may be better (for now) to pivot to building on the Node-API. The following packages are possible solutions:Limitations (Node-API)
The primary limitation of using the Node-API is portability. While a WASI build would (in theory) be compatible with any target which supports WASI (Node, Deno, Python, Wasmtime etc), a Node-API would only be compatible with Node.