machina 7.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +33 -11
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -60,17 +60,17 @@ light.dispose(); // tears down; all subsequent calls are silent no-ops
60
60
 
61
61
  ### Public API — `Fsm`
62
62
 
63
- | Method | Description |
64
- | ---------------------------- | ------------------------------------------------------------------ |
65
- | `handle(inputName, ...args)` | Dispatch an input to the current state's handler |
66
- | `canHandle(inputName)` | True if the current state has a handler (or `"*"`) for this input |
67
- | `transition(toState)` | Directly transition; fires `_onExit`, `_onEnter`, lifecycle events |
68
- | `reset()` | Transition back to `initialState` |
69
- | `currentState()` | Returns the current state name |
70
- | `compositeState()` | Dot-delimited path including active child FSM states |
71
- | `on(eventName, callback)` | Subscribe to a lifecycle event (returns `{ off() }`) |
72
- | `emit(eventName, data?)` | Emit a custom event |
73
- | `dispose(options?)` | Permanently shut down; cascades to child FSMs by default |
63
+ | Method | Description |
64
+ | ---------------------------- | ------------------------------------------------------------------------- |
65
+ | `handle(inputName, ...args)` | Dispatch an input to the current state's handler |
66
+ | `canHandle(inputName)` | True if the current state — or its `_child` chain — can handle this input |
67
+ | `transition(toState)` | Directly transition; fires `_onExit`, `_onEnter`, lifecycle events |
68
+ | `reset()` | Transition back to `initialState` |
69
+ | `currentState()` | Returns the current state name |
70
+ | `compositeState()` | Dot-delimited path including active child FSM states |
71
+ | `on(eventName, callback)` | Subscribe to a lifecycle event (returns `{ off() }`) |
72
+ | `emit(eventName, data?)` | Emit a custom event |
73
+ | `dispose(options?)` | Permanently shut down; cascades to child FSMs by default |
74
74
 
75
75
  ## `createBehavioralFsm`
76
76
 
@@ -188,6 +188,28 @@ uploader.compositeState(); // "idle"
188
188
 
189
189
  The parent re-enters `initialState` of the child FSM whenever the parent transitions into the state that owns `_child`.
190
190
 
191
+ Delegation reaches any depth: `canHandle()` answers for the whole `_child` chain, so an input handled three levels down can be dispatched from the root. When both a descendant and an ancestor could handle an input, the descendant wins.
192
+
193
+ An FSM can also declare inputs it fires at itself but never handles — expecting whatever mounts it to catch them via bubbling:
194
+
195
+ ```ts
196
+ const phase = createFsm({
197
+ id: "phase",
198
+ initialState: "running",
199
+ context: {},
200
+ bubbles: ["phaseComplete"], // "I fire this; whoever mounts me must deal with it"
201
+ states: {
202
+ running: {
203
+ _onEnter() {
204
+ // ...later: phase.handle("phaseComplete") — typed, no handler here
205
+ },
206
+ },
207
+ },
208
+ });
209
+ ```
210
+
211
+ Declared bubbles join the FSM's typed input union, and they form a compile-time contract: a config that mounts `phase` via `_child` must handle `phaseComplete`, re-declare it in its own `bubbles`, or carry a `"*"` catch-all — otherwise it fails to compile, with the error naming what's missing. Standalone FSMs owe nothing; the contract only exists where FSMs get wired together. The engine never reads `bubbles` — it's purely type-level.
212
+
191
213
  ## Deferred input
192
214
 
193
215
  Call `defer()` inside a handler to queue the current input for replay after the next transition. Pass `{ until: "stateName" }` to replay only on entry to a specific state.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "machina",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Focused finite state machines for JavaScript and TypeScript. States in, states out.",
5
5
  "author": "Jim Cowart (http://ifandelse.com)",
6
6
  "license": "MIT",