Make persistence separatted from undo/redo.

This commit is contained in:
Andrey Antukh 2020-03-13 11:09:14 +01:00 committed by Alonso Torres
parent 0f9d796460
commit 38f675d7f9

View file

@ -333,6 +333,7 @@
(assoc state :workspace-file file))))) (assoc state :workspace-file file)))))
(declare diff-and-commit-changes) (declare diff-and-commit-changes)
(declare initialize-persistence)
(defn initialize-page (defn initialize-page
[page-id] [page-id]
@ -354,13 +355,15 @@
(ptk/type? ::initialize-page %)) (ptk/type? ::initialize-page %))
stream)] stream)]
(rx/concat (rx/concat
(rx/of (initialize-persistence (get-in state [:workspace-page :id])))
(->> stream (->> stream
(rx/filter #(satisfies? IBatchedChange %)) (rx/filter #(satisfies? IBatchedChange %))
(rx/debounce 200) (rx/debounce 200)
(rx/map (constantly diff-and-commit-changes)) (rx/map (fn [_] (diff-and-commit-changes page-id)))
(rx/take-until stoper)) (rx/take-until stoper))
#_(rx/of diff-and-commit-changes)))))) #_(rx/of diff-and-commit-changes))))))
(defn finalize (defn finalize
[file-id page-id] [file-id page-id]
(us/verify ::us/uuid file-id) (us/verify ::us/uuid file-id)
@ -410,7 +413,8 @@
(reduce impl-diff [] (set/union (set (keys (:objects prev))) (reduce impl-diff [] (set/union (set (keys (:objects prev)))
(set (keys (:objects curr))))))) (set (keys (:objects curr)))))))
(def diff-and-commit-changes (defn diff-and-commit-changes
[page-id]
(ptk/reify ::diff-and-commit-changes (ptk/reify ::diff-and-commit-changes
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
@ -425,6 +429,51 @@
(when-not (empty? changes) (when-not (empty? changes)
(rx/of (commit-changes changes undo-changes))))))) (rx/of (commit-changes changes undo-changes)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Persistence
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare persist-changes)
(defn initialize-persistence
[page-id]
(ptk/reify ::initialize-persistence
ptk/UpdateEvent
(update [_ state]
(assoc state ::page-id page-id))
ptk/WatchEvent
(watch [_ state stream]
(let [stoper (rx/filter #(or (ptk/type? ::finalize %)
(ptk/type? ::initialize-page %))
stream)
notifier (->> stream
(rx/filter (ptk/type? ::commit-changes))
(rx/debounce 1000)
(rx/merge stoper))]
(->> stream
(rx/filter (ptk/type? ::commit-changes))
(rx/map deref)
(rx/buffer-until notifier)
(rx/map vec)
(rx/filter (complement empty?))
(rx/map #(persist-changes page-id %))
(rx/take-until (rx/delay 100 stoper)))))))
(defn persist-changes
[page-id changes]
(ptk/reify ::persist-changes
ptk/WatchEvent
(watch [_ state stream]
(prn "persist-changes" changes)
(let [session-id (:session-id state)
page (:workspace-page state)
params {:id (:id page)
:revn (:revn page)
:changes (vec (mapcat identity changes))}]
#_(->> (rp/mutation :update-page params)
(rx/map shapes-changes-commited))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Fetching & Uploading ;; Data Fetching & Uploading
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -1312,19 +1361,10 @@
(us/verify ::us/uuid id) (us/verify ::us/uuid id)
(us/verify string? name) (us/verify string? name)
(ptk/reify ::rename-shape (ptk/reify ::rename-shape
ptk/WatchEvent IBatchedChange
(watch [_ state stream] ptk/UpdateEvent
(let [shape (get-in state [:workspace-data :objects id]) (update [_ state]
session-id (:session-id state) (update-in state [:workspace-data :objects id] assoc :name name))))
change {:type :mod-shape
:id id
:session-id session-id
:operations [[:set :name name]]}
uchange {:type :mod-shape
:id id
:session-id session-id
:operations [[:set :name (:name shape)]]}]
(rx/of (commit-changes [change] [uchange]))))))
;; --- Shape Vertical Ordering ;; --- Shape Vertical Ordering
@ -1493,8 +1533,9 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(rx/of diff-and-commit-changes (let [pid (get-in state [:workspace-page :id])]
(rehash-shape-frame-relationship ids)))))) (rx/of (diff-and-commit-changes pid)
(rehash-shape-frame-relationship ids)))))))
(defn apply-displacement-in-bulk (defn apply-displacement-in-bulk
@ -1531,8 +1572,9 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(rx/of diff-and-commit-changes (let [pid (get-in state [:workspace-page :id])]
(rehash-shape-frame-relationship ids)))))) (rx/of (diff-and-commit-changes pid)
(rehash-shape-frame-relationship ids)))))))
(defn apply-frame-displacement (defn apply-frame-displacement
@ -1587,6 +1629,9 @@
(us/verify ::cp/changes undo-changes) (us/verify ::cp/changes undo-changes)
(ptk/reify ::commit-changes (ptk/reify ::commit-changes
cljs.core/IDeref
(-deref [_] changes)
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [pid (get-in state [:workspace-page :id]) (let [pid (get-in state [:workspace-page :id])
@ -1598,9 +1643,11 @@
(watch [_ state stream] (watch [_ state stream]
(let [page (:workspace-page state) (let [page (:workspace-page state)
uidx (get-in state [:workspace-local :undo-index] ::not-found) uidx (get-in state [:workspace-local :undo-index] ::not-found)
session-id (:session-id state)
changes (into [] (map #(assoc % :session-id session-id)) changes)
params {:id (:id page) params {:id (:id page)
:revn (:revn page) :revn (:revn page)
:changes (vec changes)}] :changes changes}]
(rx/concat (rx/concat
(when (and save-undo? (not= uidx ::not-found)) (when (and save-undo? (not= uidx ::not-found))
@ -1609,29 +1656,8 @@
(when save-undo? (when save-undo?
(let [entry {:undo-changes undo-changes (let [entry {:undo-changes undo-changes
:redo-changes changes}] :redo-changes changes}]
(rx/of (append-undo entry)))) (rx/of (append-undo entry))))))))))
(->> (rp/mutation :update-page params)
(rx/map shapes-changes-commited))))))))
;; (defn- check-page-integrity
;; [data]
;; (let [items (d/concat (:shapes data)
;; (:frame data))]
;; (loop [id (first items)
;; ids (rest items)]
;; (let [content (get-in data [:objects id])]
;; (cond
;; (nil? id)
;; nil
;; (nil? content)
;; (ex/raise :type :validation
;; :code :shape-integrity
;; :context {:id id})
;;
;; :else
;; (recur (first ids) (rest ids)))))))
(s/def ::shapes-changes-commited (s/def ::shapes-changes-commited
(s/keys :req-un [::page-id ::revn ::cp/changes])) (s/keys :req-un [::page-id ::revn ::cp/changes]))
@ -1639,22 +1665,18 @@
(defn shapes-changes-commited (defn shapes-changes-commited
[{:keys [page-id revn changes] :as params}] [{:keys [page-id revn changes] :as params}]
(us/verify ::shapes-changes-commited params) (us/verify ::shapes-changes-commited params)
(ptk/reify ::shapes-changes-commited (ptk/reify ::changes-commited
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
;; (prn "shapes-changes-commited$update" (let [sid (:session-id state)
;; (get-in state [:workspace-page :id]) state (-> state
;; page-id)
(-> state
(assoc-in [:workspace-page :revn] revn) (assoc-in [:workspace-page :revn] revn)
(assoc-in [:pages page-id :revn] revn) (assoc-in [:pages page-id :revn] revn))]
(update-in [:pages-data page-id] cp/process-changes changes) (if (not (every? #(= sid (:session-id %)) changes))
(update :workspace-data cp/process-changes changes))) (-> state
(update :workspace-data cp/process-changes changes)
ptk/EffectEvent (update-in [:pages-data page-id] cp/process-changes changes))
(effect [_ state stream] state)))))
#_(when *assert*
(check-page-integrity (:workspace-data state))))))
;; --- Start shape "edition mode" ;; --- Start shape "edition mode"