tuck.core

*allow-actions*

dynamic

Bound to false when replaying events to disable side-effects.

action!

(action! action-fn & args)
Run an action function that may side-effect and schedule asynchronous actions.
The first parameter of the action is the current send function. Actions only run
when *allow-actions* is true.

current-send-function

(current-send-function)
Get the current send function. Must be called from within process-event.

define-assoc-events

macro

(define-assoc-events & events-and-paths)

Define events that simply take their parameter and assoc it to the given path in the app state. Takes pairs of event name and path-vector. For example:

(define-assoc-events UpdateUserName [:user :name])

Will define an event record type called UpdateUserName which has one field and whose process-event will update the value of the field to the app state path [:user :name]. The new value will overwrite the value (if any) in the app state.

define-event

macro

(define-event event-record-name event-params options & body)

Define a new event record type and its process-event implementation.

  • event-record-name must be a symbol defining the event name.
  • event-params is a vector containing the names of the record’s fields.
  • options a map of parameters.
  • body code to apply the event to current app state.

Supported options:

  • :path a vector containing a path to the app state where the update should take place
  • :app a name to bind the current app state to (defaults to app)

The code in body can refer to the event params and the app state by their name. The app state is the value under :path and the returned value will replace it.

Example:

(define-event UpdateCustomerForm [form-data]
  {:path [:customer :editing]
   :app customer}
  (merge customer form-data))

Event

protocol

members

process-event

(process-event this app-state)
Process this event for the current app state. Must return new state.

send-async!

(send-async! constructor & args)

Returns a callback function which will create and apply a new event. THe constructor must be a function that returns an event. The constructor is called with the callback parameters and the (optional) arguments.

Must be called from within process-event.

Example:

;; inside some event's processing code
(GET! "/fetch-things" {:on-success (t/send-async! ->FetchThingsResponse)
                       :on-failure (t/send-async! ->ServerError)})

send-value!

(send-value! e! constructor & args)

Returns a UI event handler that sends the event’s value to the UI message processing after calling constructor with it. Useful for DOM change effects.

Example:

[:input {:type "text"
         :value name
         :on-change (t/send-value! e! ->UpdateName)}]

tuck

(tuck app root-component)(tuck app root-component options)
Entrypoint for tuck. Takes in a reagent atom and a root component.
The root component will be rendered with two parameters: a ui control
function (for sending events to) and the current state of the app atom.

The optional options map can have the following keys:
:path-fn   If path-fn is provided, it is called to return a path (for update-in)
           for the event. If the path-fn returns nil for the event, the event is
           applied to the app root. Path-fn is an alternative to wrapping send
           functions for routing events to different parts of the state atom.
:spec      If specified, the app state is validate against the spec after each
           event. If the new state is invalid the on-invalid-state handler is
           called to fix it.

:on-invalid-state
           Handler to call when the app state after an event fails spec validation.
           Must return new (fixed) app state. Takes 4 arguments: the previous state,
           the event that caused the invalid state, the new invalid state and the
           spec it was validated against.
           Default implementation logs the event and clojure.spec explain output
           and returns the previous valid state.

For backwards compatibility, if options is a function, it is interpreted to mean
the path-fn.

The options are evaluated once, when the component is created and changes to
options don't take effect during the component's lifetime.

UpdateAt

wrap

(wrap e! wrap-constructor & args)
Wrap the given UI send function with the given constructor
and optional arguments. Returns a new UI send function where
each event is mapped with the constructor before being sent.

wrap-path

(wrap-path e! & key-path)
Wrap the given UI send function with an UpdateAt event for
the given key-path.