Browse Source

Merge branch 'feat/db' into feat/capacitor-new

charlie 7 months ago
parent
commit
4d46099908
45 changed files with 290 additions and 2571 deletions
  1. 1 1
      clj-e2e/dev/user.clj
  2. 4 0
      clj-e2e/src/logseq/e2e/assert.clj
  3. 2 15
      clj-e2e/src/logseq/e2e/block.clj
  4. 26 13
      clj-e2e/src/logseq/e2e/util.clj
  5. 32 31
      clj-e2e/test/logseq/e2e/commands_test.clj
  6. 15 0
      clj-e2e/test/logseq/e2e/custom_report.clj
  7. 2 0
      deps/common/resources/templates/config.edn
  8. 1 1
      packages/tldraw/apps/tldraw-logseq/src/lib/shapes/HTMLShape.tsx
  9. 4 3
      packages/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx
  10. 2 2
      packages/tldraw/apps/tldraw-logseq/src/lib/shapes/TweetShape.tsx
  11. 0 10
      packages/tldraw/cljs-demo/.clj-kondo/config.edn
  12. 0 68
      packages/tldraw/cljs-demo/.clj-kondo/hooks/rum.clj
  13. 0 30
      packages/tldraw/cljs-demo/.gitignore
  14. 0 14
      packages/tldraw/cljs-demo/deps.edn
  15. 0 18
      packages/tldraw/cljs-demo/package.json
  16. 0 17
      packages/tldraw/cljs-demo/public/index.html
  17. 0 22
      packages/tldraw/cljs-demo/shadow-cljs.edn
  18. 0 0
      packages/tldraw/cljs-demo/src/js/.gitkeep
  19. 0 23
      packages/tldraw/cljs-demo/src/main/playground/index.cljs
  20. 0 97
      packages/tldraw/cljs-demo/src/main/playground/rum.cljs
  21. 0 68
      packages/tldraw/cljs-demo/src/main/playground/tldraw.cljs
  22. 0 701
      packages/tldraw/cljs-demo/yarn.lock
  23. 0 17
      packages/tldraw/demo/index.html
  24. 0 29
      packages/tldraw/demo/package.json
  25. 0 15
      packages/tldraw/demo/postcss.config.js
  26. 0 277
      packages/tldraw/demo/src/App.jsx
  27. 0 81
      packages/tldraw/demo/src/index.css
  28. 0 2
      packages/tldraw/demo/src/logseq-styles.css
  29. 0 11
      packages/tldraw/demo/src/main.jsx
  30. 0 64
      packages/tldraw/demo/vite.config.js
  31. 4 797
      packages/tldraw/yarn.lock
  32. 6 3
      src/main/frontend/common/file/core.cljs
  33. 8 7
      src/main/frontend/components/page.cljs
  34. 1 0
      src/main/frontend/components/property/value.cljs
  35. 3 1
      src/main/frontend/components/views.cljs
  36. 1 1
      src/main/frontend/db/async.cljs
  37. 4 2
      src/main/frontend/db/react.cljs
  38. 4 1
      src/main/frontend/handler/common/config_edn.cljs
  39. 0 12
      src/main/frontend/handler/events.cljs
  40. 14 0
      src/main/frontend/handler/file_based/events.cljs
  41. 56 0
      src/main/frontend/handler/file_based/page.cljs
  42. 10 45
      src/main/frontend/handler/page.cljs
  43. 82 65
      src/main/frontend/worker/db/migrate.cljs
  44. 7 5
      src/main/frontend/worker/db_worker.cljs
  45. 1 2
      src/main/frontend/worker/rtc/client.cljs

+ 1 - 1
clj-e2e/dev/user.clj

