Skip to content

Commit

Permalink
Some more API revisions and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ingesolvoll committed Oct 17, 2021
1 parent a3330c1 commit 9983520
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Request FSM is started with either an event, like this:
`(rf/dispatch [::http/start fsm-configuration])`

Or by returning an effect from an event handler, like this:
```
```clojure
{:db (assoc db :some :prop)
:dispatch [::some-dispatch]
::http/start fsm-configuration}
Expand All @@ -96,12 +96,43 @@ FSM state is exposed through re-frame subscriptions:
=> [::http/loading]
```

```
```clojure
(rf/subscribe [::http/state-full fsm-id])
=> {:_state [::http/error ::http/retrying ::http/waiting]
:retries 1}
```

You can also embed an HTTP FSM inside another FSM. Like this:

```clojure
{:id :polling-fsm
:transition-event :transition-my-fsm
:initial ::running
:states {::running {:initial ::loading
:states {::waiting {:after [{:delay 10000
:target ::loading}]}
::loading (http/embedded-fsm
{:transition-event :transition-my-fsm
:http-xhrio "url"
:path [:store :data :here]
:state-path [:> ::running ::loading]
:success-state [:> ::running ::waiting]})}}}}
```

In this context, we get a few more settings that need to be considered.

`:transition-event`: **Required** The embedded machine needs access to the transition event of the container.

`:state-path`: **Required** The path within the containing FSM where this embedded one resides. Needed for computing
state transitions relative to the embedded machine.

Also, we may want to transition to some arbitrary state when the HTTP FSM fails or succeeds:

`:success-state`: Transition to this state when request succeeds

`:failure-state`: Transition to this state when request fails.


# Events for entering states
`:on-loading`, `:on-error` and `:on-failure` are optional events that are called when entering the corresponding
states. Used for cases where you need to trigger additional side effects or store some state.
Expand Down
8 changes: 4 additions & 4 deletions src/glimt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[:state-path {:optional true
:default [:>]}
[:vector :keyword]]
[:error-state {:optional true} [:vector :keyword]]
[:failure-state {:optional true} [:vector :keyword]]
[:success-state {:optional true} [:vector :keyword]]
[:id simple-keyword?]
[:max-retries {:optional true
Expand Down Expand Up @@ -65,7 +65,7 @@
(defn store-error [state event]
(assoc state :error (:data event)))

(defn embedded-fsm [{:keys [transition-event state-path max-retries retry-delay on-loading on-error on-failure error-state success-state] :as config}]
(defn embedded-fsm [{:keys [transition-event state-path max-retries retry-delay on-loading on-error on-failure failure-state success-state] :as config}]
(when-let [errors (m/explain embedded-config-schema config)]
(throw (ex-info "Invalid embedded HTTP FSM"
{:humanized (me/humanize errors)
Expand All @@ -87,14 +87,14 @@
(f/dispatch (vec (concat on-error [state event transition-event]))))
(assign state event)))
:states {::retrying {:always [{:guard (fn [] (< max-retries 1))
:target (or error-state ::halted)}]
:target (or failure-state ::halted)}]
:initial ::waiting
:entry (sc/assign reset-retries)
:states {::loading {:entry [(sc/assign update-retries)
#(f/dispatch [::load config])]
:on {::error [{:guard (partial more-retries? max-retries)
:target ::waiting}
(or error-state (vec (concat state-path [::error ::halted])))]
(or failure-state (vec (concat state-path [::error ::halted])))]
::success (or success-state (vec (concat state-path [::loaded])))}}
::waiting {:after [{:delay retry-delay
:target ::loading}]}}}
Expand Down

0 comments on commit 9983520

Please sign in to comment.