#Can't decide what to create: custom "Dioxus platform" or a custom renderer

1 messages · Page 1 of 1 (latest)

opal valve
#

I gotta make a dissertation and there is a possibility that I can use Dioxus in some way, which is super cool. But a key thing is that I have to make something completely on my own.

I showed to professor all of the 7 platforms Dioxus has. He said that the topic is good, if I can, for example make a new module/platform. But there is an obvious problem with this: what this platform is for? Pretty much everything already is covered (even the TUI!). I mean, I can in theory just recreate a TUI platform from scratch, but this can be one of the backup plans.

I remembered that there is https://dioxuslabs.com/awesome and there is even a renderer category! And the suddenly an idea popped into my head: what if I make a library/renderer, that allows you to render screenshots/screen state directly in Wasm and then included directly in a Typst document. For this I need to know some basic stuff like:

  1. Can a Dioxus rsx page rendering (to an SVG/PNG/JPEG) be accomplished fully in Wasm? With some tools? Or is the best thing I have is a headless browser (like a Python Selenium or Splinter) with Wasm support?
  2. What are the ways to manipulate input (keyboard and mouse)?
    The way I see it: I compile a normal Dioxus Web app that produces Wasm file and some assets. Ideally I would embed all the assets in the Wasm. Then I would call a Wasm program, that can receive the Wasm file created with dx build -r (including or also separately all the asset files). That program will then render the page and created the needed state. Lastly, it will save the rendered page with the state to an image and return the raw image. Then I simply would call image.decode(raw_image, format: "...") in Typst and that's it. I included a Dioxus app screenshot without any intermediate files and tools (everything is in-memory). Typst can run Wasm modules directly, so that Wasm program would ideally be called from Typst code. BTW, do we have some "image renderer"?

Would love to hear some ideas on this.

terse wigeon
#

The TUI platform is not updated for the latest version of Dioxus and no longer supported. Updating it and maintaining it would be extremely useful

Blitz should be able to render to an image fairly easily. Blitz uses the vello render which has an example of rendering to an image instead of a the screen. We would just need to graft that into the renderer. This would be very useful for previews/tests

#

Other potentially interesting topics:

  1. Server Signals: How can server functions be modified to make it possible to send Signal<impl Serde> in a server functions? (Probably with CRDTs?)
  2. Static analysis: There is a ton of different lints that would be useful to provide in dx check with static analysis, but our system isn't set up to handle complex lints. We have a visitor over the AST. We need something more complete like clippy
opal valve
#

I meeean... XD

#

The first one is something I'm very far from, but the second sounds kinda cool.

opal valve
#

Blitz should be able to render to an image fairly easily.
I tried the screenshot example and it kinda works. 2 main problems: as I correctly remembered, it uses the Stylo that has a very limited CSS support, so dioxuslabs.com shows kinda scratched and duckduckgo.com is just a white page; and also I can't compile it to musl, and therefore to Wasm, IIUC.

opal valve
terse wigeon
opal valve
#

Can you also elaborate on the TUI support? Does this mean we won't have TUI at all? Is Dioxus TUI not a thing anymore? I still can create a project with it: dx init -t gh:ealmloff/dioxus-template --branch dioxus-0.6, so do you need to remove it from the 0.6 template?

opal valve
terse wigeon
#

The TUI platform was moved to the blitz repo and then removed

opal valve
#

So it's not supported because it's very niche and already was failing?

#

Hmm, the src is pretty small, even though I don't understand most things after skimming. Is this really all that is needed for a platform to work (in the past)?

#

I definitely can try reviving TUI if that's all it takes, more or less.

terse wigeon
#

Yes, there were no major applications using it

#

It relies on native-core which also (mostly) no longer exists. native core handles most of the binding bits

#

I think freya has a more updated version of native core

opal valve
#

ok, 5900 lines of code is... just a tiny bit too much. I thought that plasmo is something like ratatui and nothing crazy is needed. Oh, great... plasmo uses ratatui. And crossterm.

#

So the wrapper for the ratatui is 6k LoC... wow.

#