@@ -85,7 +85,7 @@
 
   (do
     (reset! config/*headless true)
-    (reset! config/*slow-mo 100)
+    (reset! config/*slow-mo 50)
     (dotimes [i 5]
       (run-multi-tabs-test)))
 

+ 4 - 0
clj-e2e/src/logseq/e2e/assert.clj

@@ -24,6 +24,10 @@
   (assert-is-visible "#search-button")
   true)
 
+(defn assert-have-count
+  [q count]
+  (-> (w/-query q) assert-that (.hasCount count)))
+
 (defn assert-graph-loaded?
   []
   ;; there's some blocks visible now

+ 2 - 15
clj-e2e/src/logseq/e2e/block.clj

@@ -5,19 +5,6 @@
             [logseq.e2e.util :as util]
             [wally.main :as w]))
 
-(defn- wait-for-new-empty-block-inserted
-  "When inserting a new block, if the operation is too fast,
-  the w/fill operation can begin before k/enter has finished creating the block,
-  leading to the save-block not updating the block contents."
-  [last-edit-block-id]
-  (loop [i 5]
-    (if (zero? i)
-      (throw (ex-info "wait-for-new-empty-block-inserted" {}))
-      (if (not= last-edit-block-id (.getAttribute (w/-query util/editor-q) "id"))
-        :done
-        (do (util/wait-timeout 50)
-            (recur (dec i)))))))
-
 (defn open-last-block
   []
   (util/double-esc)
@@ -31,12 +18,12 @@
 (defn new-block
   [title]
   (let [editor (util/get-editor)
-        last-edit-block-id (when editor (.getAttribute editor "id"))]
+        blocks-count (util/blocks-count)]
     (when-not editor (open-last-block))
     (assert/assert-editor-mode)
     (k/enter)
+    (assert/assert-have-count ".ls-block" (inc blocks-count))
     (assert/assert-editor-mode)
-    (when last-edit-block-id (wait-for-new-empty-block-inserted last-edit-block-id))
     (save-block title)))
 
 ;; TODO: support tree

+ 26 - 13
clj-e2e/src/logseq/e2e/util.clj

@@ -4,8 +4,10 @@
             [logseq.e2e.assert :as assert]
             [logseq.e2e.keyboard :as k]
             [wally.main :as w]
-            [wally.selectors :as ws])
-  (:import [com.microsoft.playwright TimeoutError]))
+            [wally.repl :as repl])
+  (:import (com.microsoft.playwright Locator$PressSequentiallyOptions
+                                     Locator$FilterOptions)
+           (com.microsoft.playwright TimeoutError)))
 
 (defn repeat-until-visible
   [n q repeat-fn]
@@ -47,10 +49,11 @@
   [text]
   (w/fill "*:focus" text))
 
-(defn type
-  [text]
+(defn press-seq
+  [text & {:keys [delay] :or {delay 0}}]
   (let [input-node (w/-query "*:focus")]
-    (.type input-node text)))
+    (.pressSequentially input-node text
+                        (.setDelay (Locator$PressSequentiallyOptions.) delay))))
 
 (defn double-esc
   "Exits editing mode and ensure there's no action bar"
@@ -178,15 +181,25 @@
   (let [content (get-edit-content)]
     (when (and (not= (str (last content)) " ")
                (not= content ""))
-      (type " ")))
-  (type "/")
-  (type command)
+      (press-seq " ")))
+  (press-seq "/" {:delay 20})
   (w/wait-for ".ui__popover-content")
-  (k/enter))
+  (press-seq command {:delay 20})
+  (w/click "a.menu-link.chosen"))
 
 (defn set-tag
   [tag]
-  (type " #")
-  (type tag)
-  (w/wait-for (w/find-one-by-text "a.menu-link mark" tag))
-  (k/enter))
+  (press-seq " #" {:delay 20})
+  (press-seq tag)
+  (w/click (format "a.menu-link:has-text(\"%s\")" tag))
+  ;; wait tag added on ui
+  (assert/assert-is-visible
+   (-> (w/-query ".ls-block")
+       (.filter (.setHas (Locator$FilterOptions.)
+                         (w/-query ".editor-wrapper textarea")))
+       (.filter (.setHas (Locator$FilterOptions.)
+                         (w/-query (format ".block-tag :text('%s')" tag)))))))
+
+(defn -query-last
+  [q]
+  (.last (w/-query q)))

+ 32 - 31
clj-e2e/test/logseq/e2e/commands_test.clj

@@ -4,6 +4,7 @@
    [clj-time.local :as tl]
    [clojure.string :as string]
    [clojure.test :refer [deftest testing is use-fixtures]]
+   [logseq.e2e.assert :as assert]
    [logseq.e2e.block :as b]
    [logseq.e2e.fixtures :as fixtures]
    [logseq.e2e.keyboard :as k]
@@ -18,9 +19,8 @@
 (deftest command-trigger-test
   (testing "/command trigger popup"
     (b/new-block "b2")
-    (util/type " /")
-    (w/wait-for ".ui__popover-content")
-    (is (some? (w/find-one-by-text "span" "Node reference")))
+    (util/press-seq " /")
+    (w/wait-for "a.menu-link.chosen:has-text('Node reference')")
     (k/backspace)
     (w/wait-for-not-visible ".ui__popover-content")))
 
@@ -28,16 +28,16 @@
   (testing "Node reference"
     (testing "Page reference"
       (b/new-blocks ["b1" ""])
-      (util/input-command "Node eferen")
-      (util/type "Another page")
+      (util/input-command "Node reference")
+      (util/press-seq "Another page")
       (k/enter)
       (is (= "[[Another page]]" (util/get-edit-content)))
       (util/exit-edit)
       (is (= "Another page" (util/get-text "a.page-ref"))))
     (testing "Block reference"
       (b/new-block "")
-      (util/input-command "Node eferen")
-      (util/type "b1")
+      (util/input-command "Node reference")
+      (util/press-seq "b1")
       (util/wait-timeout 300)
       (k/enter)
       (is (string/includes? (util/get-edit-content) "[["))
@@ -47,16 +47,16 @@
 (deftest link-test
   (testing "/link"
     (let [add-logseq-link (fn []
-                            (util/type "https://logseq.com")
+                            (util/press-seq "https://logseq.com")
                             (k/tab)
-                            (util/type "Logseq")
+                            (util/press-seq "Logseq")
                             (k/tab)
                             (k/enter))]
       (b/new-block "")
       (util/input-command "link")
       (add-logseq-link)
       (is (= "[Logseq](https://logseq.com)" (util/get-edit-content)))
-      (util/type " some content ")
+      (util/press-seq " some content ")
       (util/input-command "link")
       (add-logseq-link)
       (is (= (str "[Logseq](https://logseq.com)"
@@ -67,9 +67,9 @@
   (testing "/image link"
     (b/new-block "")
     (util/input-command "image link")
-    (util/type "https://logseq.com/test.png")
+    (util/press-seq "https://logseq.com/test.png")
     (k/tab)
-    (util/type "Logseq")
+    (util/press-seq "Logseq")
     (k/tab)
     (k/enter)
     (is (= "![Logseq](https://logseq.com/test.png)" (util/get-edit-content)))))
@@ -79,7 +79,7 @@
     (b/new-block "")
     (util/input-command "underline")
     (is (= "<ins></ins>" (util/get-edit-content)))
-    (util/type "test")
+    (util/press-seq "test")
     (is (= "<ins>test</ins>" (util/get-edit-content)))
     (util/move-cursor-to-end)))
 
@@ -96,7 +96,7 @@
   (testing "/math block"
     (b/new-block "")
     (util/input-command "math block")
-    (util/type "1 + 2 = 3")
+    (util/press-seq "1 + 2 = 3")
     (util/exit-edit)
     (w/wait-for ".katex")))
 
@@ -150,7 +150,7 @@
         (b/new-block text)
         (util/input-command command)
         (k/enter)
-        (k/esc)
+        (assert/assert-editor-mode)
         (util/exit-edit)
         (is (= command (util/get-text ".property-k")))
         (is (= "Today" (util/get-text ".ls-datetime a.page-ref")))))))
@@ -191,7 +191,10 @@
     (is (= ["1." "2." "3."] (w/all-text-contents "span.typed-list")))
     ;; double `enter` convert the next block to bullet block
     (k/enter)
+    (assert/assert-have-count "span.typed-list" 4)
+    (util/wait-timeout 60)
     (k/enter)
+    (assert/assert-have-count "span.typed-list" 3)
     (is (= ["1." "2." "3."] (w/all-text-contents "span.typed-list")))))
 
 (deftest number-children-test
@@ -202,21 +205,19 @@
     (k/tab)
     (b/jump-to-block "a")
     (util/input-command "number children")
+    (assert/assert-have-count "span.typed-list" 3)
     (is (= ["1." "2." "3."] (w/all-text-contents "span.typed-list")))))
 
 (deftest query-test
   (testing "query"
     (b/new-blocks ["[[foo]] block" "[[foo]] another" ""])
     (util/input-command "query")
-    (let [btn (w/find-one-by-text "button" "Filter")]
+    (let [btn (util/-query-last "button:text('filter')")]
       (w/click btn)
       (util/input "page reference")
-      (is (some? (w/find-one-by-text "div" "page reference")))
-      (k/enter)
-      (util/input "foo")
-      (is (some? (w/find-one-by-text "div" "foo")))
-      (k/enter)
-      (is (some? (w/find-one-by-text "div" "Live query (2)"))))))
+      (w/click "a.menu-link:has-text('page reference')")
+      (w/click "a.menu-link:has-text('foo')")
+      (assert/assert-is-visible "div:text('Live query (2)')"))))
 
 (deftest advanced-query-test
   (testing "query"
@@ -235,7 +236,8 @@
     (b/new-block "")
     (util/input-command "calculator")
     (util/input "1 + 2")
-    (is (some? (w/find-one-by-text "div.extensions__code-calc-output-line" "3")))))
+    (w/wait-for "div.extensions__code-calc-output-line")
+    (is (= "3" (util/get-text "div.extensions__code-calc-output-line")))))
 
 (deftest template-test
   (testing "template"
@@ -249,16 +251,15 @@
     (util/input-command "template")
     (util/input "template 1")
     (k/enter)
-    (util/exit-edit)
-    (let [content (w/all-text-contents ".ls-block .block-content")]
-      (doseq [text ["block 1" "block 2" "block 3"]]
-        (is (= 2 (count (filter #(= % text) content))))))))
+    (doseq [text ["block 1" "block 2" "block 3"]]
+      (assert/assert-have-count (.or (w/-query (format ".ls-block .block-title-wrap:text('%s')" text))
+                                     (w/-query (format ".ls-block textarea:text('%s')" text))) 2))))
 
 (deftest embed-html-test
   (testing "embed html"
     (b/new-block "")
     (util/input-command "embed html")
-    (util/type "<div id=\"embed-test\">test</div>")
+    (util/press-seq "<div id=\"embed-test\">test</div>")
     (util/exit-edit)
     (is (= "test" (util/get-text "#embed-test")))))
 
@@ -266,7 +267,7 @@
   (testing "embed video"
     (b/new-block "")
     (util/input-command "embed video")
-    (util/type "https://www.youtube.com/watch?v=7xTGNNLPyMI")
+    (util/press-seq "https://www.youtube.com/watch?v=7xTGNNLPyMI")
     (util/exit-edit)
     (w/wait-for "iframe")))
 
@@ -274,7 +275,7 @@
   (testing "embed tweet"
     (b/new-block "")
     (util/input-command "embed tweet")
-    (util/type "https://x.com/logseq/status/1784914564083314839")
+    (util/press-seq "https://x.com/logseq/status/1784914564083314839")
     (util/exit-edit)
     (w/wait-for "iframe")))
 
@@ -282,7 +283,7 @@
   (testing "cloze"
     (b/new-block "")
     (util/input-command "cloze")
-    (util/type "hidden answer")
+    (util/press-seq "hidden answer")
     (util/exit-edit)
     (w/click "a.cloze")
     (w/wait-for "a.cloze-revealed")))

+ 15 - 0
clj-e2e/test/logseq/e2e/custom_report.clj

@@ -38,3 +38,18 @@
   (when-let [all-contexts (seq *pw-contexts*)]
     (doseq [page (mapcat pw-page/get-pages all-contexts)]
       (screenshot page (string/join "-" (map (comp str :name meta) t/*testing-vars*))))))
+
+(defmethod t/report :fail
+  [m]
+  (t/with-test-out
+    (t/inc-report-counter :fail)
+    (println "\nFAIL in" (t/testing-vars-str m))
+    (when (seq t/*testing-contexts*) (println (t/testing-contexts-str)))
+    (when-let [message (:message m)] (println message))
+    (println "expected:" (pr-str (:expected m)))
+    (println "  actual:" (pr-str (:actual m))))
+
+  ;; screenshot for all pw pages when :fail
+  (when-let [all-contexts (seq *pw-contexts*)]
+    (doseq [page (mapcat pw-page/get-pages all-contexts)]
+      (screenshot page (string/join "-" (map (comp str :name meta) t/*testing-vars*))))))

+ 2 - 0
deps/common/resources/templates/config.edn

@@ -22,6 +22,7 @@
 
  ;; Define the default journal page template.
  ;; Enter the template name between the quotes.
+ ;; This is _only_ for file graphs.
  :default-templates
  {:journals ""}
 
@@ -37,6 +38,7 @@
  ;;   This configuration is not retroactive and affects only new journals.
  ;;   To show old journal files in the app, manually rename the files in the
  ;;   journal directory to match the new format.
+ ;; This is _only_ for file graphs.
  ;; Default value: "yyyy_MM_dd"
  ;; :journal/file-name-format "yyyy_MM_dd"
 

+ 1 - 1
packages/tldraw/apps/tldraw-logseq/src/lib/shapes/HTMLShape.tsx

@@ -96,7 +96,7 @@ export class HTMLShape extends TLBoxShape<HTMLShapeProps> {
     React.useEffect(() => {
       if (this.props.size[1] === 0) {
         this.onResetBounds({ zoom: app.viewport.camera.zoom })
-        app.persist({replace: true})
+        app.persist()
       }
     }, [])
 

+ 4 - 3
packages/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx

@@ -296,7 +296,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
             size: [this.props.size[0], newHeight],
           })
 
-          if (loaded) app.persist({replace: true})
+          if (loaded) app.persist({})
         }
       }
     }, [innerHeight, this.props.isAutoResizing])
@@ -305,7 +305,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
       if (!this.initialHeightCalculated) {
         setTimeout(() => {
           this.onResetBounds()
-          app.persist({replace: true})
+          app.persist({})
         })
       }
     }, [this.initialHeightCalculated])
@@ -423,9 +423,10 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     const onPageNameChanged = React.useCallback((id: string, isPage: boolean) => {
       this.initialHeightCalculated = false
       const blockType = isPage ? 'P' : 'B'
+      const height = isPage ? 320 : 40
       this.update({
         pageId: id,
-        size: [400, 320],
+        size: [400, height],
         blockType: blockType,
         compact: blockType === 'B',
       })

+ 2 - 2
packages/tldraw/apps/tldraw-logseq/src/lib/shapes/TweetShape.tsx

@@ -61,7 +61,7 @@ export class TweetShape extends TLBoxShape<TweetShapeProps> {
         this.update({
           size: [this.props.size[0], newHeight],
         })
-        app.persist({replace: true})
+        app.persist()
       }
     }, [innerHeight])
 
@@ -69,7 +69,7 @@ export class TweetShape extends TLBoxShape<TweetShapeProps> {
       if (!this.initialHeightCalculated) {
         setTimeout(() => {
           this.onResetBounds()
-          app.persist({replace: true})
+          app.persist()
         })
       }
     }, [this.initialHeightCalculated])

+ 0 - 10
packages/tldraw/cljs-demo/.clj-kondo/config.edn

@@ -1,10 +0,0 @@
-{:hooks {:analyze-call {rum.core/defc hooks.rum/defc
-                         rum.core/defcs hooks.rum/defcs}}
- :lint-as {promesa.core/let clojure.core/let
-           promesa.core/loop clojure.core/loop
-           promesa.core/recur clojure.core/recur
-           rum.core/defcc rum.core/defc
-           rum.core/defcontext clojure.core/def
-           clojure.test.check.clojure-test/defspec clojure.core/def
-           clojure.test.check.properties/for-all clojure.core/for}
- :skip-comments true}

+ 0 - 68
packages/tldraw/cljs-demo/.clj-kondo/hooks/rum.clj

@@ -1,68 +0,0 @@
-(ns hooks.rum
-  (:require [clj-kondo.hooks-api :as api]))
-
-(defn fn-body? [x]
-  (and (seq? x)
-       (vector? (first x))))
-
-(defn rewrite-body [mixins body defcs?]
-  (if defcs?
-    (let [[binding-vec & body] (:children body)
-          [state-arg & rest-args] (:children binding-vec)
-          ;; the original vector without the state argument
-          fn-args (assoc binding-vec :children rest-args)
-          body (api/list-node
-                (list* (api/token-node 'let*)
-                       (api/vector-node [state-arg (api/token-node nil)])
-                       state-arg
-                       (concat mixins body)))
-          body (api/list-node [fn-args body])]
-      body)
-    (let [[binding-vec & body] (:children body)]
-      (api/list-node (cons binding-vec (concat mixins body))))))
-
-(defn rewrite
-  ([node] (rewrite node false))
-  ([node defcs?]
-   (let [args (rest (:children node))
-         component-name (first args)
-         ?docstring (when (string? (api/sexpr (second args)))
-                      (second args))
-         args (if ?docstring
-                (nnext args)
-                (next args))
-         bodies
-         (loop [args* (seq args)
-                mixins []
-                bodies []]
-           (if args*
-             (let [a (first args*)
-                   a-sexpr (api/sexpr a)]
-               (cond (vector? a-sexpr) ;; a-sexpr is a binding vec and the rest is the body of the function
-                     [(rewrite-body mixins (api/list-node args*) defcs?)]
-                     (fn-body? a-sexpr)
-                     (recur (next args*)
-                            mixins
-                            (conj bodies (rewrite-body mixins a defcs?)))
-                     ;; assume mixin
-                     :else (recur (next args*)
-                                  (conj mixins a)
-                                  bodies)))
-             bodies))
-         new-node (with-meta
-                    (api/list-node
-                     (list* (api/token-node 'defn)
-                            component-name
-                            (if ?docstring
-                              (cons ?docstring bodies)
-                              bodies)))
-                    (meta node))]
-     new-node)))
-
-(defn defc [{:keys [:node]}]
-  (let [new-node (rewrite node)]
-    {:node new-node}))
-
-(defn defcs [{:keys [:node]}]
-  (let [new-node (rewrite node true)]
-    {:node new-node}))

+ 0 - 30
packages/tldraw/cljs-demo/.gitignore

@@ -1,30 +0,0 @@
-node_modules/
-public/js
-public/styles.css
-
-src/js/tldraw-logseq.js
-
-/target
-/checkouts
-/src/gen
-
-dist
-
-pom.xml
-pom.xml.asc
-*.iml
-*.jar
-*.log
-.shadow-cljs
-.idea
-.lein-*
-.nrepl-*
-.DS_Store
-
-.hgignore
-.hg/
-
-.clj-kondo/.cache
-.lsp
-.calva
-.cpcache

+ 0 - 14
packages/tldraw/cljs-demo/deps.edn

@@ -1,14 +0,0 @@
-{:paths ["src/main" "src/gen" "src/js"]
-
- :deps
- {rum/rum                             {:mvn/version "0.12.9"}
-  org.clojure/clojure                 {:mvn/version "1.10.0"}
-  org.clojure/clojurescript           {:mvn/version "1.11.4"}
-  org.clojure/tools.namespace         {:mvn/version "0.2.11"}
-  cljs-bean/cljs-bean                 {:mvn/version "1.8.0"}}
-
- :aliases
- {:shadow-cljs
-  {:extra-deps {thheller/shadow-cljs        {:mvn/version "2.18.0"}
-                binaryage/devtools          {:mvn/version "1.0.6"}
-                cider/cider-nrepl           {:mvn/version "0.28.3"}}}}}

+ 0 - 18
packages/tldraw/cljs-demo/package.json

@@ -1,18 +0,0 @@
-{
-  "version": "0.0.0-dev",
-  "name": "tldraw-logseq-demo",
-  "license": "MIT",
-  "scripts": {
-    "postinstall": "ln -fs `pwd`/../apps/tldraw-logseq/src/styles.css public/styles.css; ln -f `pwd`/../apps/tldraw-logseq/dist/index.js src/js/tldraw-logseq.js",
-    "dev": "shadow-cljs watch frontend"
-  },
-  "devDependencies": {
-    "node-libs-browser": "^2.2.1",
-    "react": "^17",
-    "react-dom": "^17",
-    "shadow-cljs": "^2.19.0"
-  },
-  "dependencies": {
-    "tldraw-logseq": "../apps/tldraw-logseq"
-  }
-}

+ 0 - 17
packages/tldraw/cljs-demo/public/index.html

@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html lang="en" data-theme="light">
-  <head>
-    <meta charset="UTF-8" />
-    <meta
-      name="viewport"
-      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
-    />
-    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
-  </head>
-  <body>
-    <div id="app"></div>
-    <script src="js/main.js"></script>
-    <link rel="stylesheet" href="styles.css" />
-    <link rel="stylesheet" href="https://asset.logseq.com/static/css/style.css" />
-  </body>
-</html>

+ 0 - 22
packages/tldraw/cljs-demo/shadow-cljs.edn

@@ -1,22 +0,0 @@
-;; shadow-cljs configuration
-{:deps {:aliases [:shadow-cljs]}
-
- :nrepl
- {:port 8702}
-
- :js-options {:js-package-dirs ["node_modules" "../node_modules"]}
-
- :compiler-options {:infer-externs      :auto
-                    :output-feature-set :es-next
-                    :source-map         true
-                    :source-map-detail-level :all
-                    :warnings           {:fn-deprecated false}}
-
- :builds
- {:frontend
-  {:target :browser
-   :module-loader true
-   :modules {:main {:init-fn playground.index/init}}
-   :devtools
-   {:http-root   "public"
-    :http-port   3100}}}}

+ 0 - 0
packages/tldraw/cljs-demo/src/js/.gitkeep


+ 0 - 23
packages/tldraw/cljs-demo/src/main/playground/index.cljs

@@ -1,23 +0,0 @@
-(ns playground.index
-  (:require [rum.core :as rum]
-            [playground.tldraw :refer [Tldraw]]))
-
-(rum/defc root []
-  [:div.h-screen.w-screen (Tldraw)])
-
-(defn ^:dev/after-load  start []
-  ;; start is called by init and after code reloading finishes
-  ;; this is controlled by the :after-load in the config
-  (rum/mount (root)
-             (. js/document (getElementById "app"))))
-
-(defn ^:export init []
-  ;; init is called ONCE when the page loads
-  ;; this is called in the index.html and must be exported
-  ;; so it is available even in :advanced release builds
-  (start))
-
-(defn stop []
-  ;; stop is called before any code is reloaded
-  ;; this is controlled by :before-load in the config
-  (js/console.log "stop"))

+ 0 - 97
packages/tldraw/cljs-demo/src/main/playground/rum.cljs

@@ -1,97 +0,0 @@
-(ns playground.rum
-  (:require [clojure.string :as s]
-            [clojure.set :as set]
-            [clojure.walk :as w]
-            [rum.core :refer [use-state use-effect!] :as rum]
-            [daiquiri.interpreter :as interpreter]
-            [cljs-bean.core :as bean]))
-
-;; copy from https://github.com/priornix/antizer/blob/35ba264cf48b84e6597743e28b3570d8aa473e74/src/antizer/core.cljs
-
-(defn kebab-case->camel-case
-  "Converts from kebab case to camel case, eg: on-click to onClick"
-  [input]
-  (let [words (s/split input #"-")
-        capitalize (->> (rest words)
-                        (map #(apply str (s/upper-case (first %)) (rest %))))]
-    (apply str (first words) capitalize)))
-
-(defn map-keys->camel-case
-  "Stringifys all the keys of a cljs hashmap and converts them
-   from kebab case to camel case. If :html-props option is specified,
-   then rename the html properties values to their dom equivalent
-   before conversion"
-  [data & {:keys [html-props]}]
-  (let [convert-to-camel (fn [[key value]]
-                           [(kebab-case->camel-case (name key)) value])]
-    (w/postwalk (fn [x]
-                  (if (map? x)
-                    (let [new-map (if html-props
-                                    (set/rename-keys x {:class :className :for :htmlFor})
-                                    x)]
-                      (into {} (map convert-to-camel new-map)))
-                    x))
-                data)))
-
-;; adapted from https://github.com/tonsky/rum/issues/20
-(defn adapt-class
-  ([react-class]
-   (adapt-class react-class false))
-  ([react-class skip-opts-transform?]
-   (fn [& args]
-     (let [[opts children] (if (map? (first args))
-                             [(first args) (rest args)]
-                             [{} args])
-           type# (first children)
-          ;; we have to make sure to check if the children is sequential
-          ;; as a list can be returned, eg: from a (for)
-           new-children (if (sequential? type#)
-                          (let [result (interpreter/interpret children)]
-                            (if (sequential? result)
-                              result
-                              [result]))
-                          children)
-          ;; convert any options key value to a react element, if
-          ;; a valid html element tag is used, using sablono
-           vector->react-elems (fn [[key val]]
-                                 (if (sequential? val)
-                                   [key (daiquiri.interpreter/interpret val)]
-                                   [key val]))
-           new-options (into {}
-                             (if skip-opts-transform?
-                               opts
-                               (map vector->react-elems opts)))]
-       (apply js/React.createElement react-class
-        ;; sablono html-to-dom-attrs does not work for nested hashmaps
-              (bean/->js (map-keys->camel-case new-options :html-props true))
-              new-children)))))
-
-(defn use-atom-fn
-  [a getter-fn setter-fn]
-  (let [[val set-val] (use-state (getter-fn @a))]
-    (use-effect!
-     (fn []
-       (let [id (str (random-uuid))]
-         (add-watch a id (fn [_ _ prev-state next-state]
-                           (let [prev-value (getter-fn prev-state)
-                                 next-value (getter-fn next-state)]
-                             (when-not (= prev-value next-value)
-                               (set-val next-value)))))
-         #(remove-watch a id)))
-     [])
-    [val #(swap! a setter-fn %)]))
-
-(defn use-atom
-  "(use-atom my-atom)"
-  [a]
-  (use-atom-fn a identity (fn [_ v] v)))
-
-(defn use-mounted
-  []
-  (let [*mounted (rum/use-ref false)]
-    (use-effect!
-     (fn []
-       (rum/set-ref! *mounted true)
-       #(rum/set-ref! *mounted false))
-     [])
-    #(rum/deref *mounted)))

+ 0 - 68
packages/tldraw/cljs-demo/src/main/playground/tldraw.cljs

@@ -1,68 +0,0 @@
-(ns playground.tldraw
-  (:require [rum.core :as rum]
-            ["/tldraw-logseq" :as tldraw]))
-
-(def persist-key "playground.index")
-
-;; from apps/logseq/src/documents/dev.ts
-(def dev-doc-model
-  {"currentPageId" "page1",
-   "selectedIds" ["0jy4JuM61pS9QQthBDme-"],
-   "pages"
-   [{"id" "page1",
-     "name" "Page",
-     "shapes"
-     [{"parentId" "page1",
-       "handles"
-       {"start" {"id" "start", "canBind" true, "point" [0 0]}, "end" {"id" "end", "canBind" true, "point" [392 272]}},
-       "scale" [1 1],
-       "label" "",
-       "id" "0jy4JuM61pS9QQthBDme-",
-       "stroke" "",
-       "fill" "",
-       "strokeWidth" 1,
-       "type" "line",
-       "decorations" {"end" "arrow"},
-       "nonce" 1655952872458,
-       "opacity" 1,
-       "point" [379.6805699752259 82.67652436640805 0.5]}
-      {"parentId" "page1",
-       "pageId" "car",
-       "collapsed" false,
-       "blockType" "P",
-       "collapsedHeight" 0,
-       "scale" [1 1],
-       "id" "hRp0fnc0i2BZIjEbZqO6_",
-       "stroke" "",
-       "fill" "",
-       "strokeWidth" 2,
-       "type" "logseq-portal",
-       "nonce" 1655952865192,
-       "size" [600 320],
-       "opacity" 1,
-       "point" [876.7157262252258 195.59449311640805]}],
-     "bindings" {},
-     "nonce" 1}],
-   "assets" []})
-
-(set! *warn-on-infer* false)
-
-;; Debounce it?
-(defn on-persist [app]
-  (let [document (.-serialized app)]
-    ;; persit to localstorage
-    (.setItem js/sessionStorage persist-key (js/JSON.stringify document))))
-
-(defn on-load []
-  (if-let [raw-str (.getItem js/sessionStorage persist-key)]
-    (js->clj (js/JSON.parse raw-str))
-    dev-doc-model))
-
-(def model (on-load))
-
-(rum/defc test-comp [props] [:div (js/JSON.stringify props)])
-
-(rum/defc Tldraw []
-  (tldraw/App (clj->js {:PageComponent test-comp
-                        :onPersist on-persist
-                        :model model})))

+ 0 - 701
packages/tldraw/cljs-demo/yarn.lock

@@ -1,701 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-asn1.js@^5.2.0:
-  version "5.4.1"
-  resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
-  integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
-  dependencies:
-    bn.js "^4.0.0"
-    inherits "^2.0.1"
-    minimalistic-assert "^1.0.0"
-    safer-buffer "^2.1.0"
-
-assert@^1.1.1:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
-  integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
-  dependencies:
-    object-assign "^4.1.1"
-    util "0.10.3"
-
-base64-js@^1.0.2:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
-  integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
-  version "4.12.0"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
-  integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
-
-bn.js@^5.0.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
-  integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
-
-bn.js@^5.2.1:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
-  integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
-
-brorand@^1.0.1, brorand@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
-  integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
-
-browserify-aes@^1.0.0, browserify-aes@^1.0.4:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
-  integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
-  dependencies:
-    buffer-xor "^1.0.3"
-    cipher-base "^1.0.0"
-    create-hash "^1.1.0"
-    evp_bytestokey "^1.0.3"
-    inherits "^2.0.1"
-    safe-buffer "^5.0.1"
-
-browserify-cipher@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
-  integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
-  dependencies:
-    browserify-aes "^1.0.4"
-    browserify-des "^1.0.0"
-    evp_bytestokey "^1.0.0"
-
-browserify-des@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
-  integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
-  dependencies:
-    cipher-base "^1.0.1"
-    des.js "^1.0.0"
-    inherits "^2.0.1"
-    safe-buffer "^5.1.2"
-
-browserify-rsa@^4.0.0, browserify-rsa@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d"
-  integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==
-  dependencies:
-    bn.js "^5.0.0"
-    randombytes "^2.0.1"
-
-browserify-sign@^4.0.0:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e"
-  integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==
-  dependencies:
-    bn.js "^5.2.1"
-    browserify-rsa "^4.1.0"
-    create-hash "^1.2.0"
-    create-hmac "^1.1.7"
-    elliptic "^6.5.4"
-    inherits "^2.0.4"
-    parse-asn1 "^5.1.6"
-    readable-stream "^3.6.2"
-    safe-buffer "^5.2.1"
-
-browserify-zlib@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
-  integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
-  dependencies:
-    pako "~1.0.5"
-
-buffer-xor@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
-  integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
-
-buffer@^4.3.0:
-  version "4.9.2"
-  resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
-  integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
-  dependencies:
-    base64-js "^1.0.2"
-    ieee754 "^1.1.4"
-    isarray "^1.0.0"
-
-builtin-status-codes@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
-  integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
-
-cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
-  integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
-  dependencies:
-    inherits "^2.0.1"
-    safe-buffer "^5.0.1"
-
-console-browserify@^1.1.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
-  integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
-
-constants-browserify@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
-  integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
-
-core-util-is@~1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
-  integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
-
-create-ecdh@^4.0.0:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
-  integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==
-  dependencies:
-    bn.js "^4.1.0"
-    elliptic "^6.5.3"
-
-create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
-  integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
-  dependencies:
-    cipher-base "^1.0.1"
-    inherits "^2.0.1"
-    md5.js "^1.3.4"
-    ripemd160 "^2.0.1"
-    sha.js "^2.4.0"
-
-create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
-  integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
-  dependencies:
-    cipher-base "^1.0.3"
-    create-hash "^1.1.0"
-    inherits "^2.0.1"
-    ripemd160 "^2.0.0"
-    safe-buffer "^5.0.1"
-    sha.js "^2.4.8"
-
-crypto-browserify@^3.11.0:
-  version "3.12.0"
-  resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
-  integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
-  dependencies:
-    browserify-cipher "^1.0.0"
-    browserify-sign "^4.0.0"
-    create-ecdh "^4.0.0"
-    create-hash "^1.1.0"
-    create-hmac "^1.1.0"
-    diffie-hellman "^5.0.0"
-    inherits "^2.0.1"
-    pbkdf2 "^3.0.3"
-    public-encrypt "^4.0.0"
-    randombytes "^2.0.0"
-    randomfill "^1.0.3"
-
-des.js@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
-  integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
-  dependencies:
-    inherits "^2.0.1"
-    minimalistic-assert "^1.0.0"
-
-diffie-hellman@^5.0.0:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
-  integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
-  dependencies:
-    bn.js "^4.1.0"
-    miller-rabin "^4.0.0"
-    randombytes "^2.0.0"
-
-domain-browser@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
-  integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-
-elliptic@^6.5.3, elliptic@^6.5.4:
-  version "6.5.4"
-  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
-  integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
-  dependencies:
-    bn.js "^4.11.9"
-    brorand "^1.1.0"
-    hash.js "^1.0.0"
-    hmac-drbg "^1.0.1"
-    inherits "^2.0.4"
-    minimalistic-assert "^1.0.1"
-    minimalistic-crypto-utils "^1.0.1"
-
-events@^3.0.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
-  integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
-
-evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
-  integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
-  dependencies:
-    md5.js "^1.3.4"
-    safe-buffer "^5.1.1"
-
-hash-base@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
-  integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
-  dependencies:
-    inherits "^2.0.4"
-    readable-stream "^3.6.0"
-    safe-buffer "^5.2.0"
-
-hash.js@^1.0.0, hash.js@^1.0.3:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
-  integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
-  dependencies:
-    inherits "^2.0.3"
-    minimalistic-assert "^1.0.1"
-
-hmac-drbg@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
-  integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
-  dependencies:
-    hash.js "^1.0.3"
-    minimalistic-assert "^1.0.0"
-    minimalistic-crypto-utils "^1.0.1"
-
-https-browserify@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
-  integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
-
-ieee754@^1.1.4:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
-  integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-
[email protected]:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
-  integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
-
[email protected]:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
-inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
-  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-isarray@^1.0.0, isarray@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
-  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isexe@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
-  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-
-"js-tokens@^3.0.0 || ^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
-  integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-loose-envify@^1.1.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
-  integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
-  dependencies:
-    js-tokens "^3.0.0 || ^4.0.0"
-
-md5.js@^1.3.4:
-  version "1.3.5"
-  resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
-  integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
-  dependencies:
-    hash-base "^3.0.0"
-    inherits "^2.0.1"
-    safe-buffer "^5.1.2"
-
-miller-rabin@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
-  integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
-  dependencies:
-    bn.js "^4.0.0"
-    brorand "^1.0.1"
-
-minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
-  integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
-
-minimalistic-crypto-utils@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
-  integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-
-node-libs-browser@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
-  integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
-  dependencies:
-    assert "^1.1.1"
-    browserify-zlib "^0.2.0"
-    buffer "^4.3.0"
-    console-browserify "^1.1.0"
-    constants-browserify "^1.0.0"
-    crypto-browserify "^3.11.0"
-    domain-browser "^1.1.1"
-    events "^3.0.0"
-    https-browserify "^1.0.0"
-    os-browserify "^0.3.0"
-    path-browserify "0.0.1"
-    process "^0.11.10"
-    punycode "^1.2.4"
-    querystring-es3 "^0.2.0"
-    readable-stream "^2.3.3"
-    stream-browserify "^2.0.1"
-    stream-http "^2.7.2"
-    string_decoder "^1.0.0"
-    timers-browserify "^2.0.4"
-    tty-browserify "0.0.0"
-    url "^0.11.0"
-    util "^0.11.0"
-    vm-browserify "^1.0.1"
-
-object-assign@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
-  integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-os-browserify@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
-  integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
-
-pako@~1.0.5:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
-  integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
-
-parse-asn1@^5.0.0, parse-asn1@^5.1.6:
-  version "5.1.6"
-  resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4"
-  integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==
-  dependencies:
-    asn1.js "^5.2.0"
-    browserify-aes "^1.0.0"
-    evp_bytestokey "^1.0.0"
-    pbkdf2 "^3.0.3"
-    safe-buffer "^5.1.1"
-
[email protected]:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
-  integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
-
-pbkdf2@^3.0.3:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
-  integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==
-  dependencies:
-    create-hash "^1.1.2"
-    create-hmac "^1.1.4"
-    ripemd160 "^2.0.1"
-    safe-buffer "^5.0.1"
-    sha.js "^2.4.8"
-
-process-nextick-args@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
-  integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-process@^0.11.10:
-  version "0.11.10"
-  resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
-  integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
-
-public-encrypt@^4.0.0:
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
-  integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
-  dependencies:
-    bn.js "^4.1.0"
-    browserify-rsa "^4.0.0"
-    create-hash "^1.1.0"
-    parse-asn1 "^5.0.0"
-    randombytes "^2.0.1"
-    safe-buffer "^5.1.2"
-
[email protected]:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-  integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
-punycode@^1.2.4:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
-  integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
-querystring-es3@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
-  integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
-
[email protected]:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-  integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
-randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
-  integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
-  dependencies:
-    safe-buffer "^5.1.0"
-
-randomfill@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
-  integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
-  dependencies:
-    randombytes "^2.0.5"
-    safe-buffer "^5.1.0"
-
-react-dom@^17:
-  version "17.0.2"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
-  integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-    scheduler "^0.20.2"
-
-react@^17:
-  version "17.0.2"
-  resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
-  integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-
-readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6:
-  version "2.3.7"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
-  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
-  dependencies:
-    core-util-is "~1.0.0"
-    inherits "~2.0.3"
-    isarray "~1.0.0"
-    process-nextick-args "~2.0.0"
-    safe-buffer "~5.1.1"
-    string_decoder "~1.1.1"
-    util-deprecate "~1.0.1"
-
-readable-stream@^3.6.0:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
-  integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
-  dependencies:
-    inherits "^2.0.3"
-    string_decoder "^1.1.1"
-    util-deprecate "^1.0.1"
-
-readable-stream@^3.6.2:
-  version "3.6.2"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
-  integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
-  dependencies:
-    inherits "^2.0.3"
-    string_decoder "^1.1.1"
-    util-deprecate "^1.0.1"
-
-readline-sync@^1.4.7:
-  version "1.4.10"
-  resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
-  integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==
-
-ripemd160@^2.0.0, ripemd160@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
-  integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
-  dependencies:
-    hash-base "^3.0.0"
-    inherits "^2.0.1"
-
-safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
-  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
-  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safer-buffer@^2.1.0:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
-  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-scheduler@^0.20.2:
-  version "0.20.2"
-  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
-  integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-
-setimmediate@^1.0.4:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
-  integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
-
-sha.js@^2.4.0, sha.js@^2.4.8:
-  version "2.4.11"
-  resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
-  integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
-  dependencies:
-    inherits "^2.0.1"
-    safe-buffer "^5.0.1"
-
[email protected]:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz#97273afe1747b6a2311917c1c88d9e243c81957b"
-  integrity sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==
-
-shadow-cljs@^2.19.0:
-  version "2.19.4"
-  resolved "https://registry.yarnpkg.com/shadow-cljs/-/shadow-cljs-2.19.4.tgz#7973df717aa1edbec09539c0282d82de25bb575a"
-  integrity sha512-4SSy4RW5R7z8e3OIqXTFmF9AtxlG7nvsa7PZ81cAB5Wn2nn82nR8w9m4mtoZXdmqMgMOfadrhnMQdyurJdiXVQ==
-  dependencies:
-    node-libs-browser "^2.2.1"
-    readline-sync "^1.4.7"
-    shadow-cljs-jar "1.3.2"
-    source-map-support "^0.4.15"
-    which "^1.3.1"
-    ws "^7.4.6"
-
-source-map-support@^0.4.15:
-  version "0.4.18"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
-  integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==
-  dependencies:
-    source-map "^0.5.6"
-
-source-map@^0.5.6:
-  version "0.5.7"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-  integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
-stream-browserify@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
-  integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
-  dependencies:
-    inherits "~2.0.1"
-    readable-stream "^2.0.2"
-
-stream-http@^2.7.2:
-  version "2.8.3"
-  resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
-  integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
-  dependencies:
-    builtin-status-codes "^3.0.0"
-    inherits "^2.0.1"
-    readable-stream "^2.3.6"
-    to-arraybuffer "^1.0.0"
-    xtend "^4.0.0"
-
-string_decoder@^1.0.0, string_decoder@^1.1.1:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
-  integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
-  dependencies:
-    safe-buffer "~5.2.0"
-
-string_decoder@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
-  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
-  dependencies:
-    safe-buffer "~5.1.0"
-
-timers-browserify@^2.0.4:
-  version "2.0.12"
-  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee"
-  integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==
-  dependencies:
-    setimmediate "^1.0.4"
-
-tldraw-logseq@../apps/tldraw-logseq:
-  version "0.0.0-dev"
-
-to-arraybuffer@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
-  integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
-
[email protected]:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
-  integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
-
-url@^0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
-  integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
-  dependencies:
-    punycode "1.3.2"
-    querystring "0.2.0"
-
-util-deprecate@^1.0.1, util-deprecate@~1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
[email protected]:
-  version "0.10.3"
-  resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
-  integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
-  dependencies:
-    inherits "2.0.1"
-
-util@^0.11.0:
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
-  integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==
-  dependencies:
-    inherits "2.0.3"
-
-vm-browserify@^1.0.1:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
-  integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
-
-which@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
-  integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
-  dependencies:
-    isexe "^2.0.0"
-
-ws@^7.4.6:
-  version "7.5.7"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
-  integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
-
-xtend@^4.0.0:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
-  integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==

+ 0 - 17
packages/tldraw/demo/index.html

@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link
-      rel="stylesheet"
-      href="https://cdn.jsdelivr.net/npm/@tabler/icons@latest/iconfont/tabler-icons.min.css"
-    />
-
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite App</title>
-  </head>
-  <body>
-    <div id="root"></div>
-    <script type="module" src="/src/main.jsx"></script>
-  </body>
-</html>

+ 0 - 29
packages/tldraw/demo/package.json

@@ -1,29 +0,0 @@
-{
-  "name": "@tldraw/demo",
-  "private": true,
-  "version": "0.0.0-dev",
-  "devDependencies": {
-    "@babel/plugin-proposal-decorators": "^7.20.2",
-    "@swc/core": "^1.3.21",
-    "@typescript-eslint/eslint-plugin": "^5.43.0",
-    "@typescript-eslint/parser": "^5.43.0",
-    "@vitejs/plugin-basic-ssl": "^0.1.2",
-    "autoprefixer": "^10.4.13",
-    "eslint": "^8.27.0",
-    "postcss": "^8.4.19",
-    "prettier-plugin-jsdoc": "^0.4.2",
-    "tailwindcss": "^3.2.4",
-    "tslib": "^2.4.1",
-    "typescript": "^4.9.3",
-    "unplugin-swc": "^1.3.2",
-    "vite": "^3.2.7"
-  },
-  "scripts": {
-    "dev": "vite"
-  },
-  "dependencies": {
-    "@vitejs/plugin-react": "^2.2.0",
-    "react": "^17",
-    "react-dom": "^17"
-  }
-}

+ 0 - 15
packages/tldraw/demo/postcss.config.js

@@ -1,15 +0,0 @@
-const rootTailwindConfig = require('../../../tailwind.config')
-
-module.exports = {
-  plugins: {
-    'postcss-import': {},
-    'postcss-nested': {},
-    'postcss-import-ext-glob': {},
-    'tailwindcss/nesting': {},
-    tailwindcss: {
-      ...rootTailwindConfig,
-      content: ['./**/*.jsx', '../apps/**/*.{js,jsx,ts,tsx}'],
-    },
-    autoprefixer: {},
-  },
-}

