1
0
Эх сурвалжийг харах

feat: add frontend.pubsub ns (#8312)

* feat: add frontend.pubsub ns
* update clj-kondo config
rcmerci 2 жил өмнө
parent
commit
08edcb76b4

+ 3 - 1
.clj-kondo/config.edn

@@ -22,7 +22,9 @@
                              frontend.util/node-path.dirname
                              frontend.util/node-path.join
                              frontend.util/node-path.extname
-                             frontend.util/node-path.name]}
+                             frontend.util/node-path.name
+                             ;; frontend.pubsub/def-mult-or-pub generate vars clj-kondo cannot resolve
+                             frontend.pubsub]}
 
   :consistent-alias
   {:aliases {cljs.reader reader

+ 3 - 2
src/main/frontend/fs/sync.cljs

@@ -27,6 +27,7 @@
             [frontend.db :as db]
             [frontend.fs :as fs]
             [frontend.encrypt :as encrypt]
+            [frontend.pubsub :as pubsub]
             [logseq.graph-parser.util :as gp-util]
             [medley.core :refer [dedupe-by]]
             [rum.core :as rum]
@@ -2766,7 +2767,7 @@
     (async/tap remote->local-sync-mult private-remote->local-sync-chan)
     (async/tap remote->local-full-sync-mult private-remote->local-full-sync-chan)
     (async/tap pause-resume-mult private-pause-resume-chan)
-    (async/tap util/app-wake-up-from-sleep-mult app-awake-from-sleep-chan)
+    (async/tap pubsub/app-wake-up-from-sleep-mult app-awake-from-sleep-chan)
     (go-loop []
       (let [{:keys [remote->local remote->local-full-sync local->remote-full-sync local->remote resume pause stop]}
             (async/alt!
@@ -3074,7 +3075,7 @@
         (async/untap remote->local-sync-mult private-remote->local-sync-chan)
         (async/untap remote->local-full-sync-mult private-remote->local-full-sync-chan)
         (async/untap pause-resume-mult private-pause-resume-chan)
-        (async/untap util/app-wake-up-from-sleep-mult app-awake-from-sleep-chan)
+        (async/untap pubsub/app-wake-up-from-sleep-mult app-awake-from-sleep-chan)
         (when ops-chan (async/close! ops-chan))
         (stop-local->remote! local->remote-syncer)
         (stop-remote->local! remote->local-syncer)

+ 75 - 0
src/main/frontend/pubsub.cljc

@@ -0,0 +1,75 @@
+(ns frontend.pubsub
+  "All mults and pubs are collected to this ns.
+  vars with suffix '-mult' is a/Mult, use a/tap and a/untap on them. used by event subscribers
+  vars with suffix '-pub' is a/Pub, use a/sub and a/unsub on them. used by event subscribers
+  vars with suffix '-ch' is chan used by event publishers."
+  {:clj-kondo/config {:linters {:unresolved-symbol {:level :off}}}}
+  #?(:cljs (:require-macros [frontend.pubsub :refer [def-mult-or-pub chan-of]]))
+  (:require [clojure.core.async :as a :refer [chan mult pub]]
+            [clojure.core.async.impl.protocols :as ap]
+            [malli.core :as m]
+            [malli.dev.pretty :as mdp]
+            [clojure.pprint :as pp]))
+
+;;; helper macro
+(defmacro chan-of [malli-schema malli-schema-validator & chan-args]
+  `(let [ch# (chan ~@chan-args)]
+     (reify
+       ap/ReadPort
+       (~'take! [~'_ fn1-handler#]
+        (ap/take! ch# fn1-handler#))
+       ap/WritePort
+       (~'put! [~'_ val# fn1-handler#]
+        (if (~malli-schema-validator val#)
+          (ap/put! ch# val# fn1-handler#)
+          (do (mdp/explain ~malli-schema val#)
+              (throw (ex-info "validate chan value failed" {:val val#}))))))))
+
+(defmacro def-mult-or-pub
+  "define following vars:
+  - `symbol-name`-ch for event publisher.
+  - `symbol-name`-mult or `symbol-name`-pub for event subscribers.
+  - `symbol-name`-validator is malli schema validator
+  def -pub var when `:topic-fn` exists otherwise -mult var"
+  [symbol-name doc-string malli-schema & {:keys [ch-buffer topic-fn]
+                                          :or   {ch-buffer 1}}]
+  (let [schema-validator-name (symbol (str symbol-name "-validator"))
+        schema-name           (symbol (str symbol-name "-schema"))
+        ch-name               (symbol (str symbol-name "-ch"))
+        mult-or-pub-name      (if topic-fn
+                                (symbol (str symbol-name "-pub"))
+                                (symbol (str symbol-name "-mult")))
+        doc-string*           (str doc-string "\nMalli-schema:\n" (with-out-str (pp/pprint malli-schema)))]
+    `(do
+       (def ~schema-name ~malli-schema)
+       (def ~schema-validator-name (m/validator ~malli-schema))
+       (def ~ch-name ~doc-string* (chan-of ~malli-schema ~schema-validator-name ~ch-buffer))
+       ~(if topic-fn
+          `(def ~mult-or-pub-name ~doc-string* (pub ~ch-name ~topic-fn))
+          `(def ~mult-or-pub-name ~doc-string* (mult ~ch-name))))))
+
+;;; all chan, mult, pub defined here...
+
+(def-mult-or-pub app-wake-up-from-sleep
+  "app wake up from sleep event"
+  [:map
+   [:last-activated-at :int]
+   [:now :int]])
+
+(def-mult-or-pub sync-events
+  "file-sync events"
+  [:map
+   [:event [:enum
+            :created-local-version-file
+            :finished-local->remote
+            :finished-remote->local
+            :start
+            :pause
+            :resume
+            :exception-decrypt-failed
+            :remote->local-full-sync-failed
+            :local->remote-full-sync-failed
+            :get-remote-graph-failed
+            :get-deletion-logs-failed]]
+   [:data :map]]
+  :topic-fn :event)

+ 4 - 5
src/main/frontend/util.cljc

@@ -28,7 +28,8 @@
             [rum.core :as rum]
             [clojure.core.async :as async]
             [cljs.core.async.impl.channels :refer [ManyToManyChannel]]
-            [medley.core :as medley]))
+            [medley.core :as medley]
+            [frontend.pubsub :as pubsub]))
   (:require
    [clojure.pprint]
    [clojure.string :as string]
@@ -1448,11 +1449,9 @@
 
 #?(:cljs
    (do
-     (def ^:private app-wake-up-from-sleep-chan (async/chan 1))
-     (def app-wake-up-from-sleep-mult (async/mult app-wake-up-from-sleep-chan))
      (defn <app-wake-up-from-sleep-loop
        "start a async/go-loop to check the app awake from sleep.
-Use (async/tap `app-wake-up-from-sleep-mult`) to receive messages.
+Use (async/tap `pubsub/app-wake-up-from-sleep-mult`) to receive messages.
 Arg *stop: atom, reset to true to stop the loop"
        [*stop]
        (let [*last-activated-at (volatile! (tc/to-epoch (t/now)))]
@@ -1461,7 +1460,7 @@ Arg *stop: atom, reset to true to stop the loop"
              (println :<app-wake-up-from-sleep-loop :stop)
              (let [now-epoch (tc/to-epoch (t/now))]
                (when (< @*last-activated-at (- now-epoch 10))
-                 (async/>! app-wake-up-from-sleep-chan {:last-activated-at @*last-activated-at :now now-epoch}))
+                 (async/>! pubsub/app-wake-up-from-sleep-ch {:last-activated-at @*last-activated-at :now now-epoch}))
                (vreset! *last-activated-at now-epoch)
                (async/<! (async/timeout 5000))
                (recur))))))))