You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- ✅ **Automatic Hook Registration**: Broadcast hook registered automatically on first call
24
+
- ✅ **v1 Compatible**: Sends initial state immediately (just like v1)
25
+
- ✅ **You Control the Channel**: Create buffered or unbuffered channels as needed
26
+
- ✅ **Clean Error Handling**: Returns errors instead of panicking
27
+
28
+
**Migration Impact**: Most codebases can use the built-in method instead of manually wiring up `broadcast.Manager` + `hooks.Registry`. This simplifies migration significantly.
29
+
30
+
**When You Need Advanced Control**: You can use `broadcast.Manager` directly for custom broadcast logic, multiple managers, or fine-grained control over hook execution order.
16
31
17
32
## Migration Instructions for LLMs
18
33
@@ -152,7 +167,31 @@ machine, err := fsm.New(
152
167
153
168
### Step 7: Migrate GetStateChan Usage (Critical)
154
169
155
-
This is the most complex change. v2 moves state broadcasting to a separate system.
170
+
This changed significantly in v2. The v2 API provides a built-in helper method on the FSM.
171
+
172
+
#### Decision Guide: Which Broadcasting Pattern Should You Use?
173
+
174
+
```
175
+
Do you need state change notifications?
176
+
│
177
+
├─ NO → Skip this step, use fsm.New() without hooks.Registry
178
+
│
179
+
└─ YES → Choose your approach:
180
+
│
181
+
├─ SIMPLE (Recommended for 90% of use cases)
182
+
│ ✅ Use: machine.GetStateChan(ctx, chan)
183
+
│ ✅ When: Standard broadcasting, single FSM, v1 compatibility
184
+
│ ✅ Benefits: Automatic setup, simpler code, less boilerplate
### Error: "cannot use map[string][]string as type transitionDB"
477
546
**Solution:** Wrap map with `transitions.MustNew(yourMap)` or use `transitions.New(yourMap)`
478
547
479
-
### Error: "GetStateChan undefined"
480
-
**Solution:**Set up `broadcast.Manager` (see Step 7)
548
+
### Error: "GetStateChan requires a callback registry"
549
+
**Solution:**Use `fsm.WithCallbackRegistry(registry)` when creating the FSM. The registry must be created with `hooks.WithTransitions()` for wildcard support.
481
550
482
-
### Tests fail: "expected state X, got state Y"
483
-
**Solution:**Check if test expected immediate state broadcast from `GetStateChan`. In v2, manually broadcast initial state or use wrapper.
551
+
### Error: "requires a callback registry that supports dynamic hook registration"
552
+
**Solution:**Use `hooks.Registry` instead of a custom CallbackExecutor. The FSM's built-in `GetStateChan` requires the registry to support dynamic hook registration.
484
553
485
554
### Error: "wildcard '*' cannot be used without state table"
486
555
**Solution:** When using wildcard hooks (`"*"`), you must pass `hooks.WithTransitions()` to the registry.
@@ -500,8 +569,8 @@ Use this checklist to verify your migration:
500
569
-[ ] Replaced `fsm.StatusX` with `transitions.StatusX`
501
570
-[ ] Replaced `fsm.TypicalTransitions` with `transitions.Typical`
502
571
-[ ] Updated `fsm.New()` constructor calls (moved handler to options)
503
-
-[ ] Migrated `GetStateChan()` to use `broadcast.Manager`
504
-
-[ ]Handled initial state broadcast behavior difference
572
+
-[ ] Migrated `GetStateChan()` to use `machine.GetStateChan(ctx, chan)` with hooks.Registry
573
+
-[ ]Added `WithBroadcastTimeout()` option if custom timeout needed (replaces `WithSyncTimeout`)
505
574
-[ ]**Created single abstraction constructor (if architecture supports it)**
0 commit comments