ludus/out/clojure/browser/net.cljs

182 lines
5.0 KiB
Plaintext
Raw Normal View History

2023-11-16 18:22:15 +00:00
;; Copyright (c) Rich Hickey. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.
(ns ^{:doc "Network communication library, wrapping goog.net.
Includes a common API over XhrIo, CrossPageChannel, and Websockets."
:author "Bobby Calderwood and Alex Redington"}
clojure.browser.net
(:require [clojure.browser.event :as event]
[goog.json :as gjson]
[goog.object :as gobj])
(:import [goog.net XhrIo EventType WebSocket]
[goog.net.xpc CfgFields CrossPageChannel]
[goog Uri]))
(def *timeout* 10000)
(def event-types
(into {}
(map
(fn [[k v]]
[(keyword (.toLowerCase k))
v])
(merge
(js->clj EventType)))))
(defprotocol IConnection
(connect
[this]
[this opt1]
[this opt1 opt2]
[this opt1 opt2 opt3])
(transmit
[this opt]
[this opt opt2]
[this opt opt2 opt3]
[this opt opt2 opt3 opt4]
[this opt opt2 opt3 opt4 opt5])
(close [this]))
(extend-type XhrIo
IConnection
(transmit
([this uri]
(transmit this uri "GET" nil nil *timeout*))
([this uri method]
(transmit this uri method nil nil *timeout*))
([this uri method content]
(transmit this uri method content nil *timeout*))
([this uri method content headers]
(transmit this uri method content headers *timeout*))
([this uri method content headers timeout]
(.setTimeoutInterval this timeout)
(.send this uri method content headers)))
event/IEventType
(event-types [this]
(into {}
(map
(fn [[k v]]
[(keyword (.toLowerCase k))
v])
(merge
(js->clj EventType))))))
;; TODO jQuery/sinatra/RestClient style API: (get [uri]), (post [uri payload]), (put [uri payload]), (delete [uri])
(def xpc-config-fields
(into {}
(map
(fn [[k v]]
[(keyword (.toLowerCase k))
v])
(js->clj CfgFields))))
(defn xhr-connection
"Returns an XhrIo connection"
[]
(XhrIo.))
(defprotocol ICrossPageChannel
(register-service [this service-name fn] [this service-name fn encode-json?]))
(extend-type CrossPageChannel
ICrossPageChannel
(register-service
([this service-name fn]
(register-service this service-name fn false))
([this service-name fn encode-json?]
(.registerService this (name service-name) fn encode-json?)))
IConnection
(connect
([this]
(connect this nil))
([this on-connect-fn]
(.connect this on-connect-fn))
([this on-connect-fn config-iframe-fn]
(connect this on-connect-fn config-iframe-fn (.-body js/document)))
([this on-connect-fn config-iframe-fn iframe-parent]
(.createPeerIframe this iframe-parent config-iframe-fn)
(.connect this on-connect-fn)))
(transmit [this service-name payload]
(.send this (name service-name) payload))
(close [this]
(.close this)))
(defn xpc-connection
"When passed with a config hash-map, returns a parent
CrossPageChannel object. Keys in the config hash map are downcased
versions of the goog.net.xpc.CfgFields enum keys,
e.g. goog.net.xpc.CfgFields.PEER_URI becomes :peer_uri in the config
hash.
When passed with no args, creates a child CrossPageChannel object,
and the config is automatically taken from the URL param 'xpc', as
per the CrossPageChannel API."
([]
(when-let [config (.getParameterValue
(Uri. (.-href (.-location js/window)))
"xpc")]
(CrossPageChannel. (gjson/parse config))))
([config]
(CrossPageChannel.
(reduce (fn [sum [k v]]
(if-let [field (get xpc-config-fields k)]
(doto sum (gobj/set field v))
sum))
(js-obj)
config))))
;; WebSocket is not supported in the 3/23/11 release of Google
;; Closure, but will be included in the next release.
(defprotocol IWebSocket
(open? [this]))
(extend-type WebSocket
IWebSocket
(open? [this]
(.isOpen this ()))
IConnection
(connect
([this url]
(connect this url nil))
([this url protocol]
(.open this url protocol)))
(transmit [this message]
(.send this message))
(close [this]
(.close this ()))
event/IEventType
(event-types [this]
(into {}
(map
(fn [[k v]]
[(keyword (. k (toLowerCase)))
v])
(merge
(js->clj WebSocket.EventType))))))
(defn websocket-connection
([]
(websocket-connection nil nil))
([auto-reconnect?]
(websocket-connection auto-reconnect? nil))
([auto-reconnect? next-reconnect-fn]
(WebSocket. auto-reconnect? next-reconnect-fn)))