Path-based state management with revision tracking and transactions.
A lightweight wrapper around a plain map that tracks a monotonically increasing revision number on every mutation. Useful for detecting changes and implementing optimistic concurrency.
Transactions
begin_transaction/1 captures a snapshot of the current data and revision.
Subsequent mutations increment the revision as usual. commit_transaction/1
finalises the transaction (bumping the revision once from the pre-transaction
value). rollback_transaction/1 restores the snapshot exactly.
Example
state = Plushie.State.new(%{count: 0})
state = Plushie.State.put(state, [:count], 5)
Plushie.State.get(state, [:count])
#=> 5
Plushie.State.revision(state)
#=> 1
Summary
Functions
Begins a transaction by capturing the current data and revision.
Commits the active transaction, setting the revision to one past the pre-transaction value.
Removes the key at the end of path, incrementing the revision.
Reads the value at path in the state data.
Creates a new state container wrapping data.
Sets the value at path to value, incrementing the revision.
Returns the current revision number.
Rolls back the active transaction, restoring the data and revision to their pre-transaction values.
Applies fun to the value at path, incrementing the revision.
Types
@type t() :: %Plushie.State{ data: map(), revision: non_neg_integer(), transaction: map() | nil }
Functions
Begins a transaction by capturing the current data and revision.
Returns {:error, :transaction_already_active} if a transaction is
already in progress.
Commits the active transaction, setting the revision to one past the pre-transaction value.
Removes the key at the end of path, incrementing the revision.
Uses Kernel.pop_in/2 to remove the key. If the path doesn't exist,
the revision is still incremented for consistency.
Reads the value at path in the state data.
An empty path returns the entire data map. Path elements are keys
passed to Kernel.get_in/2.
Creates a new state container wrapping data.
The initial revision is 0.
Sets the value at path to value, incrementing the revision.
@spec revision(state :: t()) :: non_neg_integer()
Returns the current revision number.
Rolls back the active transaction, restoring the data and revision to their pre-transaction values.
Applies fun to the value at path, incrementing the revision.
fun receives the current value and must return the new value.