The durable process behind one browser session.
One DurableStash.Session exists per browser session; every LiveView of
that session reads and writes through it. State is partitioned per view
module, and the single-process actor model gives a total order over writes
— per-key last-write-wins with no timestamps needed.
State shape (string keys — it round-trips through JSON object storage):
%{
"views" => %{
"Elixir.My.View" => %{"vsn" => 1, "data" => %{"key" => value}}
},
"last_seen_at" => unix_millis | nil
}Each view slice carries the vsn its writer declared. A write with a different vsn replaces the slice wholesale instead of merging — the adapter only does that with a full, migrated key set, so a version bump can never mix old- and new-shape keys.
Writes merge in memory and reply immediately; the object-store PUT then runs
in a handle_continue/2 on this same process, after the reply is sent — so
a write never blocks the calling LiveView on the network round-trip.
Durability lands a continue later, and DurableServer also flushes on its
periodic interval and on graceful shutdown. A synchronous PUT inside every
write — the previous behaviour — is what made auto_stash form views feel
sluggish under per-keystroke validation.
Summary
Functions
Callback implementation for DurableServer.after_terminate/2.
Callback implementation for DurableServer.code_change/3.
Removes keys from the view's data map. Unknown keys are ignored.
Returns {:ok, %{"vsn" => vsn, "data" => data}} or :not_found when the
view has never stashed.
Returns the view's data map, %{} when the view has never stashed.
Callback implementation for DurableServer.handle_cast/2.
Callback implementation for DurableServer.handle_info/2.
Callback implementation for DurableServer.init/1.
Merges changes (string-keyed map) into the view's slice. Per-key LWW.
Drops the view's slice.
Callback implementation for DurableServer.terminate/2.
Functions
Callback implementation for DurableServer.after_terminate/2.
Callback implementation for DurableServer.code_change/3.
Removes keys from the view's data map. Unknown keys are ignored.
Returns {:ok, %{"vsn" => vsn, "data" => data}} or :not_found when the
view has never stashed.
Returns the view's data map, %{} when the view has never stashed.
Callback implementation for DurableServer.handle_cast/2.
Callback implementation for DurableServer.handle_info/2.
Callback implementation for DurableServer.init/1.
Merges changes (string-keyed map) into the view's slice. Per-key LWW.
When the stored slice carries a different vsn, the slice is replaced with
changes wholesale (see the moduledoc).
Drops the view's slice.
Callback implementation for DurableServer.terminate/2.