+ 0 - 277
packages/tldraw/demo/src/App.jsx

@@ -1,277 +0,0 @@
-import { uniqueId, fileToBase64 } from '@tldraw/core'
-import React from 'react'
-import ReactDOM from 'react-dom'
-import { App as TldrawApp, generateJSXFromModel } from '@tldraw/logseq'
-
-const storingKey = 'playground.index'
-
-const onPersist = app => {
-  console.log('onPersist', app)
-  window.sessionStorage.setItem(storingKey, JSON.stringify(app.serialized))
-}
-
-const onLoad = () => {
-  return JSON.parse(window.sessionStorage.getItem(storingKey))
-}
-
-const documentModel = onLoad() ?? {
-  currentPageId: 'page1',
-  selectedIds: ['p6bv7EfoQPIF1eZB1RRO6'],
-  pages: [
-    {
-      id: 'page1',
-      name: 'Page',
-      shapes: [
-        {
-          parentId: 'page1',
-          id: '2ec86a35-7ae1-11ed-8cf0-d77b96340231',
-          type: 'group',
-          children: [
-            '2ec86a30-7ae1-11ed-8cf0-d77b96340231',
-            '304ce750-7ae1-11ed-8cf0-d77b96340231',
-          ],
-        },
-        {
-          scale: [1, 1],
-          id: '2ec86a30-7ae1-11ed-8cf0-d77b96340231',
-          parentId: 'page1',
-          type: 'box',
-          point: [440.1057854416563, 323.39934576376567],
-          size: [237.39428786834378, 109.46744189728395],
-          borderRadius: 2,
-          stroke: '',
-          fill: '',
-          noFill: false,
-          fontWeight: 400,
-          italic: false,
-          strokeType: 'line',
-          strokeWidth: 2,
-          opacity: 1,
-          label: '',
-          nonce: 1670934308981,
-        },
-        {
-          scale: [1, 1],
-          id: '304ce750-7ae1-11ed-8cf0-d77b96340231',
-          parentId: 'page1',
-          type: 'box',
-          point: [667.72008322492, 250.01956107918932],
-          size: [316.42711988510905, 134.2180982739887],
-          borderRadius: 2,
-          stroke: '',
-          fill: '',
-          noFill: false,
-          fontWeight: 400,
-          italic: false,
-          strokeType: 'line',
-          strokeWidth: 2,
-          opacity: 1,
-          label: '',
-          nonce: 1670934311539,
-        },
-      ],
-      bindings: {},
-      nonce: 2,
-    },
-  ],
-}
-
-const Page = () => {
-  return (
-    <div className="w-full font-mono page">
-      The Circle components are a collection of standardized UI elements and patterns for building
-      products. These pages provide more information and best practices on how to use the
-      components.The Circle components are a collection of standardized UI elements and patterns for
-      building products. These pages provide more information and best practices on how to use the
-      components.
-    </div>
-  )
-}
-
-const Block = () => {
-  return (
-    <div className="w-full font-mono single-block">
-      The Circle components are a collection of standardized UI elements and patterns for building
-      products. These pages provide more information and best practices on how to use the
-      components.The Circle components are a collection of standardized UI elements and patterns for
-      building products. These pages provide more information and best practices on how to use the
-      components.
-    </div>
-  )
-}
-
-const Breadcrumb = ({ endSeparator }) => {
-  return <div className="font-mono">Breadcrumb {endSeparator ? ' > ' : ''}</div>
-}
-
-const BlockReference = props => {
-  return <div className="font-mono">{props.blockId}</div>
-}
-
-const PageName = props => {
-  const [value, setValue] = React.useState(JSON.stringify(props))
-  return (
-    <input
-      className="whitespace-pre w-full h-full font-mono"
-      value={value}
-      onChange={e => setValue(e.target.value)}
-    />
-  )
-}
-
-const BacklinksCount = props => {
-  return (
-    <div className={props.className}>
-      <div className={'open-page-ref-link rounded bg-gray-400 p-0.5 '}>3</div>
-    </div>
-  )
-}
-
-const StatusBarSwitcher = ({ label, onClick }) => {
-  const [anchor, setAnchor] = React.useState(null)
-  React.useEffect(() => {
-    if (anchor) {
-      return
-    }
-    const id = 'status-bar-switcher-' + uniqueId()
-    let el = document.getElementById(id)
-    if (!el) {
-      el = document.createElement('div')
-      el.id = id
-      let timer = setInterval(() => {
-        const statusBarAnchor = document.querySelector('#tl-statusbar-anchor')
-        if (statusBarAnchor) {
-          statusBarAnchor.appendChild(el)
-          setAnchor(el)
-          clearInterval(timer)
-        }
-      }, 50)
-    }
-  })
-
-  if (!anchor) {
-    return null
-  }
-
-  return ReactDOM.createPortal(
-    <button
-      className="flex items-center justify-center bg-grey border px-1"
-      style={{ fontSize: '1em' }}
-      onClick={onClick}
-    >
-      {label}
-    </button>,
-    anchor
-  )
-}
-
-const ThemeSwitcher = () => {
-  const [theme, setTheme] = React.useState('light')
-
-  React.useEffect(() => {
-    document.documentElement.setAttribute('data-theme', theme)
-  }, [theme])
-
-  return (
-    <StatusBarSwitcher
-      label={theme + ' theme'}
-      onClick={() => {
-        setTheme(t => (t === 'dark' ? 'light' : 'dark'))
-      }}
-    />
-  )
-}
-
-const PreviewButton = ({ model }) => {
-  const [show, setShow] = React.useState(false)
-
-  const [[w, h], setSize] = React.useState([window.innerWidth, window.innerHeight])
-
-  React.useEffect(() => {
-    const onResize = () => {
-      setSize([window.innerWidth, window.innerHeight])
-    }
-    window.addEventListener('resize', onResize)
-    return () => window.removeEventListener('resize', onResize)
-  }, [])
-
-  const preview = React.useMemo(() => {
-    return show ? generateJSXFromModel(model, w / h) : null
-  }, [show, model, w, h])
-
-  return (
-    <>
-      {preview ? (
-        <div
-          className="fixed inset-0 flex items-center justify-center pointer-events-none h-screen w-screen"
-          style={{ zIndex: '10000' }}
-        >
-          <div className="w-1/2 h-1/2 border bg-white">{preview}</div>
-        </div>
-      ) : null}
-      <StatusBarSwitcher
-        label="Preview"
-        onClick={() => {
-          setShow(s => !s)
-        }}
-      />
-    </>
-  )
-}
-
-const searchHandler = q => {
-  return Promise.resolve({
-    pages: ['foo', 'bar', 'asdf'].filter(p => p.includes(q)),
-    blocks: [
-      { content: 'foo content 1', uuid: 'uuid 1', page: 0 },
-      { content: 'bar content 2', uuid: 'uuid 2', page: 1 },
-      { content: 'asdf content 3', uuid: 'uuid 3', page: 2 },
-    ],
-  })
-}
-
-export default function App() {
-  const [model, setModel] = React.useState(documentModel)
-
-  // Mimic external reload event
-  React.useEffect(() => {
-    const interval = setInterval(() => {
-      // setModel(onLoad())
-    }, 2000)
-
-    return () => {
-      clearInterval(interval)
-    }
-  }, [])
-
-  return (
-    <div className={`h-screen w-screen z-0 relative`}>
-      <ThemeSwitcher />
-      <PreviewButton model={model} />
-      <TldrawApp
-        renderers={{
-          Page,
-          Block,
-          Breadcrumb,
-          PageName,
-          BacklinksCount,
-          BlockReference,
-        }}
-        handlers={{
-          search: searchHandler,
-          addNewBlock: () => uniqueId(),
-          queryBlockByUUID: uuid => ({ uuid, content: 'some random content' }),
-          isWhiteboardPage: () => false,
-          saveAsset: fileToBase64,
-          makeAssetUrl: a => a,
-          getBlockPageName: a => a + '_page',
-        }}
-        model={model}
-        onPersist={app => {
-          onPersist(app)
-          setModel(app.serialized)
-        }}
-      />
-    </div>
-  )
-}

