SodiumFRP / sodium-rust

FRP implementation in Rust
BSD 3-Clause "New" or "Revised" License
77 stars 11 forks source link

WebAssembly demo #39

Open dakom opened 5 years ago

dakom commented 5 years ago

Just putting this out there. not as a proper issue but more a discussion point

The past year has seen a ton of progress on the Rust -> Wasm front... specifically these crates: https://github.com/rustwasm/wasm-bindgen/tree/master/crates

However, it's all still very low-level for daily usage.

I just noticed yesterday that there's a new initiative to create more abstractions like one level up: https://github.com/rustwasm/gloo

Interestingly, things that are idiomatic in javascript - like "add a closure as an event listener to a dom node", are still fairly difficult to reason about since Rust needs to care about the lifetimes of all those different parts.

Ultimately, even for just regular dom stuff like a to-do list, FRP might be a very nice solution since the Cells can ultimately own what they need to (for example - the dom node, the closure, and the event listener, can all travel together in a struct that a Cell owns... right?)

I haven't played hands-on yet, just putting this out there for the backburner :)

clinuxrulz commented 5 years ago

Either way you will probably end up using RefCell to change from "compile time lifetime checking" to "runtime lifetime checking". The type system as great as it is, can only go so far. (In the case of Cell we would still need RefCell, because cells can fork out and only 1 mutater needs to be insured)

Nice to hear from you again, its been a while. :)

dakom commented 5 years ago

thanks :)

clinuxrulz commented 5 years ago

Off topic: wasm32-unknown-emscripten has sourcemaps for FireFox nightly! (I had no idea)

wasm32-unknown-unknown has no sourcemap support (presumably because it is for any wasm target, not just the web browser)

The file produced by wasm32-unknown-emscripten is a bit heavy though (file is a bit big).

dakom commented 5 years ago

interesting... I believe the recommended approach is to use unknown-unknown though, and there's various tooling out there to strip it even further

but being able to debug in the browser with hints back to the rust source would be amazing!

clinuxrulz commented 5 years ago

A python script for generating sourcemaps for wasm32-unknown-unknown (the llvm backend)

https://chromium.googlesource.com/external/github.com/kripken/emscripten/+/1.38.11/tools/wasm-sourcemap.py

Plus example: https://github.com/yurydelendik/old-man-sandbox/blob/master/rust-wasm-hey/README.md

Things are getting exciting. Gotta sleep though, nyt!

clinuxrulz commented 5 years ago

Just a thought, if it were possible to model a full application using just 1 listener, then that one listener can capture (by move) all the mutable objects and be the one and thing holding those mutable objects. Which would eliminate all that Rc<RefCell<>> stuff everywhere. Just don't know how easy it is to work with just a single listener.

The single listener would need to be like a message passing system where there is a huge union type of all messages used by the application.

I.E. Stream<Either<A,B>> is isomorphic to Tuple<Stream<A>,Stream<B>>.

dakom commented 5 years ago

Sounds doable with any immediate-mode rendering, whether that be WebGL or through a vDom... vdom just needs to be fast :)

clinuxrulz commented 5 years ago

Its nice to have sourcemaps for wasm, but feels like more is required to debug it productively.

Would really like to see something like DWARF for wasm, even as a separate file that gets loaded at the same time as the wasm file. That would allow us to inspect the values of variables just as we can for regular javascript debugging.

But browser support for DRAWF? I would not hold my breath. Even just a javascript library providing a api for handles DRAWF, and being able to fully inspect variables on the console would be enought. Could be an interesting side project.

clinuxrulz commented 5 years ago

OK.... CyberDRAWF, seems someone has already done it:

https://emscripten.org/docs/debugging/CyberDWARF.html

clinuxrulz commented 5 years ago

wasm can now be debugged outside the browser via wasi. https://hacks.mozilla.org/2019/09/debugging-webassembly-outside-of-the-browser/ Source maps and the ability to inspect/change-value-of rust structs at runtime.

If a webview can be hooked up to wasi, then wasm run can be debugged properly before it is delivered to the browser.

clinuxrulz commented 4 years ago

The debugging situation is improving a little:

https://developers.google.com/web/updates/2019/12/webassembly

I'm currently working on a version 2.0 sodium rust version, with a bit of a less cluncky api (more Typescript style avoiding all those GC wrappers).

clinuxrulz commented 4 years ago

Not trying to self-promote, but more due to do with it being related the first commit at the top of this issue. This is more for other people who get here via google search, as dakom already knows about this technique. Rust being painful to use with listener pattern. Possible solution: https://github.com/clinuxrulz/idom-sodium-todo-mvc You'll see app.ts has zero listeners in it, and it is using sodium. So it is possible to create a sodium-powered incremental DOM library for rust that does not need the end-user to deal with listeners.

clinuxrulz commented 4 years ago

@dakom, I might be returning to Rust soon. I can see some free time in my future. And have an idea, and thought I'd see what you think. I can see you are quite an experienced Rust person now with all the code you have written.

OK. So here it goes.

How to enable full debug support for web-apps written in Rust

Its sort of like. Debug outside the browser, but still render to the browser. Then on production build, execute just in the browser.

dakom commented 4 years ago

hey @clinuxrulz, good to hear from you!

Yeah I have been doing much more Rust lately... still getting the hang of it, slowly but surely

Fwiw I'm finding the debugging experience in the browser itself to be fine, though I do a lot of "printf(ln!)" style debugging... wasm-logger gives line numbers and color-codes difference between info, warning, etc. and console_error_panic_hook gives better errors on panic

clinuxrulz commented 4 years ago

Funny thing, there were some gc bugs in Sodium Rust v2.0 that I could only solve with printf debugging, even with full debug support. printf debugging let me draw pictures of the graph which made it much easier to debug than using breakpoints and looking at single values.

clinuxrulz commented 4 years ago

quick question: wasm_logger::init(wasm_logger::Config::new(log::Level::max())); or wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); does not seem to capture trace!, but will capture info! and a few others. Not a big issue. Have you managed to capture trace!?

dakom commented 4 years ago

You need to set the log level to "Verbose" in Chrome DevTools to see it (not sure about other browsers)

Internally wasm_logger is using console.debug() for trace

image

clinuxrulz commented 4 years ago

I've got an incremental DOM comming together for something elses I'm working on. It might be a good wasm demo for sodium rust.

https://github.com/clinuxrulz/sdo/blob/master/src/dom_ctx.rs

It works the same way as the DomCtx in the idom Todo list TypeScript demo.

Still trying to work out how to keep closures alive long enough without leaking them. web_sys is not exactly user friendly. Which is understandable since it is automatically generated from the spec, the spec of which is designed around a different language.

clinuxrulz commented 4 years ago

rust-analyzer will be faster than RLS. If your looking for an alternative.

See: https://www.theregister.co.uk/AMP/2020/04/28/rust_analyzer_compiler/

teohhanhui commented 3 years ago

It'd be really nice to have a Cycle.js equivalent in Rust / Webassembly.

For the vdom, looks like there's virtual-dom-rs which is part of Percy: https://github.com/chinedufn/percy/tree/master/crates/virtual-dom-rs