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 ?