But realistically, are most things reusable or literally everything is broken? And how hard would it be to make everything from scratch? I see that the native-core thingy is 3.7k LoC... bruh

opal valve
terse wigeon
#

I think the version of native core in freya works in 0.6

terse wigeon
#

They accept mutations and give events to dioxus

opal valve
#

Will it be easier/better for me to make TUI the same way architecture/dependencies-wise as other platforms?

#

So I won't have to depend on native-core (in the end)?

#

Do I also need the native-core-macro crate?

terse wigeon
#

If you want a TUI platform that performs well and isn't html compliment, then I think it would be easiest to restore the existing TUI renderer. The updates shouldn't be that big

opal valve
#

I guess if I can make it just work (if the freya-native-core works) at first, then I have something happening. Then I can transfer and rewrite code to be more like up-to-date platforms.

terse wigeon
#

For more HTML compliment rendering, a TUI backed by blitz would be better

#

If you don't care about html compliance, performance, or features like widgets, it might be easier to get a basic TUI platform working without native core. (see https://github.com/DioxusLabs/dioxus/pull/329 for performance before/after native core)

opal valve
#

Since there are plenty of LoC, I think this almost automatically means that this is a dissertation-worthy project. Plus, as I said at the start, he said that it would be acceptable, if I make my own platform/module in Dioxus. This is exactly that.

terse wigeon
#

other platforms didn't use native core because they have their own styling engines. You don't need to figure out the color of every character of text in the browser. The browser does that for you

opal valve
terse wigeon
#

Yes

opal valve
#

Can you please briefly describe what is inside native-core? Some custom styling engine that works for TUI and something else?

terse wigeon
#

It is an incremental ECS tree

#

You can attach data to each node in the tree and define systems that derive data from the root data

copper pecan
terse wigeon
#

This is mainly used for styling

opal valve
terse wigeon
#

Eg. you define attributes in rsx and then derive the computed styles from those attributes

#

If you define them with native core, then they will automatically be computed incrementally

copper pecan
#

( I don't remember why, I guess it got removed ? )

terse wigeon
#

Yep, it was removed

copper pecan
#

I see

#

but yeah

terse wigeon
#

It isn't something we could actually know at compile time

copper pecan
#

just that

#

rest should work on 0.6

opal valve
#

Damn, I got an info overload. But thanks for the help. I will pitch this idea (and maybe other too) to the professor, and we'll see what happens. Right now, I'm torn between some Typst packages and something from Dioxus, mainly.

opal valve
opal valve
#

Can you pass a Signal right now? Only of primitive/non-bound type?

terse wigeon
#

You can currently only pass values that are Serialize and Deserialize

#

Passing a signal would require a way for the server and client to share a mutable value

opal valve
#

Hmm, I think the general concept of passing signals to server function is very handy if you do:

fn server_function(username: String, status: Signal<String>) -> impl Html {
  // search for a username in a DB
  let response = match found {
    true => "found",
    false => "not found",
  }
  *status.write() = format!("statuts update: {response}");
  response.into() // or some other data and/or HTTP code
}
opal valve
#

But an interesting problem.

terse wigeon
#

Passing signals to server functions almost gets you to liveview

#
fn server_function(username: String, status: Signal<String>) {
  loop {
      sleep(100);
      *status.write() = format!("statuts update: {response}");
  }
}
#

It lets you drive your UI from the server like liveview

opal valve
terse wigeon
#

but events are still handled from the client

opal valve
terse wigeon
#

Yes which would be much better in my opinion

#

It could work on desktop easily, and you still get sync event handling

#

Just hand off state to the server whenever you really need to

opal valve
#

I'm trying to think of a more realistic example. Judging by the loop, I guess the simplest example would be a progress bar? Didn't really think about it, but it should be pretty hard/hacky to accomplish with regular HTTP.

#

I just read another great example — real-time chat and such.

#

This means that currently for real-time stuff you have to use LiveView, right? Which has a drawback of missing SSR and also putting off all the work to the server. With a new hybrid approach, you would be able to have SSR, client-side logic, server functions and WS channel.

copper pecan
#

Would be cool to have a "make your own renderer" technical post

#

maybe even a series of it