🚧 More work on collaborative edition (in real time).

This commit is contained in:
Andrey Antukh 2019-12-19 13:13:08 +01:00
parent 34291fc4b4
commit 758c70f7c3
8 changed files with 282 additions and 110 deletions

View file

@ -48,7 +48,7 @@
(fn [ws message] (:type message)))
(defmethod handle-message :connect
[ws {:keys [file-id user-id] :as message}]
[{:keys [file-id user-id] :as ws} message]
(let [local (swap! state assoc-in [file-id user-id] ws)
sessions (get local file-id)
message {:type :who :users (set (keys sessions))}]
@ -66,22 +66,35 @@
(let [users (keys (get @state file-id))]
(send! ws {:type :who :users (set users)})))
;; --- Handler
(defmethod handle-message :pointer-update
[{:keys [user-id file-id] :as ws} message]
(let [sessions (->> (vals (get @state file-id))
(remove #(= user-id (:user-id %))))
message (assoc message :user-id user-id)]
(run! #(send! % message) sessions)))
(declare start-eventbus-consumer!)
(defn- on-eventbus-message
[{:keys [file-id user-id] :as ws} {:keys [body] :as message}]
(send! ws body))
(defn- start-eventbus-consumer!
[vsm ws fid]
(let [topic (str "internal.uxbox.file." fid)]
(ve/consumer vsm topic #(on-eventbus-message ws %2))))
;; --- Handler
(defn handler
[{:keys [user] :as req}]
(letfn [(on-init [ws]
(let [vsm (::vw/execution-context req)
fid (get-in req [:path-params :file-id])
ws (assoc ws
:user-id user
:file-id fid)
sem (start-eventbus-consumer! vsm ws fid)]
(handle-message ws {:type :connect :file-id fid :user-id user})
(assoc ws
::sem sem
:user-id user
:file-id fid)))
(handle-message ws {:type :connect})
(assoc ws ::sem sem)))
(on-message [ws message]
(try
@ -103,16 +116,6 @@
:on-message on-message
:on-close on-close))))
(defn- on-eventbus-message
[ws {:keys [body] :as message}]
;; TODO
(ws-send! ws body))
(defn- start-eventbus-consumer!
[vsm ws fid]
(let [topic (str "internal.uxbox.file." fid)]
(ve/consumer vsm topic #(on-eventbus-message ws %2))))
;; --- Internal (vertx api) (experimental)
(defrecord WebSocket [on-init on-message on-close]

View file

@ -8,17 +8,18 @@
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.common.pages :as cp]
[uxbox.db :as db]
[uxbox.services.mutations :as sm]
[uxbox.services.mutations.project-files :as files]
[uxbox.services.queries.project-pages :refer [decode-row]]
[uxbox.services.util :as su]
[uxbox.common.pages :as cp]
[uxbox.util.exceptions :as ex]
[uxbox.util.blob :as blob]
[uxbox.util.sql :as sql]
[uxbox.util.exceptions :as ex]
[uxbox.util.spec :as us]
[uxbox.util.uuid :as uuid]))
[uxbox.util.sql :as sql]
[uxbox.util.uuid :as uuid]
[vertx.eventbus :as ve]))
;; --- Helpers & Specs
@ -100,7 +101,7 @@
[conn {:keys [user-id id version data operations]}]
(let [sql "insert into project_page_snapshots (user_id, page_id, version, data, operations)
values ($1, $2, $3, $4, $5)
returning id, version, operations"]
returning id, page_id, user_id, version, operations"]
(db/query-one conn [sql user-id id version data operations])))
;; --- Mutation: Rename Page
@ -169,7 +170,14 @@
(-> (update-page-data conn page)
(p/then (fn [_] (insert-page-snapshot conn page)))
(p/then (fn [s] (retrieve-lagged-operations conn s params))))))
(p/then (fn [s]
(let [topic (str "internal.uxbox.file." (:file-id page))]
(p/do! (ve/publish! uxbox.core/system topic {:type :page-snapshot
:user-id (:user-id s)
:page-id (:page-id s)
:version (:version s)
:operations ops})
(retrieve-lagged-operations conn s params))))))))
(su/defstr sql:lagged-snapshots
"select s.id, s.operations
@ -182,7 +190,7 @@
(let [sql sql:lagged-snapshots]
(-> (db/query conn [sql (:id params) (:version params) #_(:id snapshot)])
(p/then (fn [rows]
{:id (:id params)
{:page-id (:id params)
:version (:version snapshot)
:operations (into [] (comp (map decode-row)
(map :operations)