Try out my example
The module is still being developed and will probably go through major changes.
If you want to try it, you can clone the repo and run these commands from the
# install dependencies npm install # start example with linux npm start # start example with windows npm run start:win
The overarching goal is to close the loop between writing Elm code and interacting with it. This concretely means:
- Code changes should be reflected immediately in a running instance of its application.
- Code changes should only break application-state if necessary, and if enabled, only partially.
- Application-states should be effortless to inspect, navigate, persist and share.
- Guidance from the compiler should be right in front of you when you make mistakes.
- The boilerplate necessary to enable the first four goals should be minimal, and if needed be, incremental.
I strongly believe that the optimal design and implementation of these goals will transform how we build our applications. Going through the loop of compiling code, reloading browser windows and getting the application into the right state costs seconds, but those seconds are spent at such a frequency that writing interactive applications is incredibly time-consuming. I hope it doesn't have to be.
These devtools are based on the Elm architecture. Since programs are constructed using a few simple functions, they can be embedded and controlled, which also sets some limits for what these devtools can do.
Automatic Message Replay
Any previous state of an application can be recomputed using the initial state and a list of messages folded by an update-function. These state-transitions happen independently of their environment - no commands are sent during replay, only the state changes. This is very useful to:
- Stop time to look at what happened.
- Go to a previous point in time to try something else.
- Reload without losing the state of your application.
- Reload with code changes but only partial (or no) loss of application state.
These devtools run in sessions. A session is essentially made up of:
- devtools settings and state.
- all messages that ever updated the debugged applications state.
Sessions keep track of what your doing during development. They persist through browser-reloads, code-changes, can be downloaded, sent, opened by collaborators, and submitted as bug-reports.
Support for Code-Changes
To reliably support code-changes in sessions, it is essential that interactions are recorded rather than states. Interactions are modeled in Elm applications with a single type, usually called
Msg. Let's do an example:
type Msg = Increment | Decrement update msg count = case msg of Increment -> count + 1 Decrement -> count - 1 state = List.foldl update 0 [ Increment, Decrement, Increment ]
If you run this example, the value of
state will be
Refactor this into an application, and devtools would deal with changes to this code in different ways:
Msgwas given another constructor, called
Reset -> 0, the value of
Decrementremoved (or changed), one of three strategies (of your choice) could be used:
- Restart the application, as
Decrementhas no meaning in the program anymore. The value of
0, and we've accomplished nothing. This is how most web-app development works.
Decrementout of the list and update accordingly. The value of
2. This works better or worse depending on the coupling between the updates your messages perform. If you remove
ViewAccountto work, you will be dissapointed.
- Take messages until you reach the first
Decrementand update using those. The value of
1. This is really great, as it captures the remaining valid sequence of updates the application could do. If
LogIngoes away, you'll never try to
- Restart the application, as
updateis changed, any sequence of messages will still be (generally) valid.
Incrementmight do a
+ 2instead, but messages still capture your interactions, so you can tweak
updateuntil it works as intended. You can tweak
subscriptionsin the same way.
By recording interactions rather than state, Elm applications can be written while running, and you will only ever have partial to full state-loss when you modify the definition of messages, which is the very definition of making those interactions impossible or different.