@@ -110,8 +110,8 @@ let user_id_codec = codec.map(codec.int(), UserId, fn(uid) {
110110```
111111
112112Gleam has no derive macros or reflection, so codecs for complex types
113- are manual. The combinators handle the serialization — you just wire
114- the fields together.
113+ are manual. The combinators handle the serialization so you just wire
114+ the fields together!
115115
116116## Modules
117117
@@ -122,11 +122,57 @@ the fields together.
122122| ` distribute/cluster ` | ` net_kernel ` start/connect/ping |
123123| ` distribute/codec ` | Binary codecs for primitives + ` subject() ` |
124124| ` distribute/codec/composite ` | Option, Result, Tuple codecs |
125+ | ` distribute/codec/variant ` | Build codecs for Custom Types (ADTs) |
125126| ` distribute/codec/tagged ` | Tagged messages with version field |
126127| ` distribute/global ` | ` GlobalSubject(msg) ` , ` call ` , ` reply ` |
128+ | ` distribute/cluster/monitor ` | ` NodeUp ` , ` NodeDown ` typed events |
127129| ` distribute/registry ` | ` TypedName(msg) ` , ` :global ` registration |
128130| ` distribute/receiver ` | Typed receive, OTP actor wrappers |
129131
132+ ### Custom Type Codecs
133+
134+ Seamlessly encode and decode your Algebraic Data Types (enums) with a fluent builder.
135+
136+ ``` gleam
137+ pub type MyMessage {
138+ Text(String)
139+ Ping
140+ }
141+
142+ import distribute/codec
143+ import distribute/codec/variant
144+
145+ let my_codec =
146+ variant.new()
147+ |> variant.add(0, "Text", codec.string(), Text, fn(m) {
148+ case m { Text(s) -> Ok(s); _ -> Error(Nil) }
149+ })
150+ |> variant.unit(1, "Ping", Ping, fn(m) { m == Ping })
151+ |> variant.build()
152+ ```
153+
154+ ### Cluster Monitoring
155+
156+ Subscribe to cluster events (` NodeUp ` , ` NodeDown ` ) to react to node topology changes.
157+
158+ ``` gleam
159+ import distribute
160+ import distribute/cluster/monitor
161+
162+ let subj = process.new_subject()
163+ let assert Ok(m) = distribute.subscribe(subj)
164+
165+ // In your actor/process
166+ case process.receive(subj, 5000) {
167+ Ok(monitor.NodeUp(node)) -> io.println("Node joined: " <> node)
168+ Ok(monitor.NodeDown(node)) -> io.println("Node left: " <> node)
169+ _ -> Nil
170+ }
171+
172+ // Later
173+ distribute.unsubscribe(m)
174+ ```
175+
130176## Caveats
131177
132178** What the types catch** — within one codebase, ` TypedName ` and
0 commit comments