Giter Club home page Giter Club logo

valerie's Issues

state::change needs to be able to replace with a new node

The router works like an a singleton of an enum that represents the route options.

When the onpopstate event is received, a component local state (eg. Atomic*) will be set to the new route.

This requires that the state objects need to be able to replace themselves with an entirely new component, with their own children and channels.

enum Routes {
    Login,
    Home,
    Post(PostID),
}

impl Default for Routes {
    fn default() -> Self {
        Self::Login
    }
} 

impl From<Url> for Routes {
    fn from(self) -> Routes {
        // ...
    }
}

fn router() -> Node {
    use Routes::*;
    let router = StateMutex<Routes>::new(); 
    HistoryService::route(router); // set up async monitor of the history API, convert url to Routes and send changes to `router`
    div!(
        router.formatter(|r| {
            match r {
                Login => login(),
                Home => home(),
                Post(id) => post(id),
            }
        }
    ).into()
}

What this requires is that StateMutex can take a closure returning a node which can replace the existing node.

Is this already in place, but I don't understand how to do this? or does it require an enhancement?

Any thoughts?

Bringing States to Attributes and Css

Issue created to brainstorm on this topic.

An initial idea is to bring States to attributes and CSS probably with functions, bind_attr and bind_css. I need some opinions.

Server side rendering?

Just curious about SSR and where Valerie stands on it. I imagine it's not possible now, but would it require massive changes to make it possible? Would work towards SSR be in line with the project goals?

JavaScript interop

Is JavaScript interoperability a goal?
I personally don't think it is needed and shouldn't be added if it would add complexity to the framework.
Anyway I think it would be important to have this (JavaScript interop as a goal, or not, and the reasons why) stated in the readme.

input_state example is not showing the value

Describe the bug
I was running the input_state example , but it's not showing the value in browser when I type in text box. ( attached screenshot)

To Reproduce
Steps to reproduce the behavior:

  1. git clone the latest version as of 26th July
    2.go to input_state example and create a static folder and insert the html.
    <!doctype html>
<title>Title</title> <script type="module"> import init from "./wasm.js" init() </script>
  1. run miniserve and go to http://127.0.0.1:8080/static/index.html

  2. type the text box with some characters.

  3. I thought it will be reflecting value , but its not.
    input_state_example

Clean up state listeners when a node is removed

Currently state bindings to nodes are permanent, meaning that even if the node is removed from the DOM (user navigated to a different route, deleted the list item, closed the dialog, etc) it will still stay in memory and will still be updated whenever its state dependencies are updated. Naturally in some cases this could lead to excessive memory usage and slow page performance.

Here's my thinking on this issue, based on past experiences. Feel free to go a different way if you prefer.

Depending on the intended browser support, this might be a great use case for the new-ish MutationObserver API, which will execute a callback function whenever an element is removed from the DOM. I have heard of performance issues with this API in the past but they've hopefully gotten ironed out by now. If it's still too heavy, Valerie itself could track when State-bound elements are removed by the library itself, although this could lead to hard-to-find memory leaks when users circumvent Valerie and modify the DOM directly in their code.

The second issue is how to actually remove the state listeners. JS has no way of cancelling an await -- once a Promise is awaited, the calling async function will remain in memory (and take some CPU cycles) until that Promise gets resolved. So, this approach would work but have a potential memory and performance cost:

let mut old = StateId::new();
while let Some((new, value)) = stateRx.receive(old).await {
  if (element_was_removed(elem)) {
    break;
  }
  // ... perform element update ...
  old = new;
}

A safer solution would use a second channel that emits when the element is removed. Something like:

let mut old = StateId::new();
while true {
  let next_event = future::select(stateRx.receive(old), destroyedRx.receive(old)).await;
  match next_event {
      Either::Left((x, b)) =>{
        // ... perform element update ...
        old = new;
      },
      Either::Right((y, a)) => break,
  }
}

This will run the next loop iteration when either a) the state is updated or b) the element is removed. In practice I don't know if this actually ends up being more performant. It is safer in that elements that have been removed will no longer take up any resources, but heavier in that all state listeners must now listen to two different Futures.

Lastly there's the issue of where to store extra data about Nodes, in this case the destroyed state for each one (destroyedRx in the example above, or whatever boolean drives element_was_removed above that). As far as I can tell JsValues cannot be used as the key for a Set or HashMap, so I don't know how well a global datastore inside Valerie would work. That leaves storing the data in the DOM tree itself as the best option, either as HTML attributes or just as additional JS properties tacked on to the Node object. Both have pros and cons, and both specifically have the con that the stored values must all be JS-safe, eg. a Promise instead of a Future. There might be a hybrid approach that works, like storing an index somewhere on the JS object and then using that index as the key to a global datastore inside Rust. Honestly I have no idea which one would perform the best, I have a lot of JS development under my belt but I'm still fairly new to Rust (hopefully that isn't too obvious :) )

Bringing stpl?

Should we bring stpl to Valerie?

https://docs.rs/stpl/0.5.0/stpl/

Because as valerie progresses we might have templates and UI component libraries. Macros might not be a good solution when there are two buttons one a normal button! and one maybe a material button!, because of the global scope of macros.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.