mccraigmccraig

mccraigmccraig

Removing the state-machines from a LiveView

I’ve been playing with an idea for LiveView… I wanted fast tests of LiveView page logic - which isn’t really possible while the logic is mixed up in the LiveView.

PageMachine is the result - it’s very much a WIP and hasn’t seen any real use yet.

It models the page logic as a collection of concurrent Spindles - coroutine-based state machines which manage state and effects for the LiveView.

defmodule MyApp.CheckoutSpindle do
  use Skuld.Syntax
  alias MyApp.StoreContract.Checkout

  defcomp run(product) do
    {:ok, _} <- MyApp.Inventory.reserve(%{product: product})
    %Checkout.ShippingEvent{shipping: shipping} <- Checkout.Yield.shipping()
    %Checkout.PaymentEvent{payment: payment} <- Checkout.Yield.payment()
    {:ok, order} <- MyApp.Orders.place(%{product: product}, shipping, payment)
    {:ok, order}
  else
    {:error, :sold_out} -> {:error, :sold_out}
    {:error, reason} -> {:error, reason}
  end
end

The Spindle is a pure computation, and can be tested by stepping it directly - there’s no need for a LiveView Process - tests run in microseconds.

I think the coroutines allow the back-and-forth logic of the interaction between the LiveView and the state to be expressed very straightforwardly.

Plenty more detail here, including how these Spindles get wired up to a LiveView, how they get bundled into a PageMachine and more: PageMachine — skuld v0.33.1

What do you think ?

Most Liked

krasenyp

krasenyp

I think this is way over engineered. What I do is for every LiveView I define a protocol, basically a view model from the MVVM architecture. This allows me to test both the protocol implementations and the live view with a stubbed view model. That’s it.

Where Next?

Popular in Discussions Top

vans163
So useless benchmarks aside, Its possible to write a webserver that can serve 300k requests per second (perhaps more with optimizations)....
New
mikl
I wanted to capitalize a string, and tried using String.capitalize(). That generally works well, until you try to capitalize a word like...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
laiboonh
Hi all, I am trying to convince my team to use liveview over the current react. What are some of the points where one should consider us...
New
lorenzo
Hey everone! I created a prototype for my app using Nodejs for the api. But the framework I chose wasnt great (in general theresnt any g...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
und0ck3d
Hello everyone! A few days ago I’ve created a topic here about how people were creating CMSs with Elixir and Phoenix. I’ve been studying...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

Other popular topics Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement