tuck.core
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 toapp
)
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.
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.