♻️ Simplifies RPC pattern for token sets (#6045)

* ♻️ Add set removal methods to tokens library

* ♻️ Add `set-token-set` method to changes

* ♻️ Add `set-token-set` to changes builder

* ♻️ Use new method in the token set creation

* ♻️ Use `set-token-set` in frontend events

* ♻️ Remove unused binding

* ♻️ Add tests

* ♻️ Remove old API methods

* ♻️ Remove unused parts of schema and multimethods

* ♻️ Make `:tokens` key optional in schema

* ♻️ Add `with-library-data` calls before `set-token-set`

* ♻️ Fix DOM properties error
This commit is contained in:
Andrei Fëdorov 2025-03-11 16:03:52 +01:00 committed by GitHub
parent f35723e772
commit b52e8bc87c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 165 additions and 90 deletions

View file

@ -394,11 +394,6 @@
[:group :string] [:group :string]
[:name :string]]] [:name :string]]]
[:add-token-set
[:map {:title "AddTokenSetChange"}
[:type [:= :add-token-set]]
[:token-set ::ctot/token-set]]]
[:add-token-sets [:add-token-sets
[:map {:title "AddTokenSetsChange"} [:map {:title "AddTokenSetsChange"}
[:type [:= :add-token-sets]] [:type [:= :add-token-sets]]
@ -410,11 +405,6 @@
[:set-group-path [:vector :string]] [:set-group-path [:vector :string]]
[:set-group-fname :string]]] [:set-group-fname :string]]]
[:mod-token-set
[:map {:title "ModTokenSetChange"}
[:type [:= :mod-token-set]]
[:name :string]
[:token-set ::ctot/token-set]]]
[:move-token-set-before [:move-token-set-before
[:map {:title "MoveTokenSetBefore"} [:map {:title "MoveTokenSetBefore"}
@ -432,21 +422,18 @@
[:before-path [:maybe [:vector :string]]] [:before-path [:maybe [:vector :string]]]
[:before-group? [:maybe :boolean]]]] [:before-group? [:maybe :boolean]]]]
[:del-token-set
[:map {:title "DelTokenSetChange"}
[:type [:= :del-token-set]]
[:name :string]]]
[:del-token-set-path
[:map {:title "DelTokenSetPathChange"}
[:type [:= :del-token-set-path]]
[:path :string]]]
[:set-tokens-lib [:set-tokens-lib
[:map {:title "SetTokensLib"} [:map {:title "SetTokensLib"}
[:type [:= :set-tokens-lib]] [:type [:= :set-tokens-lib]]
[:tokens-lib :any]]] [:tokens-lib :any]]]
[:set-token-set
[:map {:title "SetTokenSetChange"}
[:type [:= :set-token-set]]
[:set-name :string]
[:group? :boolean]
[:token-set [:maybe ::ctot/token-set]]]]
[:set-token [:set-token
[:map {:title "SetTokenChange"} [:map {:title "SetTokenChange"}
[:type [:= :set-token]] [:type [:= :set-token]]
@ -1033,6 +1020,24 @@
(ctob/update-token-in-set lib' set-name token-name (fn [prev-token] (ctob/update-token-in-set lib' set-name token-name (fn [prev-token]
(ctob/make-token (merge prev-token token))))))))) (ctob/make-token (merge prev-token token)))))))))
(defmethod process-change :set-token-set
[data {:keys [set-name group? token-set]}]
(update data :tokens-lib
(fn [lib]
(let [lib' (ctob/ensure-tokens-lib lib)]
(cond
(not token-set)
(if group?
(ctob/delete-set-group lib' set-name)
(ctob/delete-set lib' set-name))
(not (ctob/get-set lib' set-name))
(ctob/add-set lib' (ctob/make-token-set token-set))
:else
(ctob/update-set lib' set-name (fn [prev-token-set]
(ctob/make-token-set (merge prev-token-set token-set)))))))))
(defmethod process-change :update-active-token-themes (defmethod process-change :update-active-token-themes
[data {:keys [theme-ids]}] [data {:keys [theme-ids]}]
(update data :tokens-lib #(-> % (ctob/ensure-tokens-lib) (update data :tokens-lib #(-> % (ctob/ensure-tokens-lib)
@ -1059,12 +1064,6 @@
(ctob/ensure-tokens-lib) (ctob/ensure-tokens-lib)
(ctob/delete-theme group name)))) (ctob/delete-theme group name))))
(defmethod process-change :add-token-set
[data {:keys [token-set]}]
(update data :tokens-lib #(-> %
(ctob/ensure-tokens-lib)
(ctob/add-set (ctob/make-token-set token-set)))))
(defmethod process-change :add-token-sets (defmethod process-change :add-token-sets
[data {:keys [token-sets]}] [data {:keys [token-sets]}]
(update data :tokens-lib #(-> % (update data :tokens-lib #(-> %
@ -1078,14 +1077,6 @@
(ctob/ensure-tokens-lib) (ctob/ensure-tokens-lib)
(ctob/rename-set-group set-group-path set-group-fname))))) (ctob/rename-set-group set-group-path set-group-fname)))))
(defmethod process-change :mod-token-set
[data {:keys [name token-set]}]
(update data :tokens-lib (fn [lib]
(-> lib
(ctob/ensure-tokens-lib)
(ctob/update-set name (fn [prev-set]
(merge prev-set (dissoc token-set :tokens))))))))
(defmethod process-change :move-token-set-before (defmethod process-change :move-token-set-before
[data {:keys [from-path to-path before-path before-group?] :as changes}] [data {:keys [from-path to-path before-path before-group?] :as changes}]
(update data :tokens-lib #(-> % (update data :tokens-lib #(-> %
@ -1098,18 +1089,6 @@
(ctob/ensure-tokens-lib) (ctob/ensure-tokens-lib)
(ctob/move-set-group from-path to-path before-path before-group?)))) (ctob/move-set-group from-path to-path before-path before-group?))))
(defmethod process-change :del-token-set
[data {:keys [name]}]
(update data :tokens-lib #(-> %
(ctob/ensure-tokens-lib)
(ctob/delete-set-path name))))
(defmethod process-change :del-token-set-path
[data {:keys [path]}]
(update data :tokens-lib #(-> %
(ctob/ensure-tokens-lib)
(ctob/delete-set-path path))))
;; === Operations ;; === Operations
(def ^:private decode-shape (def ^:private decode-shape

View file

@ -803,13 +803,6 @@
(update :undo-changes conj {:type :add-token-theme :token-theme prev-token-theme}) (update :undo-changes conj {:type :add-token-theme :token-theme prev-token-theme})
(apply-changes-local)))) (apply-changes-local))))
(defn add-token-set
[changes token-set]
(-> changes
(update :redo-changes conj {:type :add-token-set :token-set token-set})
(update :undo-changes conj {:type :del-token-set :name (:name token-set)})
(apply-changes-local)))
(defn rename-token-set-group (defn rename-token-set-group
[changes set-group-path set-group-fname] [changes set-group-path set-group-fname]
(let [undo-path (ctob/replace-last-path-name set-group-path set-group-fname) (let [undo-path (ctob/replace-last-path-name set-group-path set-group-fname)
@ -819,29 +812,6 @@
(update :undo-changes conj {:type :rename-token-set-group :set-group-path undo-path :set-group-fname undo-fname}) (update :undo-changes conj {:type :rename-token-set-group :set-group-path undo-path :set-group-fname undo-fname})
(apply-changes-local)))) (apply-changes-local))))
(defn update-token-set
[changes token-set prev-token-set]
(-> changes
(update :redo-changes conj {:type :mod-token-set :name (:name prev-token-set) :token-set token-set})
(update :undo-changes conj {:type :mod-token-set :name (:name token-set) :token-set (or prev-token-set token-set)})
(apply-changes-local)))
(defn delete-token-set-path
[changes group? path]
(assert-library! changes)
(let [;; TODO Move leaking prefix to library
prefixed-path (if group?
(ctob/set-group-path->set-group-prefixed-path path)
(ctob/set-full-path->set-prefixed-full-path path))
prefixed-path-str (ctob/join-set-path prefixed-path)
library-data (::library-data (meta changes))
prev-token-sets (some-> (get library-data :tokens-lib)
(ctob/get-path-sets prefixed-path-str))]
(-> changes
(update :redo-changes conj {:type :del-token-set-path :path prefixed-path-str})
(update :undo-changes conj {:type :add-token-sets :token-sets prev-token-sets})
(apply-changes-local))))
(defn move-token-set-before (defn move-token-set-before
[changes {:keys [from-path to-path before-path before-group? prev-before-path prev-before-group?] :as opts}] [changes {:keys [from-path to-path before-path before-group? prev-before-path prev-before-group?] :as opts}]
(-> changes (-> changes
@ -908,6 +878,32 @@
:token nil})) :token nil}))
(apply-changes-local)))) (apply-changes-local))))
(defn set-token-set [changes set-name group? token-set]
(assert-library! changes)
(let [library-data (::library-data (meta changes))
prev-token-set (some-> (get library-data :tokens-lib)
(ctob/get-set set-name))]
(-> changes
(update :redo-changes conj {:type :set-token-set
:set-name set-name
:token-set token-set
:group? group?})
(update :undo-changes conj (if prev-token-set
{:type :set-token-set
:set-name (or
;; Undo of edit
(:name token-set)
;; Undo of delete
set-name)
:token-set prev-token-set
:group? group?}
;; Undo of create
{:type :set-token-set
:set-name set-name
:token-set nil
:group? group?}))
(apply-changes-local))))
(defn add-component (defn add-component
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page] ([changes id path name new-shapes updated-shapes main-instance-id main-instance-page]
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page nil nil nil)) (add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page nil nil nil))