+ 0 - 81
packages/tldraw/demo/src/index.css

@@ -1,81 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-.color-level {
-  background-color: var(--color-level-1);
-}
-
-.color-level .color-level {
-  background-color: var(--color-level-2);
-}
-
-.color-level .color-level .color-level {
-  background-color: var(--color-level-3);
-}
-
-.color-level .color-level .color-level .color-level {
-  background-color: var(--color-level-4);
-}
-
-.color-level .color-level .color-level .color-level .color-level {
-  background-color: var(--color-level-5);
-}
-
-.color-level .color-level .color-level .color-level .color-level .color-level {
-  background-color: var(--color-level-3);
-}
-
-.color-level .color-level .color-level .color-level .color-level .color-level .color-level {
-  background-color: var(--color-level-4);
-}
-
-.color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level {
-  background-color: var(--color-level-5);
-}
-
-.color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level {
-  background-color: var(--color-level-3);
-}
-
-.color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level {
-  background-color: var(--color-level-4);
-}
-
-.color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level
-  .color-level {
-  background-color: var(--color-level-5);
-}

+ 0 - 2
packages/tldraw/demo/src/logseq-styles.css

@@ -1,2 +0,0 @@
-@import '../../../../resources/css/tabler-extension.css';
-@import '../../apps/tldraw-logseq/src/styles.css';

