Skip to content

Commit dac79b5

Browse files
docs: update examples and changelog for struct state
- Add changelog entry under [Unreleased] documenting the breaking change - Update README handler examples to use dot access instead of Map.get - Add note to DurableObject moduledoc about the generated State struct
1 parent 4623e2e commit dac79b5

3 files changed

Lines changed: 17 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- State is now returned as a struct (`%MyApp.Counter.State{count: 0}`) instead of a plain atom-keyed map (`%{count: 0}`)
13+
- The DSL automatically generates a nested `State` struct module from the declared fields and defaults
14+
- `%{state | field: value}` update syntax continues to work unchanged
15+
- State is persisted to the database as a plain JSON map (no `__struct__` key)
16+
- Unknown keys in persisted state are silently dropped on load (forward-compatible with field removal)
17+
- `get_persisted_state/3` in `DurableObject.Testing` now returns the module's `State` struct
18+
- **Breaking:** `state[:field]` bracket access no longer works — use `state.field` dot access instead
19+
1020
## [0.2.1] - 2026-02-03
1121

1222
### Added

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,12 @@ defmodule MyApp.Counter do
8484
end
8585

8686
def handle_increment(amount \\ 1, state) do
87-
new_count = Map.get(state, :count, 0) + amount
88-
new_state = %{state | count: new_count, last_incremented_at: DateTime.utc_now()}
89-
{:reply, new_count, new_state}
87+
new_count = state.count + amount
88+
{:reply, new_count, %{state | count: new_count, last_incremented_at: DateTime.utc_now()}}
9089
end
9190

9291
def handle_get(state) do
93-
{:reply, Map.get(state, :count, 0), state}
92+
{:reply, state.count, state}
9493
end
9594

9695
def handle_reset(state) do

lib/durable_object.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ defmodule DurableObject do
4545
{:ok, count} = MyApp.Counter.increment("user-123", 5)
4646
{:ok, count} = MyApp.Counter.get("user-123")
4747
48+
The DSL generates a `MyApp.Counter.State` struct with the declared fields
49+
and defaults. State is passed to handlers as a struct, so `state.count`
50+
and `%{state | count: new_count}` work as expected.
51+
4852
## Manual Usage (without DSL)
4953
5054
You can also call Durable Objects directly without the DSL:

0 commit comments

Comments
 (0)