Giter Site home page Giter Site logo

Comments (9)

kspeakman avatar kspeakman commented on June 15, 2024 1

@MangelMaxime My response was a bit robotic. Thank you for providing a stop gap solution. Saw you on some commits when I dug into Elmish.HMR this weekend. Y'all are awesome. And I'd like to contribute something too.

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024 1

@et1975 I have some ideas now and I would be glad to help with this.

from elmish.

MangelMaxime avatar MangelMaxime commented on June 15, 2024

One way, to workaround the problem is to setup your event listener inside of a React hooks.

This way you can create the listener and have it disposed when the component is not loaded anymore.

There is an example using Fable.React syntax in this blog post. If you are using Feliz, the principle is the same.

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024

I don't like this approach. It leaks react OO / framework stuff into user code. I'd rather add to Elmish's capabilities if we can find the right abstraction.

from elmish.

et1975 avatar et1975 commented on June 15, 2024

Current beta lets you do something like that albeit not at subscription, but at the program level - via termination handler.
You could craft a sub-program for a page if you want to go that route.

Doing it via subscriptions though is a bit trickier - the problem with letting elmish itself decide when to call unsubscribe cannot be glassed over, since elmish is platform-agnostic we need to let the subscription itself decide when to to that.

This is one of the aspects that came out of #183, the plan is to reimplement subscriptions and make them more Elm-like in a way that would let a subscription body decide, based on the current state, if it wants to suspend handling the external events. And the next model change should be able to resume to keep subscriptions management as simple as it is in Elm.

I took a stab at it but it needs more time than I'm currently able to spend on it. There are several challenges:

  • it requires "upsert" semantics and either the complexity is offloaded into the subscription or each sub would need an "identity" - getting every state change as input into the sub we need to avoid creating multiple handlers on underlying emitters, so in you example elmish would need to execute listener a) idempotently and b) be able to enact changes over time.
  • the subs need to remain composable - like views, there's parent-child composition we need to be able to express

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024

Doing it via subscriptions though is a bit trickier - the problem with letting elmish itself decide when to call unsubscribe cannot be glassed over, since elmish is platform-agnostic we need to let the subscription itself decide when to to that.

I agree. I was initially thinking of HMR, and that Elmish needs to be aware of running subs for transparent cleanup. But the user should have agency to stop them as well as start them. Other platforms have hot reload now, right? (Been a long time since I did other than web and apis.) Usable for them as well.

Just running the subscription fn with current model is easily possible now.

module App =
    let subscriptions currentModel : Cmd<Msg> =
        ...

let liveSub (model, cmd) =
    model, Cmd.batch [ App.subscriptions model; cmd ]

Program.mkProgram (App.init >> liveSub) (App.update >> liveSub) App.view
...

But this does not handle unsubscribes. That's why I open the issue.

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024

I dug into Elm's source. Subs essentially run Tasks. Long-running tasks return their own stop fn like in my OP, so they can be stopped with Process.kill. Tasks can also stop themselves by running the provided callback fn, which is otherwise analogous to dispatch. The Elm HMR module I found monkey-patches Elm's task/scheduling fns to capture the Task stop fns and call them on hot reload.

Subs are data (kinda -- plus msg tag fn). Subs are centrally tracked *. Which is why they can be canceled by just not returning one next time subscribe is called. Subs eventually create Tasks. Bear in mind that Task return values are constrained to be Result-like. AFAICT a task emits exactly 1 msg and only on its exit. To send multiple msgs, the task has to spawn additional tasks. To send zero msgs, the task has to run indefinitely until killed.

* Tracking. The compiler/platform tracks subs by the module which created it. E.g. Time.every belongs to Time module. These are called effect modules, use the keyword effect and provide fns like onEffect to handle sub changes. Whenever a call to subscribe returns different (I assume) subs than last time, the platform calls each affected (I assume) module's onEffect with all its current subs and its state (similar purpose to model). The module then compares the updated subs with its previous state and then starts or stops tasks as needed and updates state. Time, for example, uses 1 task per interval, then each interval has a list of "taggers" that will receive msgs when the interval fires. Of course, effect modules can only be created by the Elm inner circle.

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024

Do you want me to close this and work under other issue? Or work under this one?

from elmish.

kspeakman avatar kspeakman commented on June 15, 2024

Closing as duplicate of #183

from elmish.

Related Issues (20)

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.