penpot/frontend/src/app/util/worker.cljs
2020-08-18 19:32:11 +02:00

53 lines
1.5 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns app.util.worker
"A lightweight layer on top of webworkers api."
(:require
[beicon.core :as rx]
[app.common.uuid :as uuid]
[app.util.transit :as t]))
(declare handle-response)
(defrecord Worker [instance stream])
(defn ask!
[w message]
(let [sender-id (uuid/next)
data (t/encode {:payload message :sender-id sender-id})
instance (:instance w)]
(.postMessage instance data)
(->> (:stream w)
(rx/filter #(= (:reply-to %) sender-id))
(rx/map handle-response)
(rx/first))))
(defn init
"Return a initialized webworker instance."
[path on-error]
(let [ins (js/Worker. path)
bus (rx/subject)
wrk (Worker. ins bus)]
(.addEventListener ins "message"
(fn [event]
(let [data (.-data event)
data (t/decode data)]
(rx/push! bus data))))
(.addEventListener ins "error"
(fn [error]
(on-error wrk error)))
wrk))
(defn- handle-response
[{:keys [payload error] :as response}]
(if-let [{:keys [data message]} error]
(throw (ex-info message data))
payload))