enhance(rtc): update schema, fix download-graph

pull/10438/head
rcmerci 2023-10-03 22:30:42 +08:00
parent b3e95ef52f
commit 38d861e0e0
5 changed files with 129 additions and 17 deletions

View File

@ -1,4 +1,7 @@
(ns frontend.db.rtc.const)
(ns frontend.db.rtc.const
(:require [malli.util :as mu]
[malli.core :as m]
[malli.transform :as mt]))
(def general-attrs-schema-coll
@ -52,3 +55,86 @@
[:map {:closed true}
[:op :keyword]
[:block-uuid :string]]]]]]])
(def data-from-ws-decoder (m/decoder data-from-ws-schema mt/string-transformer))
(def data-from-ws-validator (m/validator data-from-ws-schema))
(def block-type-schema [:enum "property" "class" "whiteboard" "macros" "object"])
(def op-schema
[:multi {:dispatch first :decode/string #(update % 0 keyword)}
[:move
[:cat :keyword
[:map
[:block-uuid :uuid]
[:target-uuid :uuid]
[:sibling? :boolean]]]]
[:remove
[:cat :keyword
[:map
[:block-uuids [:sequential :uuid]]]]]
[:update
[:cat :keyword
[:map
[:block-uuid :uuid]
[:target-uuid {:optional true} :uuid]
[:sibling? {:optional true} :boolean]
[:content {:optional true} :string]
[:updated-at {:optional true} :int]
[:created-at {:optional true} :int]
[:tags {:optional true} [:map
[:add {:optional true} [:maybe [:set :uuid]]]
[:retract {:optional true} [:maybe [:set :uuid]]]]]
[:alias {:optional true} [:map
[:add {:optional true} [:maybe [:set :uuid]]]
[:retract {:optional true} [:maybe [:set :uuid]]]]]
[:type {:optional true} [:map
[:add {:optional true} [:maybe [:set block-type-schema]]]
[:retract {:optional true} [:maybe [:set block-type-schema]]]]]
[:schema {:optional true} [:map-of :keyword :any]]]]]
[:update-page
[:cat :keyword
[:map
[:block-uuid :uuid]
[:page-name :string]]]]
[:remove-page
[:cat :keyword
[:map
[:block-uuid :uuid]]]]])
(def data-to-ws-schema
(mu/closed-schema
[:multi {:dispatch :action}
["list-graphs"
[:map
[:req-id :string]
[:action :string]]]
["register-graph-updates"
[:map
[:req-id :string]
[:action :string]
[:graph-uuid :string]]]
["apply-ops"
[:map
[:req-id :string]
[:action :string]
[:graph-uuid :string]
[:ops [:sequential op-schema]]
[:t-before :int]]]
["presign-put-temp-s3-obj"
[:map
[:req-id :string]
[:action :string]]]
["full-download-graph"
[:map
[:req-id :string]
[:action :string]
[:graph-uuid :string]]]
["full-upload-graph"
[:map
[:req-id :string]
[:action :string]
[:s3-key :string]]]]))
(def data-to-ws-decoder (m/decoder data-to-ws-schema mt/string-transformer))
(def data-to-ws-validator (m/validator data-to-ws-schema))

View File

@ -16,10 +16,29 @@
[frontend.modules.outliner.transaction :as outliner-tx]
[frontend.util :as util]
[malli.core :as m]
[malli.transform :as mt]
[malli.util :as mu]))
;; +-------------+
;; | |
;; | server |
;; | |
;; +----^----+---+
;; | |
;; | |
;; | rtc-const/data-from-ws-schema
;; | |
;; rtc-const/data-to-ws-schema |
;; | |
;; | |
;; | |
;; +----+----v---+ +------------+
;; | +---------------------> |
;; | client | | indexeddb |
;; | |<--------------------+ |
;; +-------------+ +------------+
;; frontend.db.rtc.op/op-schema
(def state-schema
"
| :user-uuid | string |
@ -50,12 +69,6 @@
[:enum :open :closed])
(def rtc-state-validator (m/validator rtc-state-schema))
(def data-from-ws-decoder (m/decoder rtc-const/data-from-ws-schema mt/string-transformer))
(def data-from-ws-validator (fn [data] (if ((m/validator rtc-const/data-from-ws-schema) data)
true
(prn data))))
(defn apply-remote-remove-ops
[repo remove-ops]
@ -240,7 +253,7 @@
(defn <apply-remote-data
[repo data-from-ws]
{:pre [(data-from-ws-validator data-from-ws)]}
(assert (rtc-const/data-from-ws-validator data-from-ws) data-from-ws)
(go
(let [
affected-blocks-map (:affected-blocks data-from-ws)
@ -435,7 +448,7 @@
;; else
(throw (ex-info "Unavailable" {:remote-ex remote-ex})))
(do (<! (p->c (op/<clean-ops repo op-keys)))
(<! (<apply-remote-data repo (data-from-ws-decoder r)))
(<! (<apply-remote-data repo (rtc-const/data-from-ws-decoder r)))
(prn :<client-op-update-handler r))))))
(defn <loop-for-rtc
@ -447,7 +460,7 @@
(reset! (:*repo state) repo)
(reset! (:*rtc-state state) :open)
(let [{:keys [data-from-ws-pub client-op-update-chan]} state
push-data-from-ws-ch (chan (async/sliding-buffer 100) (map data-from-ws-decoder))
push-data-from-ws-ch (chan (async/sliding-buffer 100) (map rtc-const/data-from-ws-decoder))
stop-rtc-loop-chan (chan)]
(reset! (:*stop-rtc-loop-chan state) stop-rtc-loop-chan)
(<! (ws/<ensure-ws-open! state))

View File

@ -93,8 +93,7 @@
(let [s (or s (<! (rtc-core/<init-state)))
graph-list (with-sub-data-from-ws s
(<! (ws/<send! s {:req-id (get-req-id)
:action "list-graphs"
:graph-uuid "placeholder"}))
:action "list-graphs"}))
(:graphs (<! (get-result-ch))))]
(reset! (::remote-graphs state) (map :graph-uuid graph-list))
(reset! debug-state s)))))]

