mirror of https://github.com/logseq/logseq
refactor(rtc): remove deprecated ns and fns
parent
635e52dad4
commit
7f7248033d
|
@ -1,164 +0,0 @@
|
|||
(ns frontend.worker.rtc.asset-sync
|
||||
"Fns for syncing assets"
|
||||
{:clj-kondo/ignore true} ;; TODO: remove when this ns is ready
|
||||
(:require [malli.core :as m]
|
||||
[malli.util :as mu]
|
||||
[cljs.core.async :as async :refer [<! >! chan go go-loop]]
|
||||
[frontend.worker.rtc.const :as rtc-const]
|
||||
[frontend.worker.rtc.op-mem-layer :as op-mem-layer]
|
||||
[frontend.worker.rtc.ws :as ws]
|
||||
[frontend.worker.async-util :include-macros true :refer [<?]]
|
||||
[datascript.core :as d]
|
||||
[frontend.worker.state :as state]))
|
||||
|
||||
(def state-schema
|
||||
[:map {:closed true}
|
||||
[:*graph-uuid :any]
|
||||
[:*repo :any]
|
||||
[:*db-conn :any]
|
||||
[:*token :any]
|
||||
[:*date-formatter :any]
|
||||
[:*ws :any]
|
||||
[:*assets-update-state :any]
|
||||
[:data-from-ws-chan :any]
|
||||
[:data-from-ws-pub :any]
|
||||
[:*auto-push-assets-update-ops? :any]
|
||||
[:toggle-auto-push-assets-update-ops-chan :any]
|
||||
[:*stop-asset-sync-loop-chan :any]])
|
||||
|
||||
(def state-validator
|
||||
(let [validator (m/validator state-schema)]
|
||||
(fn [data]
|
||||
(if (validator data)
|
||||
true
|
||||
(prn (mu/explain-data state-schema data))))))
|
||||
|
||||
(defonce *asset-sync-state (atom nil))
|
||||
|
||||
(defn init-state-from-rtc-state
|
||||
[rtc-state]
|
||||
{:post [(m/validate state-schema %)]}
|
||||
{:*graph-uuid (atom nil)
|
||||
:*repo (atom nil)
|
||||
:*db-conn (atom nil)
|
||||
:*token (:*token rtc-state)
|
||||
:*date-formatter (atom nil)
|
||||
:*ws (:*ws rtc-state)
|
||||
:*assets-update-state (atom nil)
|
||||
:data-from-ws-chan (:data-from-ws-chan rtc-state)
|
||||
:data-from-ws-pub (:data-from-ws-pub rtc-state)
|
||||
:*auto-push-assets-update-ops? (atom true :validator boolean?)
|
||||
:toggle-auto-push-assets-update-ops-chan (chan (async/sliding-buffer 1))
|
||||
:*stop-asset-sync-loop-chan (atom nil)})
|
||||
|
||||
|
||||
(defn- <push-data-from-ws-handler
|
||||
[repo push-data-from-ws]
|
||||
(prn ::push-data-from-ws :push-data-from-ws)
|
||||
(go nil)
|
||||
;; TODO
|
||||
)
|
||||
|
||||
(defn <upload-client-op-loop
|
||||
[state graph-uuid repo conn]
|
||||
(go-loop []
|
||||
(when-let [{min-epoch-asset-ops :ops asset-uuid :asset-uuid} (op-mem-layer/get-min-epoch-asset-ops repo)]
|
||||
(let [recur?
|
||||
(try
|
||||
(doseq [[tp _op] min-epoch-asset-ops]
|
||||
(case tp
|
||||
:update-asset
|
||||
(let [asset-entity (d/pull @conn '[*] [:asset/uuid asset-uuid])
|
||||
r (<? (ws/<send&receive state {:action "update-assets" :graph-uuid graph-uuid
|
||||
:create [{:asset-uuid asset-uuid
|
||||
:asset-name (or (some-> asset-entity :asset/meta :name)
|
||||
"default-name")}]}))]
|
||||
(when (:ex-data r)
|
||||
(throw (ex-info (:ex-message r) (:ex-data r)))))
|
||||
|
||||
:remove-asset
|
||||
(let [r (<? (ws/<send&receive state {:action "update-assets" :graph-uuid graph-uuid
|
||||
:delete [asset-uuid]}))]
|
||||
(when (:ex-data r)
|
||||
(throw (ex-info (:ex-message r) (:ex-data r)))))))
|
||||
(op-mem-layer/remove-asset-ops! repo asset-uuid)
|
||||
:recur
|
||||
(catch :default e
|
||||
(prn ::unknown-ex e)
|
||||
nil))]
|
||||
(when (= :recur recur?)
|
||||
(recur))))))
|
||||
|
||||
|
||||
(defn- <client-op-update-handler
|
||||
[state]
|
||||
{:pre [(some? @(:*graph-uuid state))
|
||||
(some? @(:*repo state))
|
||||
(some? @(:*db-conn state))]}
|
||||
(go
|
||||
(let [repo @(:*repo state)
|
||||
conn @(:*db-conn state)
|
||||
graph-uuid @(:*graph-uuid state)]
|
||||
(<! (<upload-client-op-loop state graph-uuid repo conn)))))
|
||||
|
||||
|
||||
(defn- make-push-assets-update-ops-timeout-ch
|
||||
[repo never-timeout?]
|
||||
(if never-timeout?
|
||||
(chan)
|
||||
(go
|
||||
(<! (async/timeout 2000))
|
||||
(pos? (op-mem-layer/get-unpushed-asset-update-count repo)))))
|
||||
|
||||
(defn <loop-for-assets-sync
|
||||
[state graph-uuid repo conn & {:keys [loop-started-ch]}]
|
||||
{:pre [(state-validator state)]}
|
||||
(go
|
||||
(reset! (:*repo state) repo)
|
||||
(reset! (:*graph-uuid state) graph-uuid)
|
||||
(reset! (:*db-conn state) conn)
|
||||
(let [{:keys [data-from-ws-pub]} state
|
||||
*auto-push-assets-update-ops? (:*auto-push-assets-update-ops? state)
|
||||
toggle-auto-push-assets-update-ops-ch (:toggle-auto-push-assets-update-ops-chan state)
|
||||
push-data-from-ws-ch (chan (async/sliding-buffer 100) (map rtc-const/data-from-ws-coercer))
|
||||
stop-assets-sync-loop-chan (chan)]
|
||||
(reset! (:*stop-asset-sync-loop-chan state) stop-assets-sync-loop-chan)
|
||||
(async/sub data-from-ws-pub "push-assets-updates" push-data-from-ws-ch)
|
||||
(when loop-started-ch
|
||||
(prn ::just-for-test (<? (ws/<send&receive state {:action "list-graphs"})))
|
||||
(async/close! loop-started-ch))
|
||||
(<! (go-loop [push-assets-update-ops-ch
|
||||
(make-push-assets-update-ops-timeout-ch repo (not @*auto-push-assets-update-ops?))]
|
||||
(let [{:keys [continue push-data-from-ws client-assets-update stop]}
|
||||
(async/alt!
|
||||
toggle-auto-push-assets-update-ops-ch {:continue true}
|
||||
push-assets-update-ops-ch ([v] (if (and @*auto-push-assets-update-ops? (true? v))
|
||||
{:client-assets-update true}
|
||||
{:continue true}))
|
||||
push-data-from-ws-ch ([v] {:push-data-from-ws v})
|
||||
stop-assets-sync-loop-chan {:stop true}
|
||||
:priority true)]
|
||||
(cond
|
||||
continue
|
||||
(recur (make-push-assets-update-ops-timeout-ch repo (not @*auto-push-assets-update-ops?)))
|
||||
|
||||
push-data-from-ws
|
||||
(let [r (<push-data-from-ws-handler repo push-data-from-ws)]
|
||||
(prn ::<push-data-from-ws-handler r)
|
||||
(recur (make-push-assets-update-ops-timeout-ch repo (not @*auto-push-assets-update-ops?))))
|
||||
|
||||
client-assets-update
|
||||
;; TODO: <wrap-ensure-id&access-token, ensure token not expired
|
||||
;; because this ns is running in db-worker now, need to move(or copy) <wrap-ensure-id&access-token
|
||||
;; to db-worker again
|
||||
(let [maybe-exp (<! (<client-op-update-handler state))]
|
||||
(if (= :expired-token (:anom (ex-data maybe-exp)))
|
||||
(prn ::<loop-for-assets-sync "quitting loop" maybe-exp)
|
||||
(recur (make-push-assets-update-ops-timeout-ch repo (not @*auto-push-assets-update-ops?)))))
|
||||
|
||||
stop
|
||||
;; (ws/stop @(:*ws state)) ;; use same ws with <rtc-loop
|
||||
(reset! (:*assets-update-state state) :closed)
|
||||
|
||||
:else nil))))
|
||||
(async/unsub data-from-ws-pub "push-assets-update" push-data-from-ws-ch))))
|
|
@ -1,24 +0,0 @@
|
|||
(ns frontend.worker.rtc.macro
|
||||
"Macros that are used for rtc")
|
||||
|
||||
(def ^:private magic-str "YBTFRD")
|
||||
|
||||
(defmacro with-sub-data-from-ws
|
||||
"TODO: result-ch also sub exception response (:req-id=nil in response)
|
||||
- sub :data-from-ws-pub
|
||||
- run body, use `get-req-id` to get req-id, and `get-result-ch` to get result-ch
|
||||
- unsub :data-from-ws-pub"
|
||||
[state & body]
|
||||
(let [req-id-sym (symbol (str magic-str "-req-id"))
|
||||
result-ch-sym (symbol (str magic-str "-result-ch"))]
|
||||
`(let [~req-id-sym (str (random-uuid))
|
||||
data-from-ws-pub# (:data-from-ws-pub ~state)
|
||||
~result-ch-sym (cljs.core.async/chan 1)]
|
||||
(cljs.core.async/sub data-from-ws-pub# ~req-id-sym ~result-ch-sym)
|
||||
(try
|
||||
~@body
|
||||
(finally
|
||||
(cljs.core.async/unsub data-from-ws-pub# ~req-id-sym ~result-ch-sym))))))
|
||||
|
||||
(defmacro get-req-id [] (symbol (str magic-str "-req-id")))
|
||||
(defmacro get-result-ch [] (symbol (str magic-str "-result-ch")))
|
|
@ -1,95 +0,0 @@
|
|||
(ns frontend.worker.rtc.ws
|
||||
"Websocket related util-fns"
|
||||
(:require-macros
|
||||
[frontend.worker.rtc.macro :refer [with-sub-data-from-ws get-req-id get-result-ch]])
|
||||
(:require [cljs-http.client :as http]
|
||||
[cljs.core.async :as async :refer [<! chan offer!]]
|
||||
[frontend.worker.async-util :include-macros true :refer [<? go-try]]
|
||||
[frontend.worker.rtc.const :as rtc-const]
|
||||
[frontend.worker.state :as worker-state]
|
||||
[goog.string :as gstring]))
|
||||
|
||||
(def WebSocketOPEN (if (= *target* "nodejs")
|
||||
1
|
||||
js/WebSocket.OPEN))
|
||||
|
||||
(defn ws-listen
|
||||
[token data-from-ws-chan ws-opened-ch]
|
||||
(let [ws (js/WebSocket. (gstring/format @worker-state/*rtc-ws-url token))]
|
||||
(set! (.-onopen ws) (fn [_e] (async/close! ws-opened-ch)))
|
||||
(set! (.-onmessage ws) (fn [e]
|
||||
(let [data (js->clj (js/JSON.parse (.-data e)) :keywordize-keys true)]
|
||||
(offer! data-from-ws-chan data))))
|
||||
|
||||
(set! (.-onclose ws) (fn [e]
|
||||
(println :ws-stopped)
|
||||
(js/console.error e)))
|
||||
ws))
|
||||
|
||||
(defn send!
|
||||
[ws message]
|
||||
(assert (= WebSocketOPEN (.-readyState ws)))
|
||||
(let [decoded-message (rtc-const/data-to-ws-coercer message)]
|
||||
(.send ws (js/JSON.stringify (clj->js (rtc-const/data-to-ws-encoder decoded-message))))))
|
||||
|
||||
(declare <send!)
|
||||
(defn <ensure-ws-open!
|
||||
"ensure websocket in state is OPEN, if not, make a connection, and
|
||||
call init 'register-graph-updates' message"
|
||||
[state]
|
||||
(go-try
|
||||
(let [ws @(:*ws state)]
|
||||
(when (or (nil? ws)
|
||||
(> (.-readyState ws) WebSocketOPEN))
|
||||
(let [ws-opened-ch (chan)
|
||||
ws* (ws-listen @(:*token state) (:data-from-ws-chan state) ws-opened-ch)]
|
||||
(<! ws-opened-ch)
|
||||
(reset! (:*ws state) ws*)
|
||||
(when-let [graph-uuid @(:*graph-uuid state)]
|
||||
(with-sub-data-from-ws state
|
||||
(<? (<send! state {:action "register-graph-updates" :req-id (get-req-id) :graph-uuid graph-uuid}))
|
||||
(<! (get-result-ch)))))))))
|
||||
|
||||
(defn <send!
|
||||
"ensure ws state=open, then send messages"
|
||||
[state message]
|
||||
(go-try
|
||||
(<? (<ensure-ws-open! state))
|
||||
(send! @(:*ws state) message)))
|
||||
|
||||
(defn <send&receive
|
||||
"Send 'message' to ws, and return response of this request.
|
||||
When this response is too huge, backend will put it in s3 and return the presigned-url,
|
||||
this fn will handle this case."
|
||||
[state message]
|
||||
(go-try
|
||||
(with-sub-data-from-ws state
|
||||
(<? (<send! state (assoc message :req-id (get-req-id))))
|
||||
(let [resp (<! (get-result-ch))
|
||||
resp*
|
||||
(if-let [s3-presign-url (:s3-presign-url resp)]
|
||||
(let [{:keys [status body]} (<! (http/get s3-presign-url {:with-credentials? false}))]
|
||||
(if (http/unexceptional-status? status)
|
||||
(js->clj (js/JSON.parse body) :keywordize-keys true)
|
||||
{:req-id (get-req-id)
|
||||
:ex-message "get s3 object failed"
|
||||
:ex-data {:type :get-s3-object-failed :status status :body body}}))
|
||||
resp)]
|
||||
(rtc-const/data-from-ws-coercer resp*)))))
|
||||
|
||||
|
||||
(defn stop
|
||||
[ws]
|
||||
(set! (.-onopen ws) nil)
|
||||
(set! (.-onclose ws) nil)
|
||||
(set! (.-onmessage ws) nil)
|
||||
(set! (.-onerror ws) nil)
|
||||
(.close ws))
|
||||
|
||||
(defn get-state
|
||||
[ws]
|
||||
(case (.-readyState ws)
|
||||
0 :connecting
|
||||
1 :open
|
||||
2 :closing
|
||||
3 :closed))
|
|
@ -1,24 +0,0 @@
|
|||
(ns frontend.worker.rtc.asset-sync-effects-test
|
||||
"This ns include tests abouts asset-sync with other components.
|
||||
These tests need to start the asset-sync-loop."
|
||||
#_:clj-kondo/ignore
|
||||
(:require [clojure.test :as t :refer [deftest is use-fixtures]]
|
||||
[frontend.test.helper :include-macros true :as test-helper]
|
||||
[frontend.worker.rtc.fixture :as rtc-fixture]
|
||||
#_:clj-kondo/ignore
|
||||
[spy.core :as spy]))
|
||||
|
||||
(use-fixtures :each
|
||||
test-helper/db-based-start-and-destroy-db-map-fixture
|
||||
rtc-fixture/listen-test-db-to-gen-rtc-ops-fixture
|
||||
rtc-fixture/start-and-stop-asset-sync-loop-fixture
|
||||
rtc-fixture/clear-op-mem-stores-fixture)
|
||||
|
||||
|
||||
;; FIXME: Re-enable when this test doesn't fail when whole test suite is run
|
||||
;; e.g. https://github.com/logseq/logseq/actions/runs/7627378707/job/20775904183
|
||||
#_(deftest asset-sync-loop-init-test
|
||||
(let [ws @(:*ws @rtc-fixture/*test-asset-sync-state)
|
||||
handler-fn (:handler-fn ws)
|
||||
ws-msg (first (spy/last-call handler-fn))]
|
||||
(is (= "list-graphs" (:action ws-msg)))))
|
|
@ -1,92 +1,10 @@
|
|||
(ns frontend.worker.rtc.fixture
|
||||
(:require [cljs.core.async :as async :refer [<! >! chan go]]
|
||||
[cljs.test :as t]
|
||||
[datascript.core :as d]
|
||||
[frontend.db :as db]
|
||||
(:require [datascript.core :as d]
|
||||
[frontend.db.conn :as conn]
|
||||
[frontend.state :as state]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.worker.db-listener :as worker-db-listener]
|
||||
[frontend.worker.rtc.asset-sync :as asset-sync]
|
||||
[frontend.worker.rtc.core :as rtc-core]
|
||||
[frontend.worker.rtc.mock :as rtc-mock]
|
||||
[frontend.worker.rtc.op-mem-layer :as op-mem-layer]))
|
||||
|
||||
(def *test-rtc-state (atom nil))
|
||||
(def *test-asset-sync-state (atom nil))
|
||||
(def test-graph-uuid "e6d04ed7-bbc4-4ed2-a91b-69f3c0b9459d")
|
||||
(def test-graph-init-local-t 1)
|
||||
|
||||
(defn- init-state-helper
|
||||
[]
|
||||
(let [data-from-ws-chan (chan (async/sliding-buffer 100))
|
||||
ws (rtc-mock/mock-websocket data-from-ws-chan)]
|
||||
(assoc (rtc-core/init-state ws data-from-ws-chan "" "user-uuid" true)
|
||||
:*auto-push-client-ops? (atom false))))
|
||||
|
||||
(defn- init-state-helper-for-asset-sync-loop
|
||||
[]
|
||||
(let [data-from-ws-chan (chan (async/sliding-buffer 100))
|
||||
ws (rtc-mock/mock-websocket data-from-ws-chan)
|
||||
rtc-state (rtc-core/init-state ws data-from-ws-chan "" "user-uuid" true)]
|
||||
(assoc (asset-sync/init-state-from-rtc-state rtc-state)
|
||||
:*auto-push-assets-update-ops? (atom false))))
|
||||
|
||||
(defn- <start-rtc-loop
|
||||
[]
|
||||
(go
|
||||
(let [graph-uuid test-graph-uuid
|
||||
repo test-helper/test-db-name-db-version
|
||||
state (init-state-helper)
|
||||
loop-started-ch (chan)]
|
||||
(reset! *test-rtc-state state)
|
||||
(rtc-core/<loop-for-rtc state graph-uuid repo (db/get-db repo false) (state/get-date-formatter) :loop-started-ch loop-started-ch)
|
||||
(<! loop-started-ch))))
|
||||
|
||||
(defn- <start-asset-sync-loop
|
||||
[]
|
||||
(go
|
||||
(let [graph-uuid test-graph-uuid
|
||||
repo test-helper/test-db-name-db-version
|
||||
state (init-state-helper-for-asset-sync-loop)
|
||||
loop-started-ch (chan)]
|
||||
(reset! *test-asset-sync-state state)
|
||||
(asset-sync/<loop-for-assets-sync state graph-uuid repo (db/get-db repo false) :loop-started-ch loop-started-ch)
|
||||
(<! loop-started-ch))))
|
||||
|
||||
(def start-and-stop-rtc-loop-fixture
|
||||
{:before
|
||||
#(t/async done
|
||||
(go
|
||||
(<! (<start-rtc-loop))
|
||||
(prn :<started-rtc-loop)
|
||||
(done)))
|
||||
:after
|
||||
#(t/async done
|
||||
(go
|
||||
(when-let [stop-rtc-loop-chan (some-> (:*stop-rtc-loop-chan @*test-rtc-state) deref)]
|
||||
(prn :stopping-rtc-loop)
|
||||
(>! stop-rtc-loop-chan true))
|
||||
(reset! *test-rtc-state nil)
|
||||
(done)))})
|
||||
|
||||
(def start-and-stop-asset-sync-loop-fixture
|
||||
{:before
|
||||
#(t/async done
|
||||
(go
|
||||
(<! (<start-asset-sync-loop))
|
||||
(prn :<start-asset-sync-loop)
|
||||
(done)))
|
||||
:after
|
||||
#(t/async done
|
||||
(go
|
||||
(when-let [stop-asset-sync-loop-chan (some-> (:*stop-asset-sync-loop-chan @*test-asset-sync-state) deref)]
|
||||
(prn :stopping-asset-sync-loop)
|
||||
(>! stop-asset-sync-loop-chan true))
|
||||
(reset! *test-asset-sync-state nil)
|
||||
(done)))})
|
||||
|
||||
|
||||
(def listen-test-db-to-gen-rtc-ops-fixture
|
||||
{:before
|
||||
#(let [test-db-conn (conn/get-db test-helper/test-db-name-db-version false)]
|
||||
|
@ -97,7 +15,6 @@
|
|||
#(when-let [test-db-conn (conn/get-db test-helper/test-db-name-db-version false)]
|
||||
(d/unlisten! test-db-conn :frontend.worker.db-listener/listen-db-changes!))})
|
||||
|
||||
|
||||
(def clear-op-mem-stores-fixture
|
||||
{:before #(do (op-mem-layer/remove-ops-store! test-helper/test-db-name-db-version)
|
||||
(op-mem-layer/init-empty-ops-store! test-helper/test-db-name-db-version))
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.worker.rtc.const :as rtc-const]
|
||||
[frontend.worker.rtc.core :as rtc-core]
|
||||
[frontend.worker.rtc.client :as r.client]
|
||||
[frontend.worker.rtc.fixture :as rtc-fixture]
|
||||
[frontend.worker.state :as worker-state]
|
||||
[logseq.common.config :as common-config]
|
||||
|
@ -32,8 +32,8 @@
|
|||
:conn conn}}
|
||||
gen-ops-fn (fn []
|
||||
(let [r (rtc-const/to-ws-ops-decoder
|
||||
(rtc-core/sort-remote-ops
|
||||
(rtc-core/gen-block-uuid->remote-ops repo conn "user-uuid")))]
|
||||
(#'r.client/sort-remote-ops
|
||||
(#'r.client/gen-block-uuid->remote-ops repo conn "user-uuid")))]
|
||||
(is (rtc-const/to-ws-ops-validator r) r)
|
||||
r))]
|
||||
(testing "create a new page"
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
(ns frontend.worker.rtc.mock
|
||||
(:require [clojure.core.async :as async]
|
||||
[frontend.worker.rtc.const :as rtc-const]
|
||||
[spy.core :as spy]))
|
||||
|
||||
;;; websocket
|
||||
(defrecord Mock-WebSocket [onopen onmessage onclose onerror readyState push-data-to-client-chan ^:mutable handler-fn]
|
||||
Object
|
||||
(close [_]
|
||||
(prn :mock-ws :closed)
|
||||
(when (fn? onclose) (onclose)))
|
||||
(send [_ s]
|
||||
(let [msg (-> s
|
||||
js/JSON.parse
|
||||
(js->clj :keywordize-keys true)
|
||||
rtc-const/data-to-ws-coercer)]
|
||||
(handler-fn msg push-data-to-client-chan)))
|
||||
|
||||
(set-handler-fn [_ f]
|
||||
(set! handler-fn f)))
|
||||
|
||||
(defn default-handler
|
||||
[msg push-data-to-client-chan]
|
||||
(case (:action msg)
|
||||
"register-graph-updates"
|
||||
(async/offer! push-data-to-client-chan (select-keys msg [:req-id]))
|
||||
"list-graphs"
|
||||
(async/offer! push-data-to-client-chan (assoc (select-keys msg [:req-id])
|
||||
:graphs []))
|
||||
;; default
|
||||
nil))
|
||||
|
||||
|
||||
(defn mock-websocket
|
||||
[data-from-ws-chan]
|
||||
(->Mock-WebSocket nil (async/chan 10) nil nil 1
|
||||
data-from-ws-chan (spy/spy default-handler)))
|
||||
|
||||
|
||||
;; (defn set-ws-handler-fn
|
||||
;; [ws f]
|
||||
;; (.set-handler-fn ws f))
|
||||
|
||||
;;; websocket ends ;;;;
|
|
@ -6,7 +6,8 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.worker.rtc.const :as rtc-const]
|
||||
[frontend.worker.rtc.core :as rtc-core]
|
||||
[frontend.worker.rtc.remote-update :as r.remote]
|
||||
[frontend.worker.rtc.client :as r.client]
|
||||
[frontend.worker.rtc.op-mem-layer :as op-mem-layer]
|
||||
[frontend.worker.state :as worker-state]
|
||||
[logseq.common.config :as common-config]
|
||||
|
@ -34,7 +35,7 @@
|
|||
[["update" {:block-uuid uuid1
|
||||
:updated-attrs {:content nil}
|
||||
:epoch 1}]]
|
||||
r (rtc-core/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
r (#'r.remote/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
(is (= {uuid1
|
||||
{:op :move
|
||||
:self uuid1
|
||||
|
@ -55,7 +56,7 @@
|
|||
[["update" {:block-uuid uuid1
|
||||
:updated-attrs {:content nil}
|
||||
:epoch 1}]]
|
||||
r (rtc-core/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
r (#'r.remote/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
(is (= {uuid1
|
||||
{:op :update-attrs
|
||||
:self uuid1
|
||||
|
@ -71,7 +72,7 @@
|
|||
:block-uuid uuid1}}
|
||||
unpushed-ops
|
||||
[["move" {:block-uuid uuid1 :epoch 1}]]
|
||||
r (rtc-core/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
r (#'r.remote/filter-remote-data-by-local-unpushed-ops affected-blocks-map unpushed-ops)]
|
||||
(is (empty? r)))))
|
||||
|
||||
|
||||
|
@ -104,9 +105,9 @@
|
|||
["move" {:block-uuid (str uuid3) :epoch 3}]
|
||||
["update" {:block-uuid (str uuid4) :epoch 4}]])
|
||||
(let [_ (op-mem-layer/new-branch! repo)
|
||||
r1 (rtc-core/gen-block-uuid->remote-ops repo conn "user-uuid" :n 1)
|
||||
r1 (#'r.client/gen-block-uuid->remote-ops repo conn "user-uuid" :n 1)
|
||||
_ (op-mem-layer/rollback! repo)
|
||||
r2 (rtc-core/gen-block-uuid->remote-ops repo conn "user-uuid" :n 2)]
|
||||
r2 (#'r.client/gen-block-uuid->remote-ops repo conn "user-uuid" :n 2)]
|
||||
(is (= {uuid2 [:move]}
|
||||
(update-vals r1 keys)))
|
||||
(is (= {uuid2 [:move]
|
||||
|
@ -151,12 +152,12 @@
|
|||
:parents [page-uuid]
|
||||
:left page-uuid
|
||||
:content "uuid1-remote"}}}
|
||||
move-ops (#'rtc-core/move-ops-map->sorted-move-ops
|
||||
move-ops (#'r.remote/move-ops-map->sorted-move-ops
|
||||
(:move-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops
|
||||
(#'r.remote/affected-blocks->diff-type-ops
|
||||
repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(#'r.remote/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-remote uuid1-client uuid2-client} (set (map :block/uuid page-blocks))))
|
||||
(is (= page-uuid (:block/uuid (:block/left (d/entity @conn [:block/uuid uuid1-remote]))))))))
|
||||
|
@ -175,12 +176,12 @@
|
|||
:self uuid1-remote
|
||||
:parents [uuid2-remote]
|
||||
:left uuid2-remote}}}
|
||||
move-ops (#'rtc-core/move-ops-map->sorted-move-ops
|
||||
move-ops (#'r.remote/move-ops-map->sorted-move-ops
|
||||
(:move-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops
|
||||
(#'r.remote/affected-blocks->diff-type-ops
|
||||
repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(#'r.remote/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-remote uuid2-remote uuid1-client uuid2-client} (set (map :block/uuid page-blocks))))
|
||||
(is (= uuid1-client (:block/uuid (:block/left (d/entity @conn [:block/uuid uuid2-remote])))))
|
||||
|
@ -229,9 +230,9 @@
|
|||
:type ["property"]}}}
|
||||
update-ops (vals
|
||||
(:update-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(#'r.remote/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-client uuid2-client uuid1-remote} (set (map :block/uuid page-blocks))))
|
||||
(is (= [uuid1-client #{"property"}]
|
||||
|
@ -252,9 +253,9 @@
|
|||
:type nil}}}
|
||||
update-ops (vals
|
||||
(:update-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(#'r.remote/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-client uuid2-client uuid1-remote} (set (map :block/uuid page-blocks))))
|
||||
(is (= [nil nil] ((juxt :block/link :block/type) (d/entity @conn [:block/uuid uuid1-remote])))))))
|
||||
|
@ -269,9 +270,9 @@
|
|||
:link uuid1-not-exist}}}
|
||||
update-ops (vals
|
||||
(:update-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(#'r.remote/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-client uuid2-client uuid1-remote} (set (map :block/uuid page-blocks))))
|
||||
(is (= [nil nil] ((juxt :block/link :block/type) (d/entity @conn [:block/uuid uuid1-remote])))))))
|
||||
|
@ -286,13 +287,13 @@
|
|||
:tags [tag1-uuid]}}}
|
||||
update-ops (vals
|
||||
(:update-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(d/transact! conn [{:block/uuid tag1-uuid
|
||||
:block/type #{"class"},
|
||||
:block/name "task",
|
||||
:block/original-name "Task"}])
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(#'r.remote/apply-remote-update-ops repo conn date-formatter update-ops)
|
||||
(is (= #{tag1-uuid} (set (map :block/uuid (:block/tags (d/entity @conn [:block/uuid uuid1-remote]))))))))))
|
||||
|
||||
(deftest ^:fix-me apply-remote-remove-ops-test
|
||||
|
@ -328,9 +329,9 @@
|
|||
remove-ops
|
||||
(vals
|
||||
(:remove-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(#'r.remote/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1-client uuid2-client} (set (map :block/uuid page-blocks)))))))
|
||||
(testing "apply-remote-remove-ops-test2"
|
||||
|
@ -340,9 +341,9 @@
|
|||
:block-uuid uuid1-client}}}
|
||||
remove-ops (vals
|
||||
(:remove-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(#'r.remote/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid2-client} (set (map :block/uuid page-blocks)))))))))
|
||||
|
||||
|
@ -394,9 +395,9 @@ server: ;; remove 2
|
|||
remove-ops
|
||||
(vals
|
||||
(:remove-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(#'r.remote/apply-remote-remove-ops repo conn date-formatter remove-ops)
|
||||
(let [page-blocks (ldb/get-page-blocks @conn (:db/id (ldb/get-page @conn page-name)) {})]
|
||||
(is (= #{uuid1 uuid3} (set (map :block/uuid page-blocks))))
|
||||
(is (= page-uuid (:block/uuid (:block/left (d/entity @conn [:block/uuid uuid3]))))))))))
|
||||
|
@ -417,9 +418,9 @@ server: ;; remove 2
|
|||
:original-name (str page1-uuid)}}}
|
||||
update-page-ops (vals
|
||||
(:update-page-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(#'r.remote/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(is (= page1-uuid (:block/uuid (d/entity @conn [:block/uuid page1-uuid]))))))
|
||||
|
||||
(testing "apply-remote-update-page-ops-test2"
|
||||
|
@ -431,9 +432,9 @@ server: ;; remove 2
|
|||
:original-name (str page1-uuid "-rename")}}}
|
||||
update-page-ops (vals
|
||||
(:update-page-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(#'r.remote/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(is (= (str page1-uuid "-rename") (:block/name (d/entity @conn [:block/uuid page1-uuid]))))))
|
||||
|
||||
(testing "apply-remote-remove-page-ops-test1"
|
||||
|
@ -443,9 +444,9 @@ server: ;; remove 2
|
|||
:block-uuid page1-uuid}}}
|
||||
remove-page-ops (vals
|
||||
(:remove-page-ops-map
|
||||
(#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-remove-page-ops repo conn remove-page-ops)
|
||||
(#'r.remote/apply-remote-remove-page-ops repo conn remove-page-ops)
|
||||
(is (nil? (d/entity @conn [:block/uuid page1-uuid])))))))
|
||||
|
||||
;; TODO: add back once page merge get supported
|
||||
|
@ -493,12 +494,12 @@ server: ;; remove 2
|
|||
:parents [page2-uuid]
|
||||
:left uuid1-remote
|
||||
:content "uuid2-remote"}}}
|
||||
all-ops (#'rtc-core/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))
|
||||
all-ops (#'r.remote/affected-blocks->diff-type-ops repo (:affected-blocks data-from-ws))
|
||||
update-page-ops (vals (:update-page-ops-map all-ops))
|
||||
move-ops (#'rtc-core/move-ops-map->sorted-move-ops (:move-ops-map all-ops))]
|
||||
move-ops (#'r.remote/move-ops-map->sorted-move-ops (:move-ops-map all-ops))]
|
||||
(is (rtc-const/data-from-ws-validator data-from-ws))
|
||||
(rtc-core/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(rtc-core/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(#'r.remote/apply-remote-update-page-ops repo conn date-formatter update-page-ops)
|
||||
(#'r.remote/apply-remote-move-ops repo conn date-formatter move-ops)
|
||||
(let [page (ldb/get-page @conn page-name)]
|
||||
(is (= #{uuid1-client uuid2-client uuid1-remote uuid2-remote}
|
||||
(set (map :block/uuid (ldb/get-page-blocks @conn (:db/id page) {})))))
|
||||
|
|
Loading…
Reference in New Issue