mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 23:31:21 -05:00
Merge pull request #3189 from penpot/hiru-sync-notifications
✨ Notify library updates when really needed
This commit is contained in:
commit
44a3f651c2
32 changed files with 373 additions and 195 deletions
|
@ -253,7 +253,6 @@
|
|||
:code :feature-mismatch
|
||||
:feature "components/v2"
|
||||
:hint "file has 'components/v2' feature enabled but frontend didn't specifies it"))
|
||||
|
||||
(cond-> file
|
||||
(and (contains? client-features "components/v2")
|
||||
(not (contains? features "components/v2")))
|
||||
|
@ -263,7 +262,6 @@
|
|||
(not (contains? client-features "storage/pointer-map")))
|
||||
(process-pointers deref)))
|
||||
|
||||
|
||||
;; --- COMMAND QUERY: get-file (by id)
|
||||
|
||||
(defn get-file
|
||||
|
|
|
@ -78,8 +78,7 @@
|
|||
(defn- library-change?
|
||||
[{:keys [type] :as change}]
|
||||
(or (contains? library-change-types type)
|
||||
(and (contains? file-change-types type)
|
||||
(some? (:component-id change)))))
|
||||
(contains? file-change-types type)))
|
||||
|
||||
(def ^:private sql:get-file
|
||||
"SELECT f.*, p.team_id
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
(ns app.util.time
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.time :as common-time]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[fipp.ednize :as fez])
|
||||
|
@ -186,9 +188,7 @@
|
|||
:else
|
||||
(throw (UnsupportedOperationException. "unsupported type")))))
|
||||
|
||||
(defn now
|
||||
[]
|
||||
(Instant/now))
|
||||
(dm/export common-time/now)
|
||||
|
||||
(defn in-future
|
||||
[v]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"main": "index.js",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"luxon": "^3.1.1"
|
||||
"luxon": "^3.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-and-watch-test": "clojure -M:dev:shadow-cljs watch test",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.pages.changes-spec :as pcs]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.colors-list :as ctcl]
|
||||
|
@ -53,7 +54,7 @@
|
|||
(run! validate-shape!)))))
|
||||
|
||||
(defmulti process-change (fn [_ change] (:type change)))
|
||||
(defmulti process-operation (fn [_ op] (:type op)))
|
||||
(defmulti process-operation (fn [_ _ op] (:type op)))
|
||||
|
||||
(defn process-changes
|
||||
([data items]
|
||||
|
@ -91,14 +92,34 @@
|
|||
|
||||
(defmethod process-change :mod-obj
|
||||
[data {:keys [id page-id component-id operations]}]
|
||||
(let [update-fn (fn [objects]
|
||||
(let [objects (if page-id
|
||||
(-> data :pages-index (get page-id) :objects)
|
||||
(-> data :components (get component-id) :objects))
|
||||
|
||||
modified-component-ids (atom #{})
|
||||
|
||||
on-touched (fn [shape]
|
||||
;; When a shape is modified, if it belongs to a main component instance,
|
||||
;; the component needs to be marked as modified.
|
||||
(let [component-root (ctn/get-component-shape objects shape {:allow-main? true})]
|
||||
(when (ctk/main-instance? component-root)
|
||||
(swap! modified-component-ids conj (:component-id component-root)))))
|
||||
|
||||
update-fn (fn [objects]
|
||||
(if-let [obj (get objects id)]
|
||||
(let [result (reduce process-operation obj operations)]
|
||||
(let [result (reduce (partial process-operation on-touched) obj operations)]
|
||||
(assoc objects id result))
|
||||
objects))]
|
||||
(if page-id
|
||||
(d/update-in-when data [:pages-index page-id :objects] update-fn)
|
||||
(d/update-in-when data [:components component-id :objects] update-fn))))
|
||||
objects))
|
||||
|
||||
modify-components (fn [data]
|
||||
(reduce ctkl/set-component-modified
|
||||
data @modified-component-ids))]
|
||||
|
||||
(as-> data $
|
||||
(if page-id
|
||||
(d/update-in-when $ [:pages-index page-id :objects] update-fn)
|
||||
(d/update-in-when $ [:components component-id :objects] update-fn))
|
||||
(modify-components $))))
|
||||
|
||||
(defmethod process-change :del-obj
|
||||
[data {:keys [page-id component-id id ignore-touched]}]
|
||||
|
@ -223,8 +244,6 @@
|
|||
(not= :frame (:type obj))
|
||||
(as-> $$ (reduce (partial assign-frame-id frame-id) $$ (:shapes obj))))))
|
||||
|
||||
|
||||
|
||||
(move-objects [objects]
|
||||
(let [valid? (every? (partial is-valid-move? objects) shapes)
|
||||
parent (get objects parent-id)
|
||||
|
@ -284,7 +303,7 @@
|
|||
|
||||
(defmethod process-change :mod-color
|
||||
[data {:keys [color]}]
|
||||
(d/assoc-in-when data [:colors (:id color)] color))
|
||||
(ctcl/set-color data color))
|
||||
|
||||
(defmethod process-change :del-color
|
||||
[data {:keys [id]}]
|
||||
|
@ -343,7 +362,7 @@
|
|||
|
||||
(defmethod process-change :mod-typography
|
||||
[data {:keys [typography]}]
|
||||
(d/update-in-when data [:typographies (:id typography)] merge typography))
|
||||
(ctyl/update-typography data (:id typography) merge typography))
|
||||
|
||||
(defmethod process-change :del-typography
|
||||
[data {:keys [id]}]
|
||||
|
@ -352,7 +371,7 @@
|
|||
;; === Operations
|
||||
|
||||
(defmethod process-operation :set
|
||||
[shape op]
|
||||
[on-touched shape op]
|
||||
(let [attr (:attr op)
|
||||
group (get component-sync-attrs attr)
|
||||
val (:val op)
|
||||
|
@ -367,7 +386,7 @@
|
|||
;; after the check added in data/workspace/modifiers/check-delta
|
||||
;; function. Better check it and test toroughly when activating
|
||||
;; components-v2 mode.
|
||||
shape-ref (:shape-ref shape)
|
||||
in-copy? (ctk/in-component-copy? shape)
|
||||
root-name? (and (= group :name-group)
|
||||
(:component-root? shape))
|
||||
|
||||
|
@ -379,17 +398,23 @@
|
|||
(gsh/close-attrs? attr val shape-val 1)
|
||||
(gsh/close-attrs? attr val shape-val))]
|
||||
|
||||
(when (and group (not ignore) (not equal?)
|
||||
(not root-name?)
|
||||
(not (and ignore-geometry is-geometry?)))
|
||||
;; Notify touched even if it's not copy, because it may be a main instance
|
||||
(on-touched shape))
|
||||
|
||||
(cond-> shape
|
||||
;; Depending on the origin of the attribute change, we need or not to
|
||||
;; set the "touched" flag for the group the attribute belongs to.
|
||||
;; In some cases we need to ignore touched only if the attribute is
|
||||
;; geometric (position, width or transformation).
|
||||
(and shape-ref group (not ignore) (not equal?)
|
||||
(and in-copy? group (not ignore) (not equal?)
|
||||
(not root-name?)
|
||||
(not (and ignore-geometry is-geometry?)))
|
||||
(->
|
||||
(update :touched cph/set-touched-group group)
|
||||
(dissoc :remote-synced?))
|
||||
(update :touched cph/set-touched-group group)
|
||||
(dissoc :remote-synced?))
|
||||
|
||||
(nil? val)
|
||||
(dissoc attr)
|
||||
|
@ -398,23 +423,23 @@
|
|||
(assoc attr val))))
|
||||
|
||||
(defmethod process-operation :set-touched
|
||||
[shape op]
|
||||
[_ shape op]
|
||||
(let [touched (:touched op)
|
||||
shape-ref (:shape-ref shape)]
|
||||
(if (or (nil? shape-ref) (nil? touched) (empty? touched))
|
||||
in-copy? (ctk/in-component-copy? shape)]
|
||||
(if (or (not in-copy?) (nil? touched) (empty? touched))
|
||||
(dissoc shape :touched)
|
||||
(assoc shape :touched touched))))
|
||||
|
||||
(defmethod process-operation :set-remote-synced
|
||||
[shape op]
|
||||
[_ shape op]
|
||||
(let [remote-synced? (:remote-synced? op)
|
||||
shape-ref (:shape-ref shape)]
|
||||
(if (or (nil? shape-ref) (not remote-synced?))
|
||||
in-copy? (ctk/in-component-copy? shape)]
|
||||
(if (or (not in-copy?) (not remote-synced?))
|
||||
(dissoc shape :remote-synced?)
|
||||
(assoc shape :remote-synced? true))))
|
||||
|
||||
(defmethod process-operation :default
|
||||
[_ op]
|
||||
[_ _ op]
|
||||
(ex/raise :type :not-implemented
|
||||
:code :operation-not-implemented
|
||||
:context {:type (:type op)}))
|
||||
|
|
|
@ -272,17 +272,6 @@
|
|||
[shape group]
|
||||
((or (:touched shape) #{}) group))
|
||||
|
||||
(defn get-root-shape
|
||||
"Get the root shape linked to a component for this shape, if any."
|
||||
[objects shape]
|
||||
|
||||
(cond
|
||||
(some? (:component-root? shape))
|
||||
shape
|
||||
|
||||
(some? (:shape-ref shape))
|
||||
(recur objects (get objects (:parent-id shape)))))
|
||||
|
||||
(defn make-container
|
||||
[page-or-component type]
|
||||
(assoc page-or-component :type type))
|
||||
|
|
|
@ -235,7 +235,7 @@
|
|||
|
||||
;; --- SPECS WITHOUT CONFORMER
|
||||
|
||||
(s/def ::inst inst?)
|
||||
(s/def ::inst inst?) ;; A clojure instant (date and time)
|
||||
|
||||
(s/def ::string
|
||||
(s/with-gen string?
|
||||
|
|
27
common/src/app/common/time.cljc
Normal file
27
common/src/app/common/time.cljc
Normal file
|
@ -0,0 +1,27 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
;; Here we put the time functions that are common between frontend and backend.
|
||||
;; In the future we may create an unified API for both.
|
||||
|
||||
(ns app.common.time
|
||||
#?(:cljs
|
||||
(:require
|
||||
["luxon" :as lxn])
|
||||
:clj
|
||||
(:import
|
||||
java.time.Instant)))
|
||||
|
||||
#?(:cljs
|
||||
(def DateTime lxn/DateTime))
|
||||
|
||||
#?(:cljs
|
||||
(def Duration lxn/Duration))
|
||||
|
||||
(defn now
|
||||
[]
|
||||
#?(:clj (Instant/now)
|
||||
:cljs (.local ^js DateTime)))
|
|
@ -58,6 +58,7 @@
|
|||
(s/def ::color-generic/gradient (s/nilable ::gradient))
|
||||
(s/def ::color-generic/ref-id uuid?)
|
||||
(s/def ::color-generic/ref-file uuid?)
|
||||
(s/def ::color-generic/modified-at ::us/inst)
|
||||
|
||||
(s/def ::shape-color
|
||||
(s/keys :req-un [:us/color
|
||||
|
@ -73,7 +74,8 @@
|
|||
::color-generic/value
|
||||
::color-generic/color
|
||||
::color-generic/opacity
|
||||
::color-generic/gradient]))
|
||||
::color-generic/gradient
|
||||
::color-generic/modified-at]))
|
||||
|
||||
(s/def ::recent-color
|
||||
(s/and
|
||||
|
|
|
@ -4,25 +4,51 @@
|
|||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.types.colors-list)
|
||||
(ns app.common.types.colors-list
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.time :as dt]
|
||||
[app.common.types.color :as ctc]))
|
||||
|
||||
(defn colors-seq
|
||||
[file-data]
|
||||
(vals (:colors file-data)))
|
||||
|
||||
(defn- touch
|
||||
[color]
|
||||
(assoc color :modified-at (dt/now)))
|
||||
|
||||
(defn add-color
|
||||
[file-data color]
|
||||
(update file-data :colors assoc (:id color) color))
|
||||
(update file-data :colors assoc (:id color) (touch color)))
|
||||
|
||||
(defn get-color
|
||||
[file-data color-id]
|
||||
(get-in file-data [:colors color-id]))
|
||||
|
||||
(defn get-ref-color
|
||||
[library-data color]
|
||||
(when (= (:ref-file color) (:id library-data))
|
||||
(get-color library-data (:ref-id color))))
|
||||
|
||||
(defn set-color
|
||||
[file-data color]
|
||||
(d/assoc-in-when file-data [:colors (:id color)] (touch color)))
|
||||
|
||||
(defn update-color
|
||||
[file-data color-id f]
|
||||
(update-in file-data [:colors color-id] f))
|
||||
[file-data color-id f & args]
|
||||
(d/update-in-when file-data [:colors color-id] #(-> (apply f % args)
|
||||
(touch))))
|
||||
|
||||
(defn delete-color
|
||||
[file-data color-id]
|
||||
(update file-data :colors dissoc color-id))
|
||||
|
||||
(defn used-colors-changed-since
|
||||
"Find all usages of any color in the library by the given shape, of colors
|
||||
that have ben modified after the date."
|
||||
[shape library since-date]
|
||||
(->> (ctc/get-all-colors shape)
|
||||
(keep #(get-ref-color (:data library) %))
|
||||
(remove #(< (:modified-at %) since-date)) ;; Note that :modified-at may be nil
|
||||
(map #(vector (:id shape) (:id %) :color))))
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
(ns app.common.types.component)
|
||||
|
||||
(defn instance-root?
|
||||
"Check if this shape is the head of a top instance."
|
||||
[shape]
|
||||
(some? (:component-root? shape)))
|
||||
|
||||
(defn instance-head?
|
||||
"Check if this shape is the head of a top instance or a subinstance."
|
||||
[shape]
|
||||
(some? (:component-id shape)))
|
||||
|
||||
|
@ -46,12 +52,12 @@
|
|||
(and (some? (:component-id shape))
|
||||
(= (:component-file shape) library-id)))
|
||||
|
||||
(defn in-component-instance?
|
||||
(defn in-component-copy?
|
||||
"Check if the shape is inside a component non-main instance."
|
||||
[shape]
|
||||
(some? (:shape-ref shape)))
|
||||
|
||||
(defn in-component-instance-not-root?
|
||||
(defn in-component-copy-not-root?
|
||||
"Check if the shape is inside a component non-main instance and
|
||||
is not the root shape."
|
||||
[shape]
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.features :as feat]))
|
||||
[app.common.files.features :as feat]
|
||||
[app.common.time :as dt]
|
||||
[app.common.types.component :as ctk]))
|
||||
|
||||
(defn components
|
||||
[file-data]
|
||||
|
@ -23,6 +25,10 @@
|
|||
[file-data]
|
||||
(filter :deleted (vals (:components file-data))))
|
||||
|
||||
(defn- touch
|
||||
[component]
|
||||
(assoc component :modified-at (dt/now)))
|
||||
|
||||
(defn add-component
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page shapes]}]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])
|
||||
|
@ -30,9 +36,9 @@
|
|||
(cond-> file-data
|
||||
:always
|
||||
(assoc-in [:components id]
|
||||
{:id id
|
||||
:name name
|
||||
:path path})
|
||||
(touch {:id id
|
||||
:name name
|
||||
:path path}))
|
||||
|
||||
(not components-v2)
|
||||
(assoc-in [:components id :objects]
|
||||
|
@ -47,24 +53,27 @@
|
|||
(defn mod-component
|
||||
[file-data {:keys [id name path objects annotation]}]
|
||||
(let [wrap-objects-fn feat/*wrap-with-objects-map-fn*]
|
||||
(update-in file-data [:components id]
|
||||
(fn [component]
|
||||
(let [objects (some-> objects wrap-objects-fn)]
|
||||
(cond-> component
|
||||
(some? name)
|
||||
(assoc :name name)
|
||||
(d/update-in-when file-data [:components id]
|
||||
(fn [component]
|
||||
(let [objects (some-> objects wrap-objects-fn)]
|
||||
(cond-> component
|
||||
(some? name)
|
||||
(assoc :name name)
|
||||
|
||||
(some? path)
|
||||
(assoc :path path)
|
||||
(some? path)
|
||||
(assoc :path path)
|
||||
|
||||
(some? objects)
|
||||
(assoc :objects objects)
|
||||
(some? objects)
|
||||
(assoc :objects objects)
|
||||
|
||||
(some? annotation)
|
||||
(assoc :annotation annotation)
|
||||
(some? annotation)
|
||||
(assoc :annotation annotation)
|
||||
|
||||
(nil? annotation)
|
||||
(dissoc :annotation)))))))
|
||||
(nil? annotation)
|
||||
(dissoc :annotation)
|
||||
|
||||
:always
|
||||
(touch)))))))
|
||||
|
||||
(defn get-component
|
||||
([file-data component-id]
|
||||
|
@ -83,8 +92,13 @@
|
|||
component)))
|
||||
|
||||
(defn update-component
|
||||
[file-data component-id f]
|
||||
(update-in file-data [:components component-id] f))
|
||||
[file-data component-id f & args]
|
||||
(d/update-in-when file-data [:components component-id] #(-> (apply f % args)
|
||||
(touch))))
|
||||
|
||||
(defn set-component-modified
|
||||
[file-data component-id]
|
||||
(update-component file-data component-id identity))
|
||||
|
||||
(defn delete-component
|
||||
[file-data component-id]
|
||||
|
@ -92,8 +106,19 @@
|
|||
|
||||
(defn mark-component-deleted
|
||||
[file-data component-id]
|
||||
(assoc-in file-data [:components component-id :deleted] true))
|
||||
(d/update-in-when file-data [:components component-id] assoc :deleted true))
|
||||
|
||||
(defn mark-component-undeleted
|
||||
[file-data component-id]
|
||||
(d/dissoc-in file-data [:components component-id :deleted]))
|
||||
|
||||
(defn used-components-changed-since
|
||||
"Check if the shape is an instance of any component in the library, and
|
||||
the component has been modified after the date."
|
||||
[shape library since-date]
|
||||
(if (ctk/uses-library-components? shape (:id library))
|
||||
(let [component (get-component (:data library) (:component-id shape))]
|
||||
(if (< (:modified-at component) since-date) ;; Note that :modified-at may be nil
|
||||
[]
|
||||
[[(:id shape) (:component-id shape) :component]]))
|
||||
[]))
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.common :as common]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
|
@ -20,10 +21,11 @@
|
|||
(s/def ::id uuid?)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::path (s/nilable ::us/string))
|
||||
(s/def ::modified-at ::us/inst)
|
||||
|
||||
(s/def ::container
|
||||
(s/keys :req-un [::id ::name]
|
||||
:opt-un [::type ::path ::ctst/objects]))
|
||||
:opt-un [::type ::path ::modified-at ::ctst/objects]))
|
||||
|
||||
(defn make-container
|
||||
[page-or-component type]
|
||||
|
@ -70,14 +72,20 @@
|
|||
|
||||
(defn get-component-shape
|
||||
"Get the parent shape linked to a component for this shape, if any"
|
||||
[objects shape]
|
||||
(if-not (:shape-ref shape)
|
||||
([objects shape] (get-component-shape objects shape nil))
|
||||
([objects shape {:keys [allow-main?] :or {allow-main? false} :as options}]
|
||||
(cond
|
||||
(nil? shape)
|
||||
nil
|
||||
(if (:component-id shape)
|
||||
shape
|
||||
(if-let [parent-id (:parent-id shape)]
|
||||
(get-component-shape objects (get objects parent-id))
|
||||
nil))))
|
||||
|
||||
(and (not (ctk/in-component-copy? shape)) (not allow-main?))
|
||||
nil
|
||||
|
||||
(ctk/instance-root? shape)
|
||||
shape
|
||||
|
||||
:else
|
||||
(get-component-shape objects (get objects (:parent-id shape)) options))))
|
||||
|
||||
(defn make-component-shape
|
||||
"Clone the shape and all children. Generate new ids and detach
|
||||
|
|
|
@ -281,6 +281,22 @@
|
|||
|
||||
(some used-in-container? (containers-seq file-data))))
|
||||
|
||||
(defn used-assets-changed-since
|
||||
"Get a lazy sequence of all assets in the library that are in use by the file and have
|
||||
been modified after the given date."
|
||||
[file-data library since-date]
|
||||
(letfn [(used-assets-shape [shape]
|
||||
(concat
|
||||
(ctkl/used-components-changed-since shape library since-date)
|
||||
(ctcl/used-colors-changed-since shape library since-date)
|
||||
(ctyl/used-typographies-changed-since shape library since-date)))
|
||||
|
||||
(used-assets-container [container]
|
||||
(->> (mapcat used-assets-shape (ctn/shapes-seq container))
|
||||
(map #(cons (:id container) %))))]
|
||||
|
||||
(mapcat used-assets-container (containers-seq file-data))))
|
||||
|
||||
(defn get-or-add-library-page
|
||||
"If exists a page named 'Library backup', get the id and calculate the position to start
|
||||
adding new components. If not, create it and start at (0, 0)."
|
||||
|
@ -370,7 +386,7 @@
|
|||
root-to-board
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
(and (ctk/instance-root? shape)
|
||||
(and (ctk/instance-head? shape)
|
||||
(not= (:type shape) :frame))
|
||||
(assoc :type :frame
|
||||
:fills []
|
||||
|
@ -548,75 +564,81 @@
|
|||
|
||||
(defn dump-tree
|
||||
([file-data page-id libraries]
|
||||
(dump-tree file-data page-id libraries false false))
|
||||
(dump-tree file-data page-id libraries false false false))
|
||||
|
||||
([file-data page-id libraries show-ids]
|
||||
(dump-tree file-data page-id libraries show-ids false))
|
||||
(dump-tree file-data page-id libraries show-ids false false))
|
||||
|
||||
([file-data page-id libraries show-ids show-touched]
|
||||
(dump-tree file-data page-id libraries show-ids show-touched false))
|
||||
|
||||
([file-data page-id libraries show-ids show-touched show-modified]
|
||||
(let [page (ctpl/get-page file-data page-id)
|
||||
objects (:objects page)
|
||||
components (ctkl/components file-data)
|
||||
root (d/seek #(nil? (:parent-id %)) (vals objects))]
|
||||
|
||||
(letfn [(show-shape [shape-id level objects]
|
||||
(let [shape (get objects shape-id)]
|
||||
(println (str/pad (str (str/repeat " " level)
|
||||
(when (:main-instance? shape) "{")
|
||||
(:name shape)
|
||||
(when (:main-instance? shape) "}")
|
||||
(when (seq (:touched shape)) "*")
|
||||
(when show-ids (str/format " <%s>" (:id shape))))
|
||||
{:length 20
|
||||
:type :right})
|
||||
(show-component-info shape objects))
|
||||
(when show-touched
|
||||
(when (seq (:touched shape))
|
||||
(println (str (str/repeat " " level)
|
||||
" "
|
||||
(str (:touched shape)))))
|
||||
(when (:remote-synced? shape)
|
||||
(println (str (str/repeat " " level)
|
||||
" (remote-synced)"))))
|
||||
(when (:shapes shape)
|
||||
(dorun (for [shape-id (:shapes shape)]
|
||||
(show-shape shape-id (inc level) objects))))))
|
||||
(let [shape (get objects shape-id)]
|
||||
(println (str/pad (str (str/repeat " " level)
|
||||
(when (:main-instance? shape) "{")
|
||||
(:name shape)
|
||||
(when (:main-instance? shape) "}")
|
||||
(when (seq (:touched shape)) "*")
|
||||
(when show-ids (str/format " <%s>" (:id shape))))
|
||||
{:length 20
|
||||
:type :right})
|
||||
(show-component-info shape objects))
|
||||
(when show-touched
|
||||
(when (seq (:touched shape))
|
||||
(println (str (str/repeat " " level)
|
||||
" "
|
||||
(str (:touched shape)))))
|
||||
(when (:remote-synced? shape)
|
||||
(println (str (str/repeat " " level)
|
||||
" (remote-synced)"))))
|
||||
(when (:shapes shape)
|
||||
(dorun (for [shape-id (:shapes shape)]
|
||||
(show-shape shape-id (inc level) objects))))))
|
||||
|
||||
(show-component-info [shape objects]
|
||||
(if (nil? (:shape-ref shape))
|
||||
(if (:component-root? shape) " #" "")
|
||||
(let [root-shape (ctn/get-component-shape objects shape)
|
||||
component-id (when root-shape (:component-id root-shape))
|
||||
component-file-id (when root-shape (:component-file root-shape))
|
||||
component-file (when component-file-id (get libraries component-file-id nil))
|
||||
component (when component-id
|
||||
(if component-file
|
||||
(ctkl/get-component (:data component-file) component-id)
|
||||
(get components component-id)))
|
||||
component-shape (when component
|
||||
(if component-file
|
||||
(get-ref-shape (:data component-file) component shape)
|
||||
(get-ref-shape file-data component shape)))]
|
||||
(if (nil? (:shape-ref shape))
|
||||
(if (:component-root? shape) " #" "")
|
||||
(let [root-shape (ctn/get-component-shape objects shape)
|
||||
component-id (when root-shape (:component-id root-shape))
|
||||
component-file-id (when root-shape (:component-file root-shape))
|
||||
component-file (when component-file-id (get libraries component-file-id nil))
|
||||
component (when component-id
|
||||
(if component-file
|
||||
(ctkl/get-component (:data component-file) component-id)
|
||||
(get components component-id)))
|
||||
component-shape (when component
|
||||
(if component-file
|
||||
(get-ref-shape (:data component-file) component shape)
|
||||
(get-ref-shape file-data component shape)))]
|
||||
|
||||
(str/format " %s--> %s%s%s"
|
||||
(cond (:component-root? shape) "#"
|
||||
(:component-id shape) "@"
|
||||
:else "-")
|
||||
(when component-file (str/format "<%s> " (:name component-file)))
|
||||
(or (:name component-shape) "?")
|
||||
(if (or (:component-root? shape)
|
||||
(nil? (:component-id shape))
|
||||
true)
|
||||
""
|
||||
(let [component-id (:component-id shape)
|
||||
component-file-id (:component-file shape)
|
||||
component-file (when component-file-id (get libraries component-file-id nil))
|
||||
component (if component-file
|
||||
(ctkl/get-component (:data component-file) component-id)
|
||||
(get components component-id))]
|
||||
(str/format " (%s%s)"
|
||||
(when component-file (str/format "<%s> " (:name component-file)))
|
||||
(:name component))))))))
|
||||
(str/format " %s--> %s%s%s"
|
||||
(cond (:component-root? shape) "#"
|
||||
(:component-id shape) "@"
|
||||
:else "-")
|
||||
|
||||
(when component-file (str/format "<%s> " (:name component-file)))
|
||||
|
||||
(or (:name component-shape) "?")
|
||||
|
||||
(if (or (:component-root? shape)
|
||||
(nil? (:component-id shape))
|
||||
true)
|
||||
""
|
||||
(let [component-id (:component-id shape)
|
||||
component-file-id (:component-file shape)
|
||||
component-file (when component-file-id (get libraries component-file-id nil))
|
||||
component (if component-file
|
||||
(ctkl/get-component (:data component-file) component-id)
|
||||
(get components component-id))]
|
||||
(str/format " (%s%s)"
|
||||
(when component-file (str/format "<%s> " (:name component-file)))
|
||||
(:name component))))))))
|
||||
|
||||
(show-component-instance [component]
|
||||
(let [page (get-component-page file-data component)
|
||||
|
@ -633,7 +655,10 @@
|
|||
(dorun (for [component (vals components)]
|
||||
(do
|
||||
(println)
|
||||
(println (str/format "[%s]" (:name component)))
|
||||
(println (str/format "[%s]%s%s"
|
||||
(:name component)
|
||||
(when show-ids (str " " (:id component)))
|
||||
(when show-modified (str " " (:modified-at component)))))
|
||||
(when (:objects component)
|
||||
(show-shape (:id component) 0 (:objects component)))
|
||||
(when (:main-instance-page component)
|
||||
|
|
|
@ -118,8 +118,8 @@
|
|||
(filter cph/frame-shape?))]
|
||||
(->> (keys objects)
|
||||
(into [] xform))))
|
||||
(remove #(or (and skip-components? (ctk/instance-root? %))
|
||||
(and skip-copies? (and (ctk/instance-root? %) (not (ctk/main-instance? %)))))))))
|
||||
(remove #(or (and skip-components? (ctk/instance-head? %))
|
||||
(and skip-copies? (and (ctk/instance-head? %) (not (ctk/main-instance? %)))))))))
|
||||
|
||||
(defn get-frames-ids
|
||||
"Retrieves all frame ids as vector"
|
||||
|
|
|
@ -4,25 +4,53 @@
|
|||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.types.typographies-list)
|
||||
(ns app.common.types.typographies-list
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.time :as dt]))
|
||||
|
||||
(defn typographies-seq
|
||||
[file-data]
|
||||
(vals (:typographies file-data)))
|
||||
|
||||
(defn- touch
|
||||
[typography]
|
||||
(assoc typography :modified-at (dt/now)))
|
||||
|
||||
(defn add-typography
|
||||
[file-data typography]
|
||||
(update file-data :typographies assoc (:id typography) typography))
|
||||
(update file-data :typographies assoc (:id typography) (touch typography)))
|
||||
|
||||
(defn get-typography
|
||||
[file-data typography-id]
|
||||
(get-in file-data [:typographies typography-id]))
|
||||
|
||||
(defn get-ref-typography
|
||||
[library-data typography]
|
||||
(when (= (:typography-ref-file typography) (:id library-data))
|
||||
(get-typography library-data (:typography-ref-id typography))))
|
||||
|
||||
(defn set-typography
|
||||
[file-data typography]
|
||||
(d/assoc-in-when file-data [:typographies (:id typography)] (touch typography)))
|
||||
|
||||
(defn update-typography
|
||||
[file-data typography-id f]
|
||||
(update-in file-data [:typographies typography-id] f))
|
||||
[file-data typography-id f & args]
|
||||
(d/update-in-when file-data [:typographies typography-id] #(-> (apply f % args)
|
||||
(touch))))
|
||||
|
||||
(defn delete-typography
|
||||
[file-data typography-id]
|
||||
(update file-data :typographies dissoc typography-id))
|
||||
|
||||
(defn used-typographies-changed-since
|
||||
"Find all usages of any typography in the library by the given shape, of
|
||||
typographies that have ben modified after the date.."
|
||||
[shape library since-date]
|
||||
(->> shape
|
||||
:content
|
||||
txt/node-seq
|
||||
(keep #(get-ref-typography (:data library) %))
|
||||
(remove #(< (:modified-at %) since-date)) ;; Note that :modified-at may be nil
|
||||
(map #(vector (:id shape) (:id %) :typography))))
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(ns app.common.types.typography
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.common.text :as txt]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
||||
|
@ -21,6 +22,7 @@
|
|||
(s/def ::line-height string?)
|
||||
(s/def ::letter-spacing string?)
|
||||
(s/def ::text-transform string?)
|
||||
(s/def ::modified-at ::us/inst)
|
||||
|
||||
(s/def ::typography
|
||||
(s/keys :req-un [::id
|
||||
|
@ -34,7 +36,8 @@
|
|||
::line-height
|
||||
::letter-spacing
|
||||
::text-transform]
|
||||
:opt-un [::path]))
|
||||
:opt-un [::path
|
||||
::modified-at]))
|
||||
|
||||
(defn uses-library-typographies?
|
||||
"Check if the shape uses any typography in the given library."
|
||||
|
|
|
@ -305,10 +305,10 @@ isexe@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
luxon@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.1.1.tgz#b492c645b2474fb86f3bd3283213846b99c32c1e"
|
||||
integrity sha512-Ah6DloGmvseB/pX1cAmjbFvyU/pKuwQMQqz7d0yvuDlVYLTs2WeDHQMpC8tGjm1da+BriHROW/OEIT/KfYg6xw==
|
||||
luxon@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48"
|
||||
integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
"highlight.js": "^11.7.0",
|
||||
"js-beautify": "^1.14.7",
|
||||
"jszip": "^3.10.1",
|
||||
"luxon": "^3.1.1",
|
||||
"luxon": "^3.3.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"opentype.js": "^1.3.4",
|
||||
"postcss-modules": "^6.0.0",
|
||||
|
|
|
@ -260,12 +260,11 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [ignore-until (-> state :workspace-file :ignore-sync-until)
|
||||
file-id (-> state :workspace-file :id)
|
||||
needs-update? (some #(and (> (:modified-at %) (:synced-at %))
|
||||
(or (not ignore-until)
|
||||
(> (:modified-at %) ignore-until)))
|
||||
libraries)]
|
||||
(let [file-data (:workspace-data state)
|
||||
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
||||
file-id (dm/get-in state [:workspace-file :id])
|
||||
needs-update? (seq (filter #(dwl/assets-need-sync % file-data ignore-until)
|
||||
libraries))]
|
||||
(when needs-update?
|
||||
(rx/of (dwl/notify-sync-file file-id)))))))
|
||||
|
||||
|
@ -1633,7 +1632,7 @@
|
|||
;; Check if the shape is an instance whose master is defined in a
|
||||
;; library that is not linked to the current file
|
||||
(foreign-instance? [shape paste-objects state]
|
||||
(let [root (cph/get-root-shape paste-objects shape)
|
||||
(let [root (ctn/get-component-shape paste-objects shape)
|
||||
root-file-id (:component-file root)]
|
||||
(and (some? root)
|
||||
(not= root-file-id (:current-file-id state))
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
|
||||
;; Shapes that are in a component, but are not root, must be detached,
|
||||
;; because they will be now children of a non instance group.
|
||||
shapes-to-detach (filter ctk/in-component-instance-not-root? shapes)
|
||||
shapes-to-detach (filter ctk/in-component-copy-not-root? shapes)
|
||||
|
||||
;; Look at the `get-empty-groups-after-group-creation`
|
||||
;; docstring to understand the real purpose of this code
|
||||
|
@ -124,7 +124,7 @@
|
|||
|
||||
;; Shapes that are in a component (including root) must be detached,
|
||||
;; because cannot be easyly synchronized back to the main component.
|
||||
shapes-to-detach (filter ctk/in-component-instance?
|
||||
shapes-to-detach (filter ctk/in-component-copy?
|
||||
(cph/get-children-with-self objects (:id group)))]
|
||||
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
|
|
|
@ -605,7 +605,7 @@
|
|||
container (cph/get-container local-file :page page-id)
|
||||
shape (ctn/get-shape container id)]
|
||||
|
||||
(when (ctk/in-component-instance? shape)
|
||||
(when (ctk/instance-head? shape)
|
||||
(let [libraries (wsh/get-libraries state)
|
||||
|
||||
changes
|
||||
|
@ -801,6 +801,8 @@
|
|||
(rx/of (dch/commit-changes (assoc changes :file-id file-id))))))))
|
||||
|
||||
(def ignore-sync
|
||||
"Mark the file as ignore syncs. All library changes before this moment will not
|
||||
ber notified to sync."
|
||||
(ptk/reify ::ignore-sync
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -812,13 +814,26 @@
|
|||
{:file-id (get-in state [:workspace-file :id])
|
||||
:date (dt/now)}))))
|
||||
|
||||
(defn assets-need-sync
|
||||
"Get a lazy sequence of all the assets of each type in the library that have
|
||||
been modified after the last sync of the library. The sync date may be
|
||||
overriden by providing a ignore-until parameter.
|
||||
|
||||
The sequence items are tuples of (page-id shape-id asset-id asset-type)."
|
||||
([library file-data] (assets-need-sync library file-data nil))
|
||||
([library file-data ignore-until]
|
||||
(let [sync-date (max (:synced-at library) (or ignore-until 0))]
|
||||
(when (> (:modified-at library) sync-date)
|
||||
(ctf/used-assets-changed-since file-data library sync-date)))))
|
||||
|
||||
(defn notify-sync-file
|
||||
[file-id]
|
||||
(us/assert ::us/uuid file-id)
|
||||
(ptk/reify ::notify-sync-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %))
|
||||
(let [file-data (:workspace-data state)
|
||||
libraries-need-sync (filter #(seq (assets-need-sync % file-data))
|
||||
(vals (get state :workspace-libraries)))
|
||||
do-update #(do (apply st/emit! (map (fn [library]
|
||||
(sync-file (:current-file-id state)
|
||||
|
@ -828,14 +843,15 @@
|
|||
do-dismiss #(do (st/emit! ignore-sync)
|
||||
(st/emit! dm/hide))]
|
||||
|
||||
(rx/of (dm/info-dialog
|
||||
(tr "workspace.updates.there-are-updates")
|
||||
:inline-actions
|
||||
[{:label (tr "workspace.updates.update")
|
||||
:callback do-update}
|
||||
{:label (tr "workspace.updates.dismiss")
|
||||
:callback do-dismiss}]
|
||||
:sync-dialog))))))
|
||||
(when (seq libraries-need-sync)
|
||||
(rx/of (dm/info-dialog
|
||||
(tr "workspace.updates.there-are-updates")
|
||||
:inline-actions
|
||||
[{:label (tr "workspace.updates.update")
|
||||
:callback do-update}
|
||||
{:label (tr "workspace.updates.dismiss")
|
||||
:callback do-dismiss}]
|
||||
:sync-dialog)))))))
|
||||
|
||||
(defn watch-component-changes
|
||||
"Watch the state for changes that affect to any main instance. If a change is detected will throw
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
(if (and (= (count shapes) 1)
|
||||
(or (and (= (:type (first shapes)) :group) (not components-v2))
|
||||
(= (:type (first shapes)) :frame))
|
||||
(not (ctk/instance-root? (first shapes))))
|
||||
(not (ctk/instance-head? (first shapes))))
|
||||
[(first shapes) (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects))]
|
||||
(let [root-name (if (= 1 (count shapes))
|
||||
|
@ -111,7 +111,7 @@
|
|||
page-id
|
||||
shapes
|
||||
root-name
|
||||
(not (ctk/instance-root? (first shapes))))
|
||||
(not (ctk/instance-head? (first shapes))))
|
||||
(prepare-create-board changes
|
||||
(uuid/next)
|
||||
(:parent-id (first shapes))
|
||||
|
@ -203,7 +203,7 @@
|
|||
(defn- generate-detach-recursive
|
||||
[changes container shape-id first]
|
||||
(let [shape (ctn/get-shape container shape-id)]
|
||||
(if (and (ctk/instance-root? shape) (not first))
|
||||
(if (and (ctk/instance-head? shape) (not first))
|
||||
;; Subinstances are not detached, but converted in top instances
|
||||
(pcb/update-shapes changes [(:id shape)] #(assoc % :component-root? true))
|
||||
;; Otherwise, detach the shape and all children
|
||||
|
@ -530,7 +530,7 @@
|
|||
[changes libraries container shape-id reset? components-v2]
|
||||
(log/debug :msg "Sync shape direct" :shape (str shape-id) :reset? reset?)
|
||||
(let [shape-inst (ctn/get-shape container shape-id)]
|
||||
(if (ctk/in-component-instance? shape-inst)
|
||||
(if (ctk/in-component-copy? shape-inst)
|
||||
(let [library (dm/get-in libraries [(:component-file shape-inst) :data])
|
||||
component (or (ctkl/get-component library (:component-id shape-inst))
|
||||
(and reset?
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[app.common.pages.common :as cpc]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.constants :refer [zoom-half-pixel-precision]]
|
||||
|
@ -54,7 +55,7 @@
|
|||
shape
|
||||
|
||||
(nil? root)
|
||||
(cph/get-root-shape objects shape)
|
||||
(ctn/get-component-shape objects shape {:allow-main? true})
|
||||
|
||||
:else root)
|
||||
|
||||
|
@ -64,7 +65,7 @@
|
|||
transformed-shape
|
||||
|
||||
(nil? transformed-root)
|
||||
(as-> (cph/get-root-shape objects transformed-shape) $
|
||||
(as-> (ctn/get-component-shape objects transformed-shape {:allow-main? true}) $
|
||||
(gsh/transform-shape (merge $ (get modif-tree (:id $)))))
|
||||
|
||||
:else transformed-root)
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
;; but hidden (to be able to recover them more easily).
|
||||
(let [shape (get objects shape-id)
|
||||
component-shape (ctn/get-component-shape objects shape)]
|
||||
(and (ctk/in-component-instance? shape)
|
||||
(and (ctk/in-component-copy? shape)
|
||||
(not= shape component-shape)
|
||||
(not (ctk/main-instance? component-shape)))))
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
(mf/defc element-icon
|
||||
[{:keys [shape main-instance?] :as props}]
|
||||
(if (ctk/instance-root? shape)
|
||||
(if (ctk/instance-head? shape)
|
||||
(if main-instance?
|
||||
i/component
|
||||
i/component-copy)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
(mf/defc element-icon-refactor
|
||||
[{:keys [shape main-instance?] :as props}]
|
||||
(if (ctk/instance-root? shape)
|
||||
(if (ctk/instance-head? shape)
|
||||
(if main-instance?
|
||||
i/component-refactor
|
||||
i/copy-refactor)
|
||||
|
|
|
@ -438,7 +438,7 @@
|
|||
|
||||
has-component? (some true? (map #(contains? % :component-id) shapes))
|
||||
is-component? (and single? (-> shapes first :component-id some?))
|
||||
is-non-root? (and single? (ctk/in-component-instance-not-root? (first shapes)))
|
||||
is-non-root? (and single? (ctk/in-component-copy-not-root? (first shapes)))
|
||||
|
||||
first-shape (first shapes)
|
||||
{:keys [shape-id component-id component-file main-instance?]} first-shape
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
#(as-> (get objects %) obj
|
||||
(and (cph/root-frame? obj)
|
||||
(d/not-empty? (:shapes obj))
|
||||
(not (ctk/instance-root? obj))
|
||||
(not (ctk/instance-head? obj))
|
||||
(not (ctk/main-instance? obj))))
|
||||
|
||||
;; Set with the elements to remove from the hover list
|
||||
|
|
|
@ -22,12 +22,13 @@
|
|||
["date-fns/locale/ru" :default dateFnsLocalesRu]
|
||||
["date-fns/locale/tr" :default dateFnsLocalesTr]
|
||||
["date-fns/locale/zh-CN" :default dateFnsLocalesZhCn]
|
||||
["luxon" :as lxn]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.time :as common-time]
|
||||
[app.util.object :as obj]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(def DateTime lxn/DateTime)
|
||||
(def Duration lxn/Duration)
|
||||
(dm/export common-time/DateTime)
|
||||
(dm/export common-time/Duration)
|
||||
|
||||
(defprotocol ITimeMath
|
||||
(plus [_ o])
|
||||
|
@ -89,9 +90,7 @@
|
|||
:rfc2822 (.fromRFC2822 ^js DateTime s #js {:zone zone :setZone force-zone})
|
||||
:http (.fromHTTP ^js DateTime s #js {:zone zone :setZone force-zone})))))
|
||||
|
||||
(defn now
|
||||
[]
|
||||
(.local ^js DateTime))
|
||||
(dm/export common-time/now)
|
||||
|
||||
(defn utc-now
|
||||
[]
|
||||
|
|
|
@ -295,18 +295,20 @@
|
|||
nil))
|
||||
|
||||
(defn dump-tree'
|
||||
([state] (dump-tree' state false false))
|
||||
([state show-ids] (dump-tree' state show-ids false))
|
||||
([state show-ids show-touched]
|
||||
([state] (dump-tree' state false false false))
|
||||
([state show-ids] (dump-tree' state show-ids false false))
|
||||
([state show-ids show-touched] (dump-tree' state show-ids show-touched false))
|
||||
([state show-ids show-touched show-modified]
|
||||
(let [page-id (get state :current-page-id)
|
||||
file-data (get state :workspace-data)
|
||||
libraries (get state :workspace-libraries)]
|
||||
(ctf/dump-tree file-data page-id libraries show-ids show-touched))))
|
||||
(ctf/dump-tree file-data page-id libraries show-ids show-touched show-modified))))
|
||||
|
||||
(defn ^:export dump-tree
|
||||
([] (dump-tree' @st/state))
|
||||
([show-ids] (dump-tree' @st/state show-ids))
|
||||
([show-ids show-touched] (dump-tree' @st/state show-ids show-touched)))
|
||||
([show-ids] (dump-tree' @st/state show-ids false false))
|
||||
([show-ids show-touched] (dump-tree' @st/state show-ids show-touched false))
|
||||
([show-ids show-touched show-modified] (dump-tree' @st/state show-ids show-touched show-modified)))
|
||||
|
||||
(when *assert*
|
||||
(defonce debug-subscription
|
||||
|
|
|
@ -3342,10 +3342,10 @@ lru-queue@^0.1.0:
|
|||
dependencies:
|
||||
es5-ext "~0.10.2"
|
||||
|
||||
luxon@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.1.1.tgz#b492c645b2474fb86f3bd3283213846b99c32c1e"
|
||||
integrity sha512-Ah6DloGmvseB/pX1cAmjbFvyU/pKuwQMQqz7d0yvuDlVYLTs2WeDHQMpC8tGjm1da+BriHROW/OEIT/KfYg6xw==
|
||||
luxon@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48"
|
||||
integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==
|
||||
|
||||
make-iterator@^1.0.0:
|
||||
version "1.0.1"
|
||||
|
|
Loading…
Add table
Reference in a new issue