View file

@ -25,4 +25,4 @@
[:name :string] [:name :string]
[:description {:optional true} [:maybe :string]] [:description {:optional true} [:maybe :string]]
[:modified-at {:optional true} ::sm/inst] [:modified-at {:optional true} ::sm/inst]
[:tokens :any]]) [:tokens {:optional true} :any]])

View file

@ -260,6 +260,9 @@
(-> (split-token-set-name name) (-> (split-token-set-name name)
(peek))) (peek)))
(defn split-token-set-path [token-set-path]
(split-path token-set-path set-separator))
(defn set-name->prefixed-full-path [name-str] (defn set-name->prefixed-full-path [name-str]
(-> (split-token-set-name name-str) (-> (split-token-set-name name-str)
(set-full-path->set-prefixed-full-path))) (set-full-path->set-prefixed-full-path)))
@ -435,6 +438,8 @@
(add-sets [_ token-set] "add a collection of sets to the library, at the end") (add-sets [_ token-set] "add a collection of sets to the library, at the end")
(update-set [_ set-name f] "modify a set in the library") (update-set [_ set-name f] "modify a set in the library")
(delete-set-path [_ set-path] "delete a set in the library") (delete-set-path [_ set-path] "delete a set in the library")
(delete-set [_ set-name] "delete a set at `set-name` in the library and disable the `set-name` in all themes")
(delete-set-group [_ set-group-name] "delete a set group at `set-group-name` in the library and disable its child sets in all themes")
(move-set [_ from-path to-path before-path before-group?] "Move token set at `from-path` to `to-path` and order it before `before-path` with `before-group?`.") (move-set [_ from-path to-path before-path before-group?] "Move token set at `from-path` to `to-path` and order it before `before-path` with `before-group?`.")
(move-set-group [_ from-path to-path before-path before-group?] "Move token set group at `from-path` to `to-path` and order it before `before-path` with `before-group?`.") (move-set-group [_ from-path to-path before-path before-group?] "Move token set group at `from-path` to `to-path` and order it before `before-path` with `before-group?`.")
(set-count [_] "get the total number if sets in the library") (set-count [_] "get the total number if sets in the library")
@ -902,6 +907,33 @@ Will return a value that matches this schema:
active-themes))) active-themes)))
this))) this)))
(delete-set [_ set-name]
(let [prefixed-path (set-name->prefixed-full-path set-name)]
(TokensLib. (d/dissoc-in sets prefixed-path)
(walk/postwalk
(fn [form]
(if (instance? TokenTheme form)
(disable-set form set-name)
form))
themes)
active-themes)))
(delete-set-group [this set-group-name]
(let [path (split-token-set-path set-group-name)
prefixed-path (map add-set-group-prefix path)
child-set-names (->> (get-sets-at-path this path)
(map :name)
(into #{}))]
(TokensLib. (d/dissoc-in sets prefixed-path)
(walk/postwalk
(fn [form]
(if (instance? TokenTheme form)
(disable-sets form child-set-names)
form))
themes)
active-themes)))
(delete-set-path [_ prefixed-set-name] (delete-set-path [_ prefixed-set-name]
(let [prefixed-set-path (split-token-set-name prefixed-set-name) (let [prefixed-set-path (split-token-set-name prefixed-set-name)
set-node (get-in sets prefixed-set-path) set-node (get-in sets prefixed-set-path)

View file

@ -132,6 +132,64 @@
(t/is (tht/token-data-eq? prev-token (ctob/get-token-in-set undo-lib set-name (:name prev-token)))) (t/is (tht/token-data-eq? prev-token (ctob/get-token-in-set undo-lib set-name (:name prev-token))))
(t/is (nil? (ctob/get-token-in-set undo-lib set-name (:name token))))))) (t/is (nil? (ctob/get-token-in-set undo-lib set-name (:name token)))))))
(t/deftest set-token-set-test
(t/testing "delete token set"
(let [set-name "foo"
file (setup-file #(ctob/add-set % (ctob/make-token-set :name set-name)))
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(pcb/set-token-set set-name false nil))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (not (ctob/set-path-exists? redo-lib [set-name])))
;; Undo
(t/is (ctob/set-path-exists? undo-lib [set-name]))))
(t/testing "add token set"
(let [set-name "foo"
token-set (ctob/make-token-set :name set-name)
file (setup-file identity)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(pcb/set-token-set set-name false token-set))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (not (ctob/set-path-exists? undo-lib [set-name])))
;; Undo
(t/is (ctob/set-path-exists? redo-lib [set-name]))))
(t/testing "update token set"
(let [set-name "foo"
token-name "bar"
token (ctob/make-token {:name token-name
:value "red"
:type :color})
file (setup-file #(-> (ctob/add-set % (ctob/make-token-set :name set-name))
(ctob/add-token-in-set set-name token)))
prev-token-set (-> file tht/get-tokens-lib :sets first)
new-set-name "foo1"
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(pcb/set-token-set set-name false (assoc prev-token-set
:name new-set-name)))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
;; Undo
(t/is (some? (ctob/get-token-in-set undo-lib set-name token-name)))
(t/is (nil? (ctob/get-token-in-set undo-lib new-set-name token-name)))
;; Redo
(t/is (nil? (ctob/get-token-in-set redo-lib set-name token-name)))
(t/is (some? (ctob/get-token-in-set redo-lib new-set-name token-name))))))
(t/deftest generate-toggle-token-set-group-test (t/deftest generate-toggle-token-set-group-test
(t/testing "toggling set group with no active sets inside will activate all child sets" (t/testing "toggling set group with no active sets inside will activate all child sets"
(let [file (setup-file #(-> % (let [file (setup-file #(-> %

View file

@ -127,11 +127,17 @@
(update state :workspace-tokens dissoc :token-set-new-path)) (update state :workspace-tokens dissoc :token-set-new-path))
ptk/WatchEvent ptk/WatchEvent
(watch [it _ _] (watch [it state _]
(let [token-set (update token-set :name #(if (empty? %) set-name (ctob/join-set-path [% set-name]))) (let [token-set' (-> token-set
(update :name #(if (empty? %)
set-name
(ctob/join-set-path [% set-name]))))
data (dsh/lookup-file-data state)
token-set-name (:name token-set')
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/add-token-set token-set))] (pcb/with-library-data data)
(rx/of (set-selected-token-set-name (:name token-set)) (pcb/set-token-set token-set-name false token-set'))]
(rx/of (set-selected-token-set-name token-set-name)
(dch/commit-changes changes)))))) (dch/commit-changes changes))))))
(defn rename-token-set-group [set-group-path set-group-fname] (defn rename-token-set-group [set-group-path set-group-fname]
@ -147,10 +153,10 @@
(ptk/reify ::update-token-set (ptk/reify ::update-token-set
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [prev-token-set (some-> (get-tokens-lib state) (let [data (dsh/lookup-file-data state)
(ctob/get-set set-name))
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/update-token-set token-set prev-token-set))] (pcb/with-library-data data)
(pcb/set-token-set set-name false token-set))]
(rx/of (rx/of
(set-selected-token-set-name (:name token-set)) (set-selected-token-set-name (:name token-set))
(dch/commit-changes changes)))))) (dch/commit-changes changes))))))
@ -196,7 +202,7 @@
(let [data (dsh/lookup-file-data state) (let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(pcb/delete-token-set-path group? path))] (pcb/set-token-set (ctob/join-set-path path) group? nil))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(wtu/update-workspace-tokens)))))) (wtu/update-workspace-tokens))))))
@ -245,9 +251,11 @@
[token] [token]
(ptk/reify ::create-token-and-set (ptk/reify ::create-token-and-set
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ state _]
(let [set-name "Global" (let [set-name "Global"
data (dsh/lookup-file-data state)
token-set token-set
(-> (ctob/make-token-set :name set-name) (-> (ctob/make-token-set :name set-name)
(ctob/add-token token)) (ctob/add-token token))
@ -259,7 +267,9 @@
(ctob/enable-set hidden-theme set-name) (ctob/enable-set hidden-theme set-name)
changes changes
(pcb/add-token-set (pcb/empty-changes) token-set) (-> (pcb/empty-changes)
(pcb/with-library-data data)
(pcb/set-token-set set-name false token-set))
changes changes
(-> changes (-> changes

View file

@ -492,7 +492,7 @@
:auto-focus true :auto-focus true
:label (tr "workspace.token.token-name") :label (tr "workspace.token.token-name")
:default-value @name-ref :default-value @name-ref
:maxlength 256 :max-length 256
:on-blur on-blur-name :on-blur on-blur-name
:on-change on-update-name}]) :on-change on-update-name}])
@ -515,7 +515,7 @@
{:id "token-value" {:id "token-value"
:placeholder (tr "workspace.token.enter-token-value") :placeholder (tr "workspace.token.enter-token-value")
:label (tr "workspace.token.token-value") :label (tr "workspace.token.token-value")
:maxlength 256 :max-length 256
:default-value @value-ref :default-value @value-ref
:ref value-input-ref :ref value-input-ref
:on-change on-update-value :on-change on-update-value
@ -534,7 +534,7 @@
{:id "token-description" {:id "token-description"
:placeholder (tr "workspace.token.enter-token-description") :placeholder (tr "workspace.token.enter-token-description")
:label (tr "workspace.token.token-description") :label (tr "workspace.token.token-description")
:maxlength 256 :max-length 256
:default-value @description-ref :default-value @description-ref
:on-blur on-update-description :on-blur on-update-description
:on-change on-update-description}] :on-change on-update-description}]