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-ctx
reg-sub
and reg-sub-raw
reg-fx
reg-cofx
Two others are on the drawing board:
reg-view
reg-interceptor
So, 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:
reg
registrar
, 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
:cofx
Optionally, 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 is a website building & hosting documentation for Clojure/Script libraries
× close