+ 0 - 11
packages/tldraw/demo/src/main.jsx

@@ -1,11 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-
-import App from './App'
-
-import './logseq-styles.css'
-import './index.css'
-
-// Not using strict mode because it may cause side effect problems
-// https://twitter.com/schickling/status/1523378971458498560
-ReactDOM.render(<App />, document.getElementById('root'))

+ 0 - 64
packages/tldraw/demo/vite.config.js

@@ -1,64 +0,0 @@
-import react from '@vitejs/plugin-react'
-// import swc from 'unplugin-swc'
-// import basicSsl from '@vitejs/plugin-basic-ssl'
-import path from 'path'
-import { defineConfig } from 'vite'
-
-const bases = {
-  core: path.resolve(__dirname, '../packages/core/src'),
-  react: path.resolve(__dirname, '../packages/react/src'),
-  tldrawLogseq: path.resolve(__dirname, '../apps/tldraw-logseq/src'),
-}
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [
-    // swc.vite({
-    //   jsc: {
-    //     target: 'es2022',
-    //     parser: {
-    //       decorators: true,
-    //       tsx: true,
-    //       jsx: true,
-    //     },
-    //     transform: {
-    //       legacyDecorator: true,
-    //       react: {
-    //         refresh: true,
-    //         runtime: 'automatic',
-    //       }
-    //     }
-    //   }
-    // }),
-    react({
-      babel: {
-        parserOpts: {
-          plugins: ['decorators-legacy'],
-        },
-        plugins: [[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }]],
-      },
-    }),
-    // basicSsl(),
-  ],
-  server: {
-    port: '3031',
-    fs: { strict: false },
-    // https: true,
-  },
-  resolve: {
-    alias: [
-      {
-        find: 'tldraw-logseq',
-        replacement: bases.tldrawLogseq,
-      },
-      {
-        find: '@tldraw/core',
-        replacement: bases.core,
-      },
-      {
-        find: '@tldraw/react',
-        replacement: bases.react,
-      },
-    ],
-  },
-})

