xmtp / libxmtp

MIT License
33 stars 13 forks source link

Tracking: WASM Bindings (Group Chat Prod - Web) #557

Open nplasterer opened 3 months ago

nplasterer commented 3 months ago

Must Have

bwcDvorak commented 3 months ago

Github, your 'convert to item' did me dirty when it came to converting issue 564, formerly a task about making the WASM bindings with a reference to an external URL. Apologies @nplasterer - can you please edit the correct title back into that issue?

nplasterer commented 3 months ago

@bwcDvorak I think that item is just a header and doesn't need to be an issue. I restored it from the edit history. It was just linking out to the repo that will help with the bindings.

bwcDvorak commented 3 months ago

TYVM!

neekolas commented 1 week ago

We've talked a lot about WASM bindings in terms of "make everything happen in Rust". The two sticking points are disk access (SQLite) and networking (GRPC Gateway or GRPC Web). To access the device APIs to do this in Rust, we'd need to use WASI. WASI is very bleeding edge, and making it work in a full-featured app that supports things like async and streaming, is going to be a big lift.

We haven't spent a lot of time discussing the other alternative to make libxmtp work on the web: doing all this work in JS. WASM (without WASI) supports calling into JS functions from Rust. We already have a trait for the API layer, where we could implement it in Javascript and write a JS -> Rust binding to expose an implementation of that trait (or use the pre-existing fetch API binding that already exists as part of web-sys) to write some of the business logic in Rust on top of the fetch API. We would then need to convert our storage layer into a trait, and likely refactor a bunch of our code that deals with things like transactions to support a generic storage interface that could be implemented in JS using IndexedDB.

Risks:

I don't think we know enough yet for me to advocate for this solution. But it's a much clearer path than WASI and probably deserves a spike to derisk.

insipx commented 1 week ago

Wasm runtimes support Host Functions. This seems to be similar to this, where we would expose a rust trait that JS needs to implement and pass host functions into the generated WASM blob. These host functions would generally be write/read etc, whatever SQLite normally does in the rust code. Could be very close to the trait Cryspen made for OpenMLS. This would require a bit of work on the JS side, but it does circumvent the need for WASI, at least until its in a more stable state.

The downside here is we would need to convert all our sqlite insert/read code to a generic trait and implement it on the rust side too.

neekolas commented 1 week ago

The fact that wasm_bindgen supports really complicated browser APIs in web-sys (it can do things like use WebGL) gives me hope that the host function support is pretty mature and full-featured.