adding doc comments and changing some internal use functions to private
This commit is contained in:
parent
1eda612d0c
commit
333e4873d5
|
@ -4,21 +4,17 @@
|
||||||
[dommy.core :refer-macros [sel1]]
|
[dommy.core :refer-macros [sel1]]
|
||||||
goog.net.BrowserChannel
|
goog.net.BrowserChannel
|
||||||
goog.net.BrowserChannel.Handler
|
goog.net.BrowserChannel.Handler
|
||||||
[goog.net.BrowserChannel.State :as bc-state]
|
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
[goog.debug.Logger.Level :as log-level]))
|
[goog.debug.Logger.Level :as log-level]))
|
||||||
|
|
||||||
(defonce channel (goog.net.BrowserChannel.))
|
(defonce channel (goog.net.BrowserChannel.))
|
||||||
|
|
||||||
(def default-options
|
; see: https://google.github.io/closure-library/api/source/closure/goog/net/browserchannel.js.src.html#l470
|
||||||
{:base "/channel"
|
(def ^:private bch-state-enum-to-keyword
|
||||||
:allow-chunked-mode? true
|
{0 :closed
|
||||||
:allow-host-prefix? true
|
1 :init
|
||||||
:fail-fast? false
|
2 :opening
|
||||||
:max-back-channel-retries 3
|
3 :opened})
|
||||||
:max-forward-channel-retries 2
|
|
||||||
:forward-channel-request-timeout (* 20 1000)
|
|
||||||
:verbose-logging? false})
|
|
||||||
|
|
||||||
; see: https://google.github.io/closure-library/api/source/closure/goog/net/browserchannel.js.src.html#l521
|
; see: https://google.github.io/closure-library/api/source/closure/goog/net/browserchannel.js.src.html#l521
|
||||||
(def ^:private bch-error-enum-to-keyword
|
(def ^:private bch-error-enum-to-keyword
|
||||||
|
@ -34,19 +30,19 @@
|
||||||
11 :bad-response
|
11 :bad-response
|
||||||
12 :active-x-blocked})
|
12 :active-x-blocked})
|
||||||
|
|
||||||
(defn encode-map
|
(defn- encode-map
|
||||||
[data]
|
[data]
|
||||||
(doto (js-obj)
|
(doto (js-obj)
|
||||||
(aset "__edn" (pr-str data))))
|
(aset "__edn" (pr-str data))))
|
||||||
|
|
||||||
(defn decode-map
|
(defn- decode-map
|
||||||
[m]
|
[m]
|
||||||
(let [m (js->clj m)]
|
(let [m (js->clj m)]
|
||||||
(if (contains? m "__edn")
|
(if (contains? m "__edn")
|
||||||
(reader/read-string (str (get m "__edn")))
|
(reader/read-string (str (get m "__edn")))
|
||||||
m)))
|
m)))
|
||||||
|
|
||||||
(defn decode-queued-map
|
(defn- decode-queued-map
|
||||||
[queued-map]
|
[queued-map]
|
||||||
(merge
|
(merge
|
||||||
{:context (aget queued-map "context")
|
{:context (aget queued-map "context")
|
||||||
|
@ -56,40 +52,52 @@
|
||||||
{:data (reader/read-string (str (get data "__edn")))}
|
{:data (reader/read-string (str (get data "__edn")))}
|
||||||
{:map data}))))
|
{:map data}))))
|
||||||
|
|
||||||
(defn decode-queued-map-array
|
(defn- decode-queued-map-array
|
||||||
[queued-map-array]
|
[queued-map-array]
|
||||||
(mapv decode-queued-map queued-map-array))
|
(mapv decode-queued-map queued-map-array))
|
||||||
|
|
||||||
(defn channel-state []
|
(defn channel-state
|
||||||
(.getState channel))
|
"returns the current state of the browserchannel connection."
|
||||||
|
[]
|
||||||
|
(get bch-state-enum-to-keyword (.getState channel) :unknown))
|
||||||
|
|
||||||
(defn connected?
|
(defn connected?
|
||||||
|
"returns true if the browserchannel connection is currently connected."
|
||||||
[]
|
[]
|
||||||
(= (channel-state) bc-state/OPENED))
|
(= (channel-state) :opened))
|
||||||
|
|
||||||
(defn set-debug-log!
|
(defn set-debug-log!
|
||||||
|
"sets the debug log level, and optionally a log output handler function
|
||||||
|
which defaults to js/console.log"
|
||||||
[level & [f]]
|
[level & [f]]
|
||||||
(doto (.. channel getChannelDebug getLogger)
|
(doto (.. channel getChannelDebug getLogger)
|
||||||
(.setLevel level)
|
(.setLevel level)
|
||||||
(.addHandler (or f #(js/console.log %)))))
|
(.addHandler (or f #(js/console.log %)))))
|
||||||
|
|
||||||
(defn send-data
|
(defn send-data
|
||||||
|
"sends data to the server over the forward channel. when the data has
|
||||||
|
been sent and the server sends an acknowledgement, the optional
|
||||||
|
on-success callback is invoked."
|
||||||
[data & [{:keys [on-success]}]]
|
[data & [{:keys [on-success]}]]
|
||||||
(if data
|
(if data
|
||||||
(.sendMap channel (encode-map data) {:on-success on-success})))
|
(.sendMap channel (encode-map data) {:on-success on-success})))
|
||||||
|
|
||||||
(defn connect!
|
(defn connect!
|
||||||
|
"starts the browserchannel connection (initiates a connection to the server).
|
||||||
|
under normal circumstances, your application should not call this directly.
|
||||||
|
instead your application code should call init!"
|
||||||
[& [{:keys [base] :as options}]]
|
[& [{:keys [base] :as options}]]
|
||||||
(let [state (channel-state)]
|
(let [state (channel-state)]
|
||||||
(if (or (= state bc-state/CLOSED)
|
(if (or (= state :closed)
|
||||||
(= state bc-state/INIT))
|
(= state :init))
|
||||||
(.connect channel
|
(.connect channel
|
||||||
(str base "/test")
|
(str base "/test")
|
||||||
(str base "/bind")))))
|
(str base "/bind")))))
|
||||||
|
|
||||||
(defn disconnect!
|
(defn disconnect!
|
||||||
|
"disconnects and closes the browserchannel connection."
|
||||||
[]
|
[]
|
||||||
(if-not (= (channel-state) bc-state/CLOSED)
|
(if-not (= (channel-state) :closed)
|
||||||
(.disconnect channel)))
|
(.disconnect channel)))
|
||||||
|
|
||||||
(defn- get-anti-forgery-token
|
(defn- get-anti-forgery-token
|
||||||
|
@ -97,7 +105,7 @@
|
||||||
(if-let [tag (sel1 "meta[name='anti-forgery-token']")]
|
(if-let [tag (sel1 "meta[name='anti-forgery-token']")]
|
||||||
(.-content tag)))
|
(.-content tag)))
|
||||||
|
|
||||||
(defn ->handler
|
(defn- ->handler
|
||||||
[{:keys [on-open on-close on-receive on-sent on-error]}]
|
[{:keys [on-open on-close on-receive on-sent on-error]}]
|
||||||
(let [handler (goog.net.BrowserChannel.Handler.)]
|
(let [handler (goog.net.BrowserChannel.Handler.)]
|
||||||
(set! (.-channelOpened handler)
|
(set! (.-channelOpened handler)
|
||||||
|
@ -142,14 +150,62 @@
|
||||||
;; setting to be able to change, so i think it's worth the risk...
|
;; setting to be able to change, so i think it's worth the risk...
|
||||||
(set! goog.net.BrowserChannel/BACK_CHANNEL_MAX_RETRIES (:max-back-channel-retries options)))
|
(set! goog.net.BrowserChannel/BACK_CHANNEL_MAX_RETRIES (:max-back-channel-retries options)))
|
||||||
|
|
||||||
|
(def default-options
|
||||||
|
"default options that will be applied by init! unless
|
||||||
|
overridden."
|
||||||
|
{
|
||||||
|
;; base/root url on which to send browserchannel requests to
|
||||||
|
:base "/channel"
|
||||||
|
|
||||||
|
;; sets whether chunked mode is allowed. sometimes a useful
|
||||||
|
;; debugging tool
|
||||||
|
:allow-chunked-mode? true
|
||||||
|
|
||||||
|
;; sets whether the channel allows the user of a subdomain
|
||||||
|
:allow-host-prefix? true
|
||||||
|
|
||||||
|
;; when true, this changes the behaviour of the forward channel
|
||||||
|
;; (client->server) such that it will not retry failed requests
|
||||||
|
;; even once.
|
||||||
|
:fail-fast? false
|
||||||
|
|
||||||
|
;; sets the max number of attempts to connect to the server for
|
||||||
|
;; back channel (server->client) requests
|
||||||
|
:max-back-channel-retries 3
|
||||||
|
|
||||||
|
;; sets the max number of attempts to connect to the server for
|
||||||
|
;; forward channel (client->server) requests
|
||||||
|
:max-forward-channel-retries 2
|
||||||
|
|
||||||
|
;; sets the timeout (in milliseconds) for a forward channel request
|
||||||
|
:forward-channel-request-timeout (* 20 1000)
|
||||||
|
|
||||||
|
;; whether to enable somewhat verbose debug logging
|
||||||
|
:verbose-logging? false
|
||||||
|
})
|
||||||
|
|
||||||
(defn init!
|
(defn init!
|
||||||
|
"initializes a browserchannel connection for use, registers your
|
||||||
|
application event handlers and setting any specified options.
|
||||||
|
|
||||||
|
handler should be a map of event handler functions:
|
||||||
|
|
||||||
|
{:on-open (fn [] ...)
|
||||||
|
:on-close (fn [pending undelivered] ...)
|
||||||
|
:on-receive (fn [data] ...)
|
||||||
|
:on-sent (fn [delivered] ...)
|
||||||
|
:on-error (fn [error-code] ...)
|
||||||
|
|
||||||
|
:on-open is called when a connection is (re-)established.
|
||||||
|
:on-close is called when a connection is closed.
|
||||||
|
:on-receive is called when data is received from the server.
|
||||||
|
:on-sent is called when data has been successfully sent to
|
||||||
|
the server ('delivered' is a list of what was sent).
|
||||||
|
:on-error is only invoked once just before the connection is
|
||||||
|
closed, and only if there was an error."
|
||||||
[handler & [options]]
|
[handler & [options]]
|
||||||
(let [options (merge default-options options)]
|
(let [options (merge default-options options)]
|
||||||
(events/listen
|
(events/listen js/window "unload" #(disconnect!))
|
||||||
js/window "unload"
|
|
||||||
(fn []
|
|
||||||
(disconnect!)))
|
|
||||||
|
|
||||||
(.setHandler channel (->handler handler))
|
(.setHandler channel (->handler handler))
|
||||||
(apply-options! options)
|
(apply-options! options)
|
||||||
(let [csrf-token (get-anti-forgery-token)
|
(let [csrf-token (get-anti-forgery-token)
|
||||||
|
|
Reference in a new issue