File diff suppressed because it is too large
+ 4 - 797
packages/tldraw/yarn.lock


+ 6 - 3
src/main/frontend/common/file/core.cljs

@@ -4,8 +4,8 @@
   (:require [clojure.string :as string]
             [datascript.core :as d]
             [logseq.db :as ldb]
-            [logseq.db.frontend.content :as db-content]
             [logseq.db.common.entity-plus :as entity-plus]
+            [logseq.db.frontend.content :as db-content]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.property :as gp-property]
             [logseq.outliner.tree :as otree]))
@@ -37,8 +37,11 @@
                        depth 0]
                   (if (or (>= depth max-depth) (empty? current-refs))
                     result-refs
-                    (let [next-refs (mapcat :block/refs current-refs)]
-                      (recur (apply conj result-refs next-refs) next-refs (inc depth)))))]
+                    (let [next-refs (set (mapcat :block/refs current-refs))
+                          result-refs' (apply conj result-refs next-refs)]
+                      (if (= (count result-refs') (count result-refs))
+                        result-refs
+                        (recur (apply conj result-refs next-refs) next-refs (inc depth))))))]
     (loop [result (db-content/id-ref->title-ref (:block/title ent) ref-set true)
            last-result nil
            depth 0]

+ 8 - 7
src/main/frontend/components/page.cljs

@@ -191,13 +191,14 @@
 
 (rum/defcs page-blocks-cp < rum/reactive db-mixins/query
   {:will-mount (fn [state]
-                 (let [page-e (first (:rum/args state))
-                       page-name (:block/name page-e)]
-                   (when (and page-name
-                              (db/journal-page? page-name)
-                              (>= (date/journal-title->int page-name)
-                                  (date/journal-title->int (date/today))))
-                     (state/pub-event! [:journal/insert-template page-name])))
+                 (when-not (config/db-based-graph?)
+                  (let [page-e (first (:rum/args state))
+                        page-name (:block/name page-e)]
+                    (when (and page-name
+                               (db/journal-page? page-name)
+                               (>= (date/journal-title->int page-name)
+                                   (date/journal-title->int (date/today))))
+                      (state/pub-event! [:journal/insert-template page-name]))))
                  state)}
   [state block* {:keys [sidebar? whiteboard?] :as config}]
   (when-let [id (:db/id block*)]

+ 1 - 0
src/main/frontend/components/property/value.cljs

@@ -1158,6 +1158,7 @@
     (if editing?
       (popup-content nil)
       (let [show! (fn [e]
+                    (util/stop e)
                     (let [target (when e (.-target e))]
                       (when-not (or config/publishing?
                                     (util/shift-key? e)

+ 3 - 1
src/main/frontend/components/views.cljs

@@ -757,7 +757,9 @@
      (assoc cell-opts
             :tabIndex 0
             :ref *ref
-            :on-click (fn [] (click-cell (rum/deref *ref)))
+            :on-click (fn [e]
+                        (when-not (dom/has-class? (.-target e) "jtrigger")
+                          (click-cell (rum/deref *ref))))
             :on-key-down (fn [e]
                            (let [container (rum/deref *ref)]
                              (case (util/ekey e)

+ 1 - 1
src/main/frontend/db/async.cljs

@@ -143,7 +143,7 @@
                               (remove empty?))]
              (when (seq tx-data) (d/transact! conn tx-data))
              (when-not skip-refresh?
-               (react/refresh-affected-queries! graph affected-keys))))
+               (react/refresh-affected-queries! graph affected-keys {:skip-kv-custom-keys? true}))))
 
          (if children-only? children block))
        (p/catch (fn [error]

+ 4 - 2
src/main/frontend/db/react.cljs

@@ -173,7 +173,8 @@
       (set-new-result! k result'))))
 
 (defn refresh-affected-queries!
-  [repo-url affected-keys]
+  [repo-url affected-keys & {:keys [skip-kv-custom-keys?]
+                             :or {skip-kv-custom-keys? false}}]
   (util/profile
    "refresh!"
    (let [db (conn/get-db repo-url)
@@ -186,7 +187,8 @@
                                 [k' cache]))) @query-state)
                     (into {}))
          all-keys (concat (distinct affected-keys)
-                          (filter #(contains? #{:custom :kv} (first %)) (keys state)))]
+                          (when-not skip-kv-custom-keys?
+                            (filter #(contains? #{:custom :kv} (first %)) (keys state))))]
      (doseq [k all-keys]
        (when-let [cache (get state k)]
          (let [{:keys [query query-fn]} cache

+ 4 - 1
src/main/frontend/handler/common/config_edn.cljs

@@ -94,6 +94,7 @@ nested keys or positional errors e.g. tuples"
      :file-sync/ignore-files
      :hidden
      :ignored-page-references-keywords
+     :journal/file-name-format
      :journal/page-title-format
      :journals-directory
      :logbook/settings
@@ -115,7 +116,9 @@ nested keys or positional errors e.g. tuples"
     :feature/enable-block-timestamps?
     "is not used in DB graphs as it is always enabled"
     :favorites
-    "is not stored in config for DB graphs"}))
+    "is not stored in config for DB graphs"
+    :default-templates
+    "is replaced by #Template and the `Apply template to tags` property"}))
 
 (defn detect-deprecations
   "Detects config keys that will or have been deprecated"

+ 0 - 12
src/main/frontend/handler/events.cljs

@@ -343,18 +343,6 @@
 (defmethod handle :shortcut/refresh [[_]]
   (st/refresh!))
 
-(defmethod handle :journal/insert-template [[_ page-name]]
-  (let [page-name (util/page-name-sanity-lc page-name)]
-    (when-let [page (db/get-page page-name)]
-      (p/do!
-       (db-async/<get-block (state/get-current-repo) (:db/id page))
-       (when (db/page-empty? (state/get-current-repo) page-name)
-         (when-let [template (state/get-default-journal-template)]
-           (editor-handler/insert-template!
-            nil
-            template
-            {:target page})))))))
-
 (defmethod handle :editor/set-heading [[_ block heading]]
   (when-let [id (:block/uuid block)]
     (editor-handler/set-heading! id heading)))

+ 14 - 0
src/main/frontend/handler/file_based/events.cljs

@@ -10,9 +10,11 @@
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
+            [frontend.db.async :as db-async]
             [frontend.fs :as fs]
             [frontend.fs.sync :as sync]
             [frontend.handler.common :as common-handler]
+            [frontend.handler.editor :as editor-handler]
             [frontend.handler.events :as events]
             [frontend.handler.file-based.file :as file-handler]
             [frontend.handler.file-based.nfs :as nfs-handler]
@@ -353,3 +355,15 @@
                                           :remote? true)
                                    r))
                                (state/get-repos)))))))
+
+(defmethod events/handle :journal/insert-template [[_ page-name]]
+  (let [page-name (util/page-name-sanity-lc page-name)]
+    (when-let [page (db/get-page page-name)]
+      (p/do!
+       (db-async/<get-block (state/get-current-repo) (:db/id page))
+       (when (db/page-empty? (state/get-current-repo) page-name)
+         (when-let [template (state/get-default-journal-template)]
+           (editor-handler/insert-template!
+            nil
+            template
+            {:target page})))))))

+ 56 - 0
src/main/frontend/handler/file_based/page.cljs

@@ -0,0 +1,56 @@
+(ns ^:no-doc frontend.handler.file-based.page
+  (:require [clojure.string :as string]
+            [frontend.config :as config]
+            [frontend.date :as date]
+            [frontend.db :as db]
+            [frontend.db.model :as model]
+            [frontend.handler.common.page :as page-common-handler]
+            [frontend.mobile.util :as mobile-util]
+            [frontend.state :as state]
+            [frontend.util :as util]
+            [logseq.common.util :as common-util]
+            [logseq.common.util.page-ref :as page-ref]))
+
+;; FIXME: add whiteboard
+(defn- get-directory
+  [journal?]
+  (if journal?
+    (config/get-journals-directory)
+    (config/get-pages-directory)))
+
+(defn- get-file-name
+  [journal? title]
+  (when-let [s (if journal?
+                 (date/journal-title->default title)
+                 ;; legacy in org-mode format, don't escape slashes except bug reported
+                 (common-util/page-name-sanity (string/lower-case title)))]
+    ;; Win10 file path has a length limit of 260 chars
+    (common-util/safe-subs s 0 200)))
+
+(defn get-page-ref-text
+  [page]
+  (let [edit-block-file-path (model/get-block-file-path (state/get-edit-block))
+        page-name (string/lower-case page)]
+    (if (and edit-block-file-path
+             (state/org-mode-file-link? (state/get-current-repo)))
+      (if-let [ref-file-path (:file/path (db/get-page-file page-name))]
+        (util/format "[[file:%s][%s]]"
+                     (util/get-relative-path edit-block-file-path ref-file-path)
+                     page)
+        (let [journal? (date/valid-journal-title? page)
+              ref-file-path (str
+                             (if (or (util/electron?) (mobile-util/native-platform?))
+                               (-> (config/get-repo-dir (state/get-current-repo))
+                                   js/decodeURI
+                                   (string/replace #"/+$" "")
+                                   (str "/"))
+                               "")
+                             (get-directory journal?)
+                             "/"
+                             (get-file-name journal? page)
+                             ".org")]
+          (page-common-handler/<create! page {:redirect? false})
+          (util/format "[[file:%s][%s]]"
+                       (util/get-relative-path edit-block-file-path ref-file-path)
+                       page)))
+      (page-ref/->page-ref page))))

+ 10 - 45
src/main/frontend/handler/page.cljs

@@ -18,6 +18,7 @@
             [frontend.handler.db-based.property :as db-property-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.file-based.nfs :as nfs-handler]
+            [frontend.handler.file-based.page :as file-page-handler]
             [frontend.handler.file-based.page-property :as file-page-property]
             [frontend.handler.graph :as graph-handler]
             [frontend.handler.notification :as notification]
@@ -92,22 +93,6 @@
                               (distinct))]
           (keep (fn [page-name] (db/get-page page-name)) page-names))))))
 
-;; FIXME: add whiteboard
-(defn- get-directory
-  [journal?]
-  (if journal?
-    (config/get-journals-directory)
-    (config/get-pages-directory)))
-
-(defn- get-file-name
-  [journal? title]
-  (when-let [s (if journal?
-                 (date/journal-title->default title)
-                 ;; legacy in org-mode format, don't escape slashes except bug reported
-                 (common-util/page-name-sanity (string/lower-case title)))]
-    ;; Win10 file path has a length limit of 260 chars
-    (common-util/safe-subs s 0 200)))
-
 (defn toggle-favorite! []
   ;; NOTE: in journals or settings, current-page is nil
   (when-let [page-name (state/get-current-page)]
@@ -159,31 +144,9 @@
 
 (defn get-page-ref-text
   [page]
-  (let [edit-block-file-path (model/get-block-file-path (state/get-edit-block))
-        page-name (string/lower-case page)]
-    (if (and edit-block-file-path
-             (state/org-mode-file-link? (state/get-current-repo)))
-      (if-let [ref-file-path (:file/path (db/get-page-file page-name))]
-        (util/format "[[file:%s][%s]]"
-                     (util/get-relative-path edit-block-file-path ref-file-path)
-                     page)
-        (let [journal? (date/valid-journal-title? page)
-              ref-file-path (str
-                             (if (or (util/electron?) (mobile-util/native-platform?))
-                               (-> (config/get-repo-dir (state/get-current-repo))
-                                   js/decodeURI
-                                   (string/replace #"/+$" "")
-                                   (str "/"))
-                               "")
-                             (get-directory journal?)
-                             "/"
-                             (get-file-name journal? page)
-                             ".org")]
-          (<create! page {:redirect? false})
-          (util/format "[[file:%s][%s]]"
-                       (util/get-relative-path edit-block-file-path ref-file-path)
-                       page)))
-      (page-ref/->page-ref page))))
+  (if (config/db-based-graph?)
+    (page-ref/->page-ref page)
+    (file-page-handler/get-page-ref-text page)))
 
 (defn init-commands!
   []
@@ -366,18 +329,20 @@
         (let [title (date/today)
               today-page (util/page-name-sanity-lc title)
               format (state/get-preferred-format repo)
-              template (state/get-default-journal-template)
+              db-based? (config/db-based-graph? repo)
               create-f (fn []
                          (p/do!
                           (<create! title {:redirect? false
                                            :split-namespace? false
-                                           :create-first-block? (not template)
+                                           :create-first-block? (if db-based?
+                                                                  true
+                                                                  (not (state/get-default-journal-template)))
                                            :today-journal? true})
-                          (state/pub-event! [:journal/insert-template today-page])
+                          (when-not db-based? (state/pub-event! [:journal/insert-template today-page]))
                           (ui-handler/re-render-root!)
                           (plugin-handler/hook-plugin-app :today-journal-created {:title today-page})))]
           (when (db/page-empty? repo today-page)
-            (if (config/db-based-graph? repo)
+            (if db-based?
               (when-not (model/get-journal-page title)
                 (create-f))
               (p/let [file-name (date/journal-title->default title)

+ 82 - 65
src/main/frontend/worker/db/migrate.cljs

@@ -113,11 +113,16 @@
   [db props-to-rename]
   (let [property-tx (map
                      (fn [[old new]]
-                       (merge {:db/id (:db/id (d/entity db old))
-                               :db/ident new}
-                              (when-let [new-title (get-in db-property/built-in-properties [new :title])]
-                                {:block/title new-title
-                                 :block/name (common-util/page-name-sanity-lc new-title)})))
+                       (let [e-new (d/entity db new)
+                             e-old (d/entity db old)]
+                         (if e-new
+                           (when e-old
+                             [:db/retractEntity (:db/id e-old)])
+                           (merge {:db/id (:db/id (d/entity db old))
+                                   :db/ident new}
+                                  (when-let [new-title (get-in db-property/built-in-properties [new :title])]
+                                    {:block/title new-title
+                                     :block/name (common-util/page-name-sanity-lc new-title)})))))
                      props-to-rename)
         titles-tx (->> (d/datoms db :avet :block/title)
                        (keep (fn [d]
@@ -127,32 +132,34 @@
                                    [:db/add (:e d) :block/title title'])))))
         sorting-tx (->> (d/datoms db :avet :logseq.property.table/sorting)
                         (keep (fn [d]
-                                (when-let [props (seq (filter (fn [[old _new]]
-                                                                (some (fn [item] (= old (:id item))) (:v d))) props-to-rename))]
-                                  (let [value (reduce
-                                               (fn [sorting [old new]]
-                                                 (mapv
-                                                  (fn [item]
-                                                    (if (= old (:id item))
-                                                      (assoc item :id new)
-                                                      item))
-                                                  sorting))
-                                               (:v d)
-                                               props)]
-                                    [:db/add (:e d) :logseq.property.table/sorting value])))))
+                                (when (coll? (:v d))
+                                  (when-let [props (seq (filter (fn [[old _new]]
+                                                                  (some (fn [item] (= old (:id item))) (:v d))) props-to-rename))]
+                                    (let [value (reduce
+                                                 (fn [sorting [old new]]
+                                                   (mapv
+                                                    (fn [item]
+                                                      (if (= old (:id item))
+                                                        (assoc item :id new)
+                                                        item))
+                                                    sorting))
+                                                 (:v d)
+                                                 props)]
+                                      [:db/add (:e d) :logseq.property.table/sorting value]))))))
         sized-columns-tx (->> (d/datoms db :avet :logseq.property.table/sized-columns)
                               (keep (fn [d]
-                                      (when-let [props (seq (filter (fn [[old _new]] (get (:v d) old)) props-to-rename))]
-                                        (let [value (reduce
-                                                     (fn [sizes [old new]]
-                                                       (if-let [size (get sizes old)]
-                                                         (-> sizes
-                                                             (dissoc old)
-                                                             (assoc new size))
-                                                         sizes))
-                                                     (:v d)
-                                                     props)]
-                                          [:db/add (:e d) :logseq.property.table/sized-columns value])))))
+                                      (when (map? (:v d))
+                                        (when-let [props (seq (filter (fn [[old _new]] (get (:v d) old)) props-to-rename))]
+                                          (let [value (reduce
+                                                       (fn [sizes [old new]]
+                                                         (if-let [size (get sizes old)]
+                                                           (-> sizes
+                                                               (dissoc old)
+                                                               (assoc new size))
+                                                           sizes))
+                                                       (:v d)
+                                                       props)]
+                                            [:db/add (:e d) :logseq.property.table/sized-columns value]))))))
         hidden-columns-tx (mapcat
                            (fn [[old new]]
                              (->> (d/datoms db :avet :logseq.property.table/hidden-columns old)
@@ -162,31 +169,33 @@
                            props-to-rename)
         ordered-columns-tx (->> (d/datoms db :avet :logseq.property.table/ordered-columns)
                                 (keep (fn [d]
-                                        (when-let [props (seq (filter (fn [[old _new]] ((set (:v d)) old)) props-to-rename))]
-                                          (let [value (reduce
-                                                       (fn [col [old new]]
-                                                         (mapv (fn [v] (if (= old v) new v)) col))
-                                                       (:v d)
-                                                       props)]
-                                            [:db/add (:e d) :logseq.property.table/ordered-columns value])))))
+                                        (when (coll? (:v d))
+                                          (when-let [props (seq (filter (fn [[old _new]] ((set (:v d)) old)) props-to-rename))]
+                                            (let [value (reduce
+                                                         (fn [col [old new]]
+                                                           (mapv (fn [v] (if (= old v) new v)) col))
+                                                         (:v d)
+                                                         props)]
+                                              [:db/add (:e d) :logseq.property.table/ordered-columns value]))))))
         filters-tx (->> (d/datoms db :avet :logseq.property.table/filters)
                         (keep (fn [d]
                                 (let [filters (:filters (:v d))]
-                                  (when-let [props (seq (filter (fn [[old _new]]
-                                                                  (some (fn [item] (and (vector? item)
-                                                                                        (= old (first item)))) filters)) props-to-rename))]
-                                    (let [value (update (:v d) :filters
-                                                        (fn [col]
-                                                          (reduce
-                                                           (fn [col [old new]]
-                                                             (mapv (fn [item]
-                                                                     (if (and (vector? item) (= old (first item)))
-                                                                       (vec (cons new (rest item)))
-                                                                       item))
-                                                                   col))
-                                                           col
-                                                           props)))]
-                                      [:db/add (:e d) :logseq.property.table/filters value]))))))]
+                                  (when (coll? filters)
+                                    (when-let [props (seq (filter (fn [[old _new]]
+                                                                    (some (fn [item] (and (vector? item)
+                                                                                          (= old (first item)))) filters)) props-to-rename))]
+                                      (let [value (update (:v d) :filters
+                                                          (fn [col]
+                                                            (reduce
+                                                             (fn [col [old new]]
+                                                               (mapv (fn [item]
+                                                                       (if (and (vector? item) (= old (first item)))
+                                                                         (vec (cons new (rest item)))
+                                                                         item))
+                                                                     col))
+                                                             col
+                                                             props)))]
+                                        [:db/add (:e d) :logseq.property.table/filters value])))))))]
     (concat property-tx
             titles-tx
             sorting-tx
@@ -801,8 +810,13 @@
                       :logseq.task/priority.high :logseq.property/priority.high
                       :logseq.task/priority.urgent :logseq.property/priority.urgent}
           closed-values-tx (mapv (fn [[old new]]
-                                   {:db/id (:db/id (d/entity @conn old))
-                                    :db/ident new})
+                                   (let [e-new (d/entity @conn new)
+                                         e-old (d/entity @conn old)]
+                                     (if e-new
+                                       (when e-old
+                                         [:db/retractEntity (:db/id e-old)])
+                                       {:db/id (:db/id (d/entity @conn old))
+                                        :db/ident new})))
                                  new-idents)
           filters-tx (->> (d/datoms db :avet :logseq.property.table/filters)
                           (keep (fn [d]
@@ -814,18 +828,21 @@
                                                           (fn [col]
                                                             (reduce
                                                              (fn [col property]
-                                                               (mapv (fn [item]
-                                                                       (if (and (vector? item) (= property (first item)))
-                                                                         (let [[p o v] item
-                                                                               f (fn [id]
-                                                                                   (let [new-ident (get new-idents (:db/ident (d/entity db [:block/uuid id])))]
-                                                                                     (common-uuid/gen-uuid :db-ident-block-uuid new-ident)))
-                                                                               v' (if (set? v)
-                                                                                    (set (map f v))
-                                                                                    (f v))]
-                                                                           [p o v'])
-                                                                         item))
-                                                                     col))
+                                                               (vec
+                                                                (keep (fn [item]
+                                                                        (if (and (vector? item) (= property (first item)))
+                                                                          (let [[p o v] item
+                                                                                f (fn [id]
+                                                                                    (when-let [new-ident (get new-idents (:db/ident (d/entity db [:block/uuid id])))]
+                                                                                      (common-uuid/gen-uuid :db-ident-block-uuid new-ident)))
+                                                                                v' (if (set? v)
+                                                                                     (when-let [v' (seq (keep f v))]
+                                                                                       (set v'))
+                                                                                     (f v))]
+                                                                            (when v'
+                                                                              [p o v']))
+                                                                          item))
+                                                                      col)))
                                                              col
                                                              [:logseq.task/status :logseq.task/priority])))]
                                         [:db/add (:e d) :logseq.property.table/filters value]))))))]

+ 7 - 5
src/main/frontend/worker/db_worker.cljs

@@ -365,11 +365,13 @@
 
           (db-migrate/migrate conn search-db)
 
-          (catch :default _e
-            (log/error "DB migrate failed, retrying")
-            (when db-based?
-              (rebuild-db-from-datoms! conn db import-type)
-              (db-migrate/migrate conn search-db))))
+          (catch :default e
+            (log/error "DB migrate failed, error: " e)
+            (if (and db-based? (= (.-message e) "DB missing addresses"))
+              (do
+                (rebuild-db-from-datoms! conn db import-type)
+                (db-migrate/migrate conn search-db))
+              (throw e))))
 
         (db-listener/listen-db-changes! repo (get @*datascript-conns repo))))))
 

+ 1 - 2
src/main/frontend/worker/rtc/client.cljs

@@ -165,8 +165,7 @@
      (fn [a]
        (when-let [ns (namespace a)]
          (and
-          (or (= "logseq.task" ns)
-              (string/starts-with? ns "logseq.property")
+          (or (string/starts-with? ns "logseq.property")
               (string/ends-with? ns ".property"))
           (= :db.cardinality/one (:db/cardinality (db-schema a)))))) a-coll)))
 

Some files were not shown because too many files changed in this diff