View File

@ -40,19 +40,26 @@
(go
(let [{:keys [url key all-blocks-str]}
(with-sub-data-from-ws state
(<! (<send! state {:req-id (get-req-id) :action "presign-put-temp-s3-obj" :graph-uuid "not-yet"}))
(<! (<send! state {:req-id (get-req-id) :action "presign-put-temp-s3-obj"}))
(let [all-blocks (export-as-blocks repo)
all-blocks-str (transit/write (transit/writer :json) all-blocks)]
(merge (<! (get-result-ch)) {:all-blocks-str all-blocks-str})))]
(<! (http/put url {:body all-blocks-str}))
(with-sub-data-from-ws state
(<! (<send! state {:req-id (get-req-id) :action "full-upload-graph" :graph-uuid "not-yet" :s3-key key}))
(<! (<send! state {:req-id (get-req-id) :action "full-upload-graph" :s3-key key}))
(let [r (<! (get-result-ch))]
(if-not (:graph-uuid r)
(ex-info "upload graph failed" r)
(do (<! (p->c (op/<update-graph-uuid! repo (:graph-uuid r))))
r)))))))
(def block-type-ident->str
{:block-type/property "property"
:block-type/class "class"
:block-type/whiteboard "whiteboard"
:block-type/macros "macros"
:block-type/object "object"})
(defn- replace-db-id-with-temp-id
[blocks]
@ -61,11 +68,16 @@
(let [db-id (:db/id block)
block-parent (:db/id (:block/parent block))
block-left (:db/id (:block/left block))
block-alias (map :db/id (:block/alias block))]
block-alias (map :db/id (:block/alias block))
block-tags (map :db/id (:block/tags block))
block-type (keep (comp block-type-ident->str :db/ident) (:block/type block))]
;; TODO: :block/tags :block/type
(cond-> (assoc block :db/id (str db-id))
block-parent (assoc :block/parent (str block-parent))
block-left (assoc :block/left (str block-left))
(seq block-alias) (assoc :block/alias (map str block-alias)))))
(seq block-alias) (assoc :block/alias (map str block-alias))
(seq block-tags) (assoc :block/tags (map str block-tags))
(seq block-type) (assoc :block/type block-type))))
blocks))
(def page-of-block

View File

@ -3,6 +3,7 @@
[frontend.db.rtc.macro :refer [with-sub-data-from-ws get-req-id get-result-ch]])
(:require [frontend.config :as config]
[frontend.util :as util]
[frontend.db.rtc.const :as rtc-const]
[cljs.core.async :as async :refer [<! >! chan go go-loop offer!
poll! timeout]]))
@ -23,6 +24,7 @@
(defn send!
[ws message]
(assert (= js/WebSocket.OPEN (.-readyState ws)))
(assert (rtc-const/data-to-ws-validator (rtc-const/data-to-ws-decoder message)) message)
(.send ws (js/JSON.stringify (clj->js message))))
(declare <send!)