Introduce new API - `remove-post-event-callback`

This commit is contained in:
Mike Thompson 2016-06-03 12:49:49 +10:00
parent a9dcdd695e
commit 5684543b1a
3 changed files with 42 additions and 28 deletions

View File

@ -1,4 +1,4 @@
## 0.8.0 (XXX)
## 0.8.0 (2016.06.XXXX)
Headline:
- re-frame subscriptions are now de-duplicated. As a result, some Signal graphs will be much more
@ -20,7 +20,7 @@ Headline:
So, these two subscriptions are *not* "the same": `[:some-event 42]` `[:some-event "blah"]`. Even
though they involve the same event id, `:some-event`, the query vectors do not test `=`.
Breaking:
- requires Reagent >= 0.6.0 or later. It won't work with <= Reagent 0.5.2.
@ -29,12 +29,12 @@ Breaking:
supply alternatives using `re-frame.core/set-loggers!`.
With this release, any alternatives you supply will be called with different parameters.
Previously loggers were given a single `str` parameter but now they are expected to act
Previously loggers were called with a single `str` parameter but now they are expected to act
like `console.log` itself and take variadic, non string params. Sorry to break things, but
we are trying to maximise use of cljs-devtools and information is lost when strings are
output, instead of real data.
output, instead of actual data.
To transition, here's the tweak you can make:
To transition, you'll need to tweak like this:
```
;; your old log function might have looked like this. Single string parameter.
(defn my-logger [s] (do-something-with s))
@ -42,13 +42,15 @@ Breaking:
;; your new version will have variadic params, and turn them into a string
(defn my-logger [& args] (do-something-with (apply str args))
```
Of course, you only have to worry about this if you are using `re-frame.core/set-loggers!` to
hook in your own loggers. Otherwise, you have nothing to do.
Improvements
- XXXX middleware for spec checking of event vectors
- XXXX better subscriptions of subscriptions
- XXX spec definitions of what subscriptions deliver ??
- added new API `re-frame.core/remove-post-event-callback`. See doc string.
- when an event-handler makes no change to `app-db`, the `debug` middleware now logs a
single line saying so, rather than a "group". Makes it slightly easier to grok
the absence of change.

View File

@ -53,16 +53,22 @@
;; -- Event Procssing Callbacks
(defn add-post-event-callback
"Normal users of re-frame can ignore this part of the API. Useful
only to libraries providing 'isomorphic javascript' rendering on
Nodejs or Nashorn.
Registers a callback function 'f'.
"Registers a callback function 'f'.
f will be called after each dispatched event is procecessed
f will be called with two parameters:
- the event's vector. That which was dispatched orignally.
- the further event queue - what is still to be processed. A PersistentQueue.
This is useful in advanced cases like:
- you are implementing a complex bootstrap pipeline
- you want to create your own handling infrastructure, with perhaps multiple
handlers for the one event, etc. Hook in here.
- a libraries providing 'isomorphic javascript' rendering on Nodejs or Nashorn.
"
[f]
(router/add-post-event-callback re-frame.router/event-queue f))
(defn remove-post-event-callback
[f]
(router/remove-post-event-callback re-frame.router/event-queue f))

View File

@ -1,7 +1,7 @@
(ns re-frame.router
(:require [reagent.core]
[re-frame.handlers :refer [handle]]
[re-frame.utils :refer [error]]
[re-frame.utils :refer [warn error]]
[goog.async.nextTick]))
@ -72,6 +72,7 @@
;; -- Public API
(enqueue [this event])
(add-post-event-callback [this f])
(remove-post-event-callback [this f])
;; -- Implementation via a Finite State Machine
(-fsm-trigger [this trigger arg])
@ -95,16 +96,21 @@
;; -- API ------------------------------------------------------------------
(enqueue [this event]
;; put an event into the queue (assumidly because of a dispatch)
;; put an event into the queue (presumably because of a dispatch)
(-fsm-trigger this :add-event event))
(add-post-event-callback [this f]
;; register a callback to be invoked when events are processed
;; register a callback to be invoked after events are processed
;; Useful to so-called isomorphic, server-side rendering frameworks
;; or when you want to do specialised event processing.
(set! post-event-callback-fns (conj post-event-callback-fns f)))
(remove-post-event-callback [this f]
(set! post-event-callback-fns (remove #(= % f) post-event-callback-fns)))
;; -- FSM Implementation ---------------------------------------------------
(-fsm-trigger
[this trigger arg]
@ -118,10 +124,10 @@
;; You should read the following "case" as:
;; [current-FSM-state trigger] -> [new-FSM-state action-fn]
;;
;; So, the next line should be interpreted as:
;; So, for example, the next line should be interpreted as:
;; if you are in state ":idle" and a trigger ":add-event"
;; happens, then move the FSM to state ":scheduled" and execute
;; that "do" fucntion.
;; that two-part "do" fucntion.
[:idle :add-event] [:scheduled #(do (-add-event this arg)
(-run-next-tick this))]
@ -137,7 +143,7 @@
[:idle]
[:scheduled #(-run-next-tick this)])
;; State: :paused (the event metadata :flush-dom has caused a temporary pause in processing)
;; State: :paused (:flush-dom metadata on an event has caused a temporary pause in processing)
[:paused :add-event] [:paused #(-add-event this arg)]
[:paused :resume ] [:running #(-resume this)]
@ -156,13 +162,13 @@
(let [event-v (peek queue)]
(try
(handle event-v)
(catch :default ex
(-fsm-trigger this :exception ex)))
(set! queue (pop queue))
(set! queue (pop queue))
;; Tell all registed callbacks that an event was just processed.
;; Pass in the event just handled and the new state of the queue
(doseq [f post-event-callback-fns] (f event-v queue))))
;; Tell all registed callbacks that an event was just processed.
;; Pass in the event just handled and the new state of the queue
(doseq [f post-event-callback-fns] (f event-v queue))
(catch :default ex
(-fsm-trigger this :exception ex)))))
(-run-next-tick
[this]
@ -220,13 +226,13 @@
(defn dispatch-sync
"Send an event to be processed by the registered handler
immediately. Note: dispatch-sync cannot be called while another
event is being handled.
"Immediately process an event using the registered handler.
Generally, don't use this. Use \"dispatch\" instead. It
is an error to even try and use it within an event handler.
Usage example:
(dispatch-sync [:delete-item 42])"
[event-v]
(handle event-v)
nil) ;; Ensure nil return. See https://github.com/Day8/re-frame/wiki/Beware-Returning-False