Status: Drafting. May be incoherent and/or wrong. Don't read.
This EP proposes changes to the way re-frame handlers are registered, to allow for the capture of richer handler metadata. These changes also lay the groundwork for tooling advances, and EPs to follow.
re-frame's API currently includes 7 functions for registering handlers:
reg-event-db, reg-event-fx and reg-event-ctxreg-sub and reg-sub-rawreg-fxreg-cofxTwo others are on the drawing board:
reg-viewreg-interceptorSo, there are potentially 9 kinds of handlers.
Internally, re-frame manages registered handlers in a registrar, which is a two-level map,
keyed at the first level by the kind of handler and at the second level by the (keyword)
id of the handler. The leaf values are the handler functions themselves.
This EP proposes that:
regregistrar, which are currently the handler functions themselves,
become instead a map of values related to the handler,
including a doc string, the file/line where defined, specs, etc, and, of course,
the handler itself.There's pressure from multiple directions to collect and retain more metadata about handlers:
re-frame-10x to actively help programmers when they are learning a
new code base. That's one of the four stated goals.
Ideally, re-frame would be capable of providing tooling with "a complete
inventory" of an app's handlers, along with useful
metadata on each handles. When an event is processed, the audit trail of
handlers involved should be rich with information.As part of the retained handler metadata, we'd like to automatically capture source code coordinates, like namespace and line number. To make this happen, a macro will need to be introduced for registration, and that's a shift in approach because, until now, macros have been manfully resisted.
Introducing docstrings into registrations also encourages a macro solution because docstrings should be removed from production builds.
A new macro reg will become the method
of registering handlers. The existing 7 registration functions
will ultimately be deprecated.
reg will take one argument, a map, which captures all aspects of
the handler.
Previously, reg-event-db was used like this:
(rf/reg-event-db
:event-id
(fn [db event]
(assoc db :some :thing)))
now, use reg would be used like this:
(rf/reg
{:kind :event-db
:id :event-id
:fn (fn [db event]
(assoc db :some :thing))})
The map argument must contain the keys :kind, :id and :fn,
with other valid keys being dependent on the kind of
handler being registered.
The value :kind can be one these 7 (mapping to 7 existing reg-* functions):
:event-db :event-fx :event-ctx:sub :sub-raw:fx:cofxOptionally, for all kinds of handlers the
the map can also have these additional keys:
:doc a doc string:ns the namespace where the handler was registered:line line number where the handler was registered:file the name file where the handler was registeredIn a dev build, the reg macro will supply the final 3 (source code coordinates),
if not explicitly supplied in the map.
In a production build, the :doc string will be elided, so we do not
appear in the final source code at all.
The key :pkg is reserved for future use, and might eventually indicate the
"package" to which this handler belongs. See EP 002.
Other keys: XXX
:cept for interceptors (when registering events):ins for input signals (when registering subscriptions):ret for return spec (subscriptions and events):spec for event spec (when registering events) ??? Too much ??XXX I'm not entirely happy about using short names like :cept. But, then
again, there's the aesthetics of formatting the code and lining things up.
XXX could have a :cofx key for event handlers to make them more explicit.
The argument to reg can also be a vector of maps to allow
for multiple handlers to be registered at once:
(rf/reg
[{:kind :event-db ...}
{:kind :event-db ...}
{:kind :event-fx ...}
{:kind :sub ...])
XXX maybe not needed. Provide the most minimal API? Then let towers of abstraction be built on top.
Each entry stored in the registrar will become a map instead of just a handler.
Map keys:
:kind - somehow redundant:id:doc:line:ns:doc:fn the handlerXXX look into reg-sub
XXX
:doc for display in HTML? Or just texual.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |