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: Headline:
- re-frame subscriptions are now de-duplicated. As a result, some Signal graphs will be much more - re-frame subscriptions are now de-duplicated. As a result, some Signal graphs will be much more
@ -29,12 +29,12 @@ Breaking:
supply alternatives using `re-frame.core/set-loggers!`. supply alternatives using `re-frame.core/set-loggers!`.
With this release, any alternatives you supply will be called with different parameters. 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 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 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. ;; your old log function might have looked like this. Single string parameter.
(defn my-logger [s] (do-something-with s)) (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 ;; your new version will have variadic params, and turn them into a string
(defn my-logger [& args] (do-something-with (apply str args)) (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 Improvements
- XXXX middleware for spec checking of event vectors - XXXX middleware for spec checking of event vectors
- XXXX better subscriptions of subscriptions - XXXX better subscriptions of subscriptions
- XXX spec definitions of what subscriptions deliver ?? - 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 - 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 single line saying so, rather than a "group". Makes it slightly easier to grok
the absence of change. the absence of change.

View File

@ -53,16 +53,22 @@
;; -- Event Procssing Callbacks ;; -- Event Procssing Callbacks
(defn add-post-event-callback (defn add-post-event-callback
"Normal users of re-frame can ignore this part of the API. Useful "Registers a callback function 'f'.
only to libraries providing 'isomorphic javascript' rendering on
Nodejs or Nashorn.
Registers a callback function 'f'.
f will be called after each dispatched event is procecessed f will be called after each dispatched event is procecessed
f will be called with two parameters: f will be called with two parameters:
- the event's vector. That which was dispatched orignally. - the event's vector. That which was dispatched orignally.
- the further event queue - what is still to be processed. A PersistentQueue. - 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] [f]
(router/add-post-event-callback re-frame.router/event-queue 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 (ns re-frame.router
(:require [reagent.core] (:require [reagent.core]
[re-frame.handlers :refer [handle]] [re-frame.handlers :refer [handle]]
[re-frame.utils :refer [error]] [re-frame.utils :refer [warn error]]
[goog.async.nextTick])) [goog.async.nextTick]))
@ -72,6 +72,7 @@
;; -- Public API ;; -- Public API
(enqueue [this event]) (enqueue [this event])
(add-post-event-callback [this f]) (add-post-event-callback [this f])
(remove-post-event-callback [this f])
;; -- Implementation via a Finite State Machine ;; -- Implementation via a Finite State Machine
(-fsm-trigger [this trigger arg]) (-fsm-trigger [this trigger arg])
@ -95,16 +96,21 @@
;; -- API ------------------------------------------------------------------ ;; -- API ------------------------------------------------------------------
(enqueue [this event] (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)) (-fsm-trigger this :add-event event))
(add-post-event-callback [this f] (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 ;; 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))) (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 Implementation ---------------------------------------------------
(-fsm-trigger (-fsm-trigger
[this trigger arg] [this trigger arg]
@ -118,10 +124,10 @@
;; You should read the following "case" as: ;; You should read the following "case" as:
;; [current-FSM-state trigger] -> [new-FSM-state action-fn] ;; [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" ;; if you are in state ":idle" and a trigger ":add-event"
;; happens, then move the FSM to state ":scheduled" and execute ;; 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) [:idle :add-event] [:scheduled #(do (-add-event this arg)
(-run-next-tick this))] (-run-next-tick this))]
@ -137,7 +143,7 @@
[:idle] [:idle]
[:scheduled #(-run-next-tick this)]) [: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 :add-event] [:paused #(-add-event this arg)]
[:paused :resume ] [:running #(-resume this)] [:paused :resume ] [:running #(-resume this)]
@ -156,13 +162,13 @@
(let [event-v (peek queue)] (let [event-v (peek queue)]
(try (try
(handle event-v) (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. ;; Tell all registed callbacks that an event was just processed.
;; Pass in the event just handled and the new state of the queue ;; Pass in the event just handled and the new state of the queue
(doseq [f post-event-callback-fns] (f event-v queue)))) (doseq [f post-event-callback-fns] (f event-v queue))
(catch :default ex
(-fsm-trigger this :exception ex)))))
(-run-next-tick (-run-next-tick
[this] [this]
@ -220,13 +226,13 @@
(defn dispatch-sync (defn dispatch-sync
"Send an event to be processed by the registered handler "Immediately process an event using the registered handler.
immediately. Note: dispatch-sync cannot be called while another
event is being handled. Generally, don't use this. Use \"dispatch\" instead. It
is an error to even try and use it within an event handler.
Usage example: Usage example:
(dispatch-sync [:delete-item 42])" (dispatch-sync [:delete-item 42])"
[event-v] [event-v]
(handle event-v) (handle event-v)
nil) ;; Ensure nil return. See https://github.com/Day8/re-frame/wiki/Beware-Returning-False nil) ;; Ensure nil return. See https://github.com/Day8/re-frame/wiki/Beware-Returning-False