瀏覽代碼

Merge branch 'feat/db' of https://github.com/logseq/logseq into feat/db

Konstantinos Kaloutas 1 年之前
父節點
當前提交
9b63936aa7
共有 40 個文件被更改,包括 670 次插入283 次删除
  1. 13 0
      deps/common/src/logseq/common/marker.cljs
  2. 1 0
      deps/db/.carve/config.edn
  3. 0 2
      deps/db/.carve/ignore
  4. 1 1
      deps/db/package.json
  5. 7 6
      deps/db/src/logseq/db.cljs
  6. 13 0
      deps/db/src/logseq/db/frontend/content.cljs
  7. 1 2
      deps/db/src/logseq/db/frontend/schema.cljs
  8. 6 6
      deps/db/yarn.lock
  9. 2 2
      deps/graph-parser/package.json
  10. 10 10
      deps/graph-parser/yarn.lock
  11. 2 1
      deps/outliner/package.json
  12. 50 2
      deps/outliner/src/logseq/outliner/core.cljs
  13. 1 0
      deps/outliner/src/logseq/outliner/transaction.cljc
  14. 347 6
      deps/outliner/yarn.lock
  15. 1 1
      deps/publishing/package.json
  16. 20 19
      deps/publishing/src/logseq/publishing/db.cljs
  17. 4 4
      deps/publishing/yarn.lock
  18. 0 10
      resources/js/tabler.ext.js
  19. 2 2
      scripts/package.json
  20. 2 0
      scripts/src/logseq/tasks/lang.clj
  21. 10 10
      scripts/yarn.lock
  22. 1 2
      src/main/frontend/common.css
  23. 6 5
      src/main/frontend/components/block.cljs
  24. 3 3
      src/main/frontend/components/block.css
  25. 6 5
      src/main/frontend/components/content.cljs
  26. 69 108
      src/main/frontend/components/db_based/page.cljs
  27. 1 1
      src/main/frontend/components/page.cljs
  28. 4 0
      src/main/frontend/components/page.css
  29. 8 1
      src/main/frontend/components/property.cljs
  30. 1 1
      src/main/frontend/components/property.css
  31. 1 2
      src/main/frontend/db/conn.cljs
  32. 11 4
      src/main/frontend/db_worker.cljs
  33. 0 20
      src/main/frontend/handler/db_based/status.cljs
  34. 21 20
      src/main/frontend/handler/editor.cljs
  35. 9 8
      src/main/frontend/handler/export/common.cljs
  36. 3 5
      src/main/frontend/handler/file_based/status.cljs
  37. 4 3
      src/main/frontend/persist_db/browser.cljs
  38. 15 2
      src/main/frontend/worker/rtc/core.cljs
  39. 5 4
      src/main/frontend/worker/rtc/full_upload_download_graph.cljs
  40. 9 5
      src/test/frontend/worker/rtc/asset_sync_effects_test.cljs

+ 13 - 0
deps/common/src/logseq/common/marker.cljs

@@ -0,0 +1,13 @@
+(ns logseq.common.marker
+  "marker patterns"
+  (:require [clojure.string :as string]))
+
+(defn marker-pattern [format]
+  (re-pattern
+   (str "^" (if (= format :markdown) "(#+\\s+)?" "(\\*+\\s+)?")
+        "(NOW|LATER|TODO|DOING|DONE|WAITING|WAIT|CANCELED|CANCELLED|IN-PROGRESS)?\\s?")))
+
+
+(defn clean-marker
+  [content format]
+  (string/replace-first content (marker-pattern format) ""))

+ 1 - 0
deps/db/.carve/config.edn

@@ -6,6 +6,7 @@
                   logseq.db.sqlite.cli
                   logseq.db.frontend.property
                   logseq.db.frontend.property.util
+                  logseq.db.frontend.content
                   logseq.db.sqlite.create-graph
                   logseq.db.frontend.malli-schema
                   ;; Some fns are used by frontend but not worth moving over yet

+ 0 - 2
deps/db/.carve/ignore

@@ -8,5 +8,3 @@ logseq.db.frontend.rules/extract-rules
 logseq.db.frontend.property.type/type-or-closed-value?
 ;; Internal API
 logseq.db.frontend.rules/rules
-;; API
-logseq.db.frontend.content/special-id-ref->page

+ 1 - 1
deps/db/package.json

@@ -6,7 +6,7 @@
     "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v8"
   },
   "dependencies": {
-    "better-sqlite3": "8.0.1"
+    "better-sqlite3": "9.3.0"
   },
   "scripts": {
     "test": "yarn nbb-logseq -cp test -m nextjournal.test-runner"

+ 7 - 6
deps/db/src/logseq/db.cljs

@@ -71,9 +71,10 @@
                  (callback)))))
 
 (defn transact!
-  ([conn tx-data]
-   (transact! conn tx-data nil))
-  ([conn tx-data tx-meta]
+  "`repo-or-conn`: repo for UI thread and conn for worker/node"
+  ([repo-or-conn tx-data]
+   (transact! repo-or-conn tx-data nil))
+  ([repo-or-conn tx-data tx-meta]
    (let [tx-data (->> (common-util/fast-remove-nils tx-data)
                       (remove empty?))
          request-finished? (request-finished?)]
@@ -91,14 +92,14 @@
                         (not sync?)
                         (assoc :request-id request-id))]
          (if sync?
-           (f conn tx-data tx-meta')
+           (f repo-or-conn tx-data tx-meta')
            (let [resp (p/deferred)]
              (when request-finished?
-               (f conn tx-data tx-meta'))
+               (f repo-or-conn tx-data tx-meta'))
              (let [value (if request-finished?
                            {:response resp}
                            {:response resp
-                            :callback #(f conn tx-data tx-meta')})]
+                            :callback #(f repo-or-conn tx-data tx-meta')})]
                (swap! *request-id->response assoc request-id value))
              resp)))))))
 

+ 13 - 0
deps/db/src/logseq/db/frontend/content.cljs

@@ -43,3 +43,16 @@
         (assoc item :block/content (special-id->page content refs)))
       item)
     item))
+
+(defn content-without-tags
+  "Remove tags from content"
+  [content tags]
+  (->
+   (reduce
+    (fn [content tag]
+      (-> content
+          (string/replace (str "#" tag) "")
+          (string/replace (str "#" page-ref/left-brackets tag page-ref/right-brackets) "")))
+    content
+    tags)
+   (string/trim)))

+ 1 - 2
deps/db/src/logseq/db/frontend/schema.cljs

@@ -150,8 +150,7 @@
 
 ;; If only block/content changes
 (def db-version-retract-attributes
-  #{:block/tags
-    :block/refs
+  #{:block/refs
     :block/marker
     :block/priority
     :block/scheduled

+ 6 - 6
deps/db/yarn.lock

@@ -13,13 +13,13 @@ base64-js@^1.3.1:
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
 
-better-sqlite3@8.0.1:
-  version "8.0.1"
-  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.0.1.tgz#3a596d21fbcefadf36f94e126c5cf24d5697d0b8"
-  integrity sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==
+better-sqlite3@9.3.0:
+  version "9.3.0"
+  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.3.0.tgz#2a8aaad65fa0210a4df5e8a0bcbc9156f6138d56"
+  integrity sha512-ww73jVpQhRRdS9uMr761ixlkl4bWoXi8hMQlBGhoN6vPNlUHpIsNmw4pKN6kjknlt/wopdvXHvLk1W75BI+n0Q==
   dependencies:
     bindings "^1.5.0"
-    prebuild-install "^7.1.0"
+    prebuild-install "^7.1.1"
 
 bindings@^1.5.0:
   version "1.5.0"
@@ -155,7 +155,7 @@ once@^1.3.1, once@^1.4.0:
   dependencies:
     wrappy "1"
 
-prebuild-install@^7.1.0:
+prebuild-install@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
   integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==

+ 2 - 2
deps/graph-parser/package.json

@@ -4,10 +4,10 @@
   "private": true,
   "devDependencies": {
     "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v8",
-    "better-sqlite3": "8.0.1"
+    "better-sqlite3": "9.3.0"
   },
   "dependencies": {
-    "mldoc": "^1.5.1"
+    "mldoc": "^1.5.8"
   },
   "scripts": {
     "test": "nbb-logseq -cp test -m nextjournal.test-runner"

+ 10 - 10
deps/graph-parser/yarn.lock

@@ -23,13 +23,13 @@ base64-js@^1.3.1:
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
 
-better-sqlite3@8.0.1:
-  version "8.0.1"
-  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.0.1.tgz#3a596d21fbcefadf36f94e126c5cf24d5697d0b8"
-  integrity sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==
+better-sqlite3@9.3.0:
+  version "9.3.0"
+  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.3.0.tgz#2a8aaad65fa0210a4df5e8a0bcbc9156f6138d56"
+  integrity sha512-ww73jVpQhRRdS9uMr761ixlkl4bWoXi8hMQlBGhoN6vPNlUHpIsNmw4pKN6kjknlt/wopdvXHvLk1W75BI+n0Q==
   dependencies:
     bindings "^1.5.0"
-    prebuild-install "^7.1.0"
+    prebuild-install "^7.1.1"
 
 bindings@^1.5.0:
   version "1.5.0"
@@ -276,10 +276,10 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
   resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
   integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
 
-mldoc@^1.5.1:
-  version "1.5.3"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.3.tgz#98d5bb276ac6908d72e1c58c27916e488ef9d395"
-  integrity sha512-hkI3PtjBHhbZqTr1U5/A8TIrIzg9DGZzCMLrfzePAdM+97GNeZijmPqUQXWEAyEQsDPnkipMoQZsBXxhnwzfJA==
+mldoc@^1.5.8:
+  version "1.5.8"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.8.tgz#5433950c9124f8917075bafa4f1ed886959504c5"
+  integrity sha512-wNUGgwdgB/5c3GTp2qRPzWD8CpeTmA/HDlGJjTJUo2WXJttiBaz8cHQh2OdAshiLdVxteqIaSTXSPFRf7z1YRw==
   dependencies:
     yargs "^12.0.2"
 
@@ -372,7 +372,7 @@ path-key@^2.0.0, path-key@^2.0.1:
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
   integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
 
-prebuild-install@^7.1.0:
+prebuild-install@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
   integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==

+ 2 - 1
deps/outliner/package.json

@@ -6,7 +6,8 @@
     "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v8"
   },
   "dependencies": {
-    "better-sqlite3": "8.0.1"
+    "better-sqlite3": "9.3.0",
+    "mldoc": "^1.5.8"
   },
   "scripts": {
     "test": "yarn nbb-logseq -cp test -m nextjournal.test-runner"

+ 50 - 2
deps/outliner/src/logseq/outliner/core.cljs

@@ -16,7 +16,9 @@
             [logseq.graph-parser.property :as gp-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.sqlite.util :as sqlite-util]
-            [cljs.pprint :as pprint]))
+            [cljs.pprint :as pprint]
+            [logseq.db.frontend.content :as db-content]
+            [logseq.common.marker :as common-marker]))
 
 (def ^:private block-map
   (mu/optional-keys
@@ -256,6 +258,36 @@
 ;; -get-id, -get-parent-id, -get-left-id return block-id
 ;; the :block/parent, :block/left should be datascript lookup ref
 
+;; TODO: don't parse marker and deprecate typing marker to set status
+(defn- db-marker-handle
+  [conn m]
+  (or
+   (let [marker (:block/marker m)
+         property (db-property/get-property @conn "status")
+         matched-status-id (when marker
+                             (->> (get-in property [:block/schema :values])
+                                 (some (fn [id]
+                                         (let [value-e (d/entity @conn [:block/uuid id])
+                                               value (get-in value-e [:block/schema :value])]
+                                           (when (= (string/lower-case marker) (string/lower-case value))
+                                             id))))))]
+     (cond-> m
+       matched-status-id
+       (update :block/properties assoc (:block/uuid property) matched-status-id)
+
+       matched-status-id
+       (update :block/content (fn [content]
+                                (common-marker/clean-marker content (get m :block/format :markdown))))
+       matched-status-id
+       (update :db/other-tx (fn [tx]
+                              (if-let [task (d/entity @conn [:block/name "task"])]
+                                (conj tx [:db/add (:db/id m) :block/tags (:db/id task)])
+                                tx)))
+
+       true
+       (dissoc :block/marker :block/priority)))
+   m))
+
 (extend-type Block
   otree/INode
   (-get-id [this conn]
@@ -318,7 +350,23 @@
           db-id (:db/id (:data this))
           block-uuid (:block/uuid (:data this))
           eid (or db-id (when block-uuid [:block/uuid block-uuid]))
-          block-entity (d/entity db eid)]
+          block-entity (d/entity db eid)
+          m' (if (and (:block/content m) db-based?)
+              (update m :block/content
+                      (fn [content]
+                        (db-content/content-without-tags
+                         content
+                         (->>
+                          (map
+                           (fn [tag]
+                             (when (:block/uuid tag)
+                               (str db-content/page-ref-special-chars (:block/uuid tag))))
+                           (:block/tags m))
+                          (remove nil?)))))
+              m)
+          m (cond->> m'
+              db-based?
+              (db-marker-handle conn))]
 
       ;; Ensure block UUID never changes
       (when (and db-id block-uuid)

+ 1 - 0
deps/outliner/src/logseq/outliner/transaction.cljc

@@ -4,6 +4,7 @@
   #?(:cljs (:require-macros [logseq.outliner.transaction]))
   #?(:cljs (:require [malli.core :as m])))
 
+#_:clj-kondo/ignore
 (def ^:private transact-opts [:or :symbol :map])
 
 #?(:org.babashka/nbb nil

+ 347 - 6
deps/outliner/yarn.lock

@@ -8,18 +8,28 @@
   dependencies:
     import-meta-resolve "^2.1.0"
 
+ansi-regex@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+  integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
+
+ansi-regex@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
+  integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
+
 base64-js@^1.3.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
 
[email protected]:
-  version "8.0.1"
-  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.0.1.tgz#3a596d21fbcefadf36f94e126c5cf24d5697d0b8"
-  integrity sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==
+better-sqlite3@9.3.0:
+  version "9.3.0"
+  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.3.0.tgz#2a8aaad65fa0210a4df5e8a0bcbc9156f6138d56"
+  integrity sha512-ww73jVpQhRRdS9uMr761ixlkl4bWoXi8hMQlBGhoN6vPNlUHpIsNmw4pKN6kjknlt/wopdvXHvLk1W75BI+n0Q==
   dependencies:
     bindings "^1.5.0"
-    prebuild-install "^7.1.0"
+    prebuild-install "^7.1.1"
 
 bindings@^1.5.0:
   version "1.5.0"
@@ -45,11 +55,46 @@ buffer@^5.5.0:
     base64-js "^1.3.1"
     ieee754 "^1.1.13"
 
+camelcase@^5.0.0:
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
+  integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+
 chownr@^1.1.1:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
   integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
 
+cliui@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
+  integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
+  dependencies:
+    string-width "^2.1.1"
+    strip-ansi "^4.0.0"
+    wrap-ansi "^2.0.0"
+
+code-point-at@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+  integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
+
+cross-spawn@^6.0.0:
+  version "6.0.5"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
+  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+  dependencies:
+    nice-try "^1.0.4"
+    path-key "^2.0.1"
+    semver "^5.5.0"
+    shebang-command "^1.2.0"
+    which "^1.2.9"
+
+decamelize@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+  integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+
 decompress-response@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@@ -74,6 +119,19 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
   dependencies:
     once "^1.4.0"
 
+execa@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
+  integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
+  dependencies:
+    cross-spawn "^6.0.0"
+    get-stream "^4.0.0"
+    is-stream "^1.1.0"
+    npm-run-path "^2.0.0"
+    p-finally "^1.0.0"
+    signal-exit "^3.0.0"
+    strip-eof "^1.0.0"
+
 expand-template@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
@@ -84,11 +142,30 @@ [email protected]:
   resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
   integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
 
+find-up@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
+  integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+  dependencies:
+    locate-path "^3.0.0"
+
 fs-constants@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
   integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
 
+get-caller-file@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
+  integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
+
+get-stream@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
+  integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+  dependencies:
+    pump "^3.0.0"
+
 [email protected]:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
@@ -114,6 +191,48 @@ ini@~1.3.0:
   resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
   integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
 
+invert-kv@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
+  integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+
+is-fullwidth-code-point@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+  integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
+  dependencies:
+    number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+  integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
+
+is-stream@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+  integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+lcid@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
+  integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
+  dependencies:
+    invert-kv "^2.0.0"
+
+locate-path@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
+  integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
+  dependencies:
+    p-locate "^3.0.0"
+    path-exists "^3.0.0"
+
 lru-cache@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -121,6 +240,27 @@ lru-cache@^6.0.0:
   dependencies:
     yallist "^4.0.0"
 
+map-age-cleaner@^0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
+  integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
+  dependencies:
+    p-defer "^1.0.0"
+
+mem@^4.0.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
+  integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
+  dependencies:
+    map-age-cleaner "^0.1.1"
+    mimic-fn "^2.0.0"
+    p-is-promise "^2.0.0"
+
+mimic-fn@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
+  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
 mimic-response@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
@@ -136,11 +276,23 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
   resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
   integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
 
+mldoc@^1.5.8:
+  version "1.5.8"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.8.tgz#5433950c9124f8917075bafa4f1ed886959504c5"
+  integrity sha512-wNUGgwdgB/5c3GTp2qRPzWD8CpeTmA/HDlGJjTJUo2WXJttiBaz8cHQh2OdAshiLdVxteqIaSTXSPFRf7z1YRw==
+  dependencies:
+    yargs "^12.0.2"
+
 napi-build-utils@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
   integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
 
+nice-try@^1.0.4:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
+  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
+
 node-abi@^3.3.0:
   version "3.51.0"
   resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d"
@@ -148,6 +300,18 @@ node-abi@^3.3.0:
   dependencies:
     semver "^7.3.5"
 
+npm-run-path@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+  integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
+  dependencies:
+    path-key "^2.0.0"
+
+number-is-nan@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+  integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
+
 once@^1.3.1, once@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -155,7 +319,60 @@ once@^1.3.1, once@^1.4.0:
   dependencies:
     wrappy "1"
 
-prebuild-install@^7.1.0:
+os-locale@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
+  integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+  dependencies:
+    execa "^1.0.0"
+    lcid "^2.0.0"
+    mem "^4.0.0"
+
+p-defer@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
+  integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==
+
+p-finally@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
+
+p-is-promise@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
+  integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
+
+p-limit@^2.0.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+  integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+  dependencies:
+    p-try "^2.0.0"
+
+p-locate@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
+  integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
+  dependencies:
+    p-limit "^2.0.0"
+
+p-try@^2.0.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+  integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+path-exists@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
+  integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
+
+path-key@^2.0.0, path-key@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
+  integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
+
+prebuild-install@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
   integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==
@@ -200,11 +417,26 @@ readable-stream@^3.1.1, readable-stream@^3.4.0:
     string_decoder "^1.1.1"
     util-deprecate "^1.0.1"
 
+require-directory@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+  integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+require-main-filename@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+  integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
+
 safe-buffer@^5.0.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==
 
+semver@^5.5.0:
+  version "5.7.2"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+  integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+
 semver@^7.3.5:
   version "7.5.4"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
@@ -212,6 +444,28 @@ semver@^7.3.5:
   dependencies:
     lru-cache "^6.0.0"
 
+set-blocking@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+  integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
+
+shebang-command@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+  integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
+  dependencies:
+    shebang-regex "^1.0.0"
+
+shebang-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+  integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
+
+signal-exit@^3.0.0:
+  version "3.0.7"
+  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+  integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
 simple-concat@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
@@ -226,6 +480,23 @@ simple-get@^4.0.0:
     once "^1.3.1"
     simple-concat "^1.0.0"
 
+string-width@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+  integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
+  dependencies:
+    code-point-at "^1.0.0"
+    is-fullwidth-code-point "^1.0.0"
+    strip-ansi "^3.0.0"
+
+string-width@^2.0.0, string-width@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
+  integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
+  dependencies:
+    is-fullwidth-code-point "^2.0.0"
+    strip-ansi "^4.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"
@@ -233,6 +504,25 @@ string_decoder@^1.1.1:
   dependencies:
     safe-buffer "~5.2.0"
 
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+  integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
+  dependencies:
+    ansi-regex "^2.0.0"
+
+strip-ansi@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
+  integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
+  dependencies:
+    ansi-regex "^3.0.0"
+
+strip-eof@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
+  integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
+
 strip-json-comments@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -271,12 +561,63 @@ util-deprecate@^1.0.1:
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
   integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
 
+which-module@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409"
+  integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==
+
+which@^1.2.9:
+  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"
+
+wrap-ansi@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+  integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
+  dependencies:
+    string-width "^1.0.1"
+    strip-ansi "^3.0.1"
+
 wrappy@1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
 
+"y18n@^3.2.1 || ^4.0.0":
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
+  integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
+
 yallist@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yargs-parser@^11.1.1:
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
+  integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
+  dependencies:
+    camelcase "^5.0.0"
+    decamelize "^1.2.0"
+
+yargs@^12.0.2:
+  version "12.0.5"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
+  integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
+  dependencies:
+    cliui "^4.0.0"
+    decamelize "^1.2.0"
+    find-up "^3.0.0"
+    get-caller-file "^1.0.1"
+    os-locale "^3.0.0"
+    require-directory "^2.1.1"
+    require-main-filename "^1.0.1"
+    set-blocking "^2.0.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
+    y18n "^3.2.1 || ^4.0.0"
+    yargs-parser "^11.1.1"

+ 1 - 1
deps/publishing/package.json

@@ -4,7 +4,7 @@
   "private": true,
   "devDependencies": {
     "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v8",
-    "mldoc": "^1.5.1"
+    "mldoc": "^1.5.8"
   },
   "dependencies": {
     "fs-extra": "9.1.0"

+ 20 - 19
deps/publishing/src/logseq/publishing/db.cljs

@@ -171,22 +171,23 @@
 (defn filter-only-public-pages-and-blocks
   "Prepares a database assuming all pages are private unless a page has a 'public:: true'"
   [db {:keys [db-graph?]}]
-  (when-let [public-pages* (seq (if db-graph? (get-db-public-pages db) (get-public-pages db)))]
-    (let [public-pages (set/union (set public-pages*)
-                                  (get-aliases-for-page-ids db public-pages*))
-          exported-namespace? #(contains? #{"block" "recent"} %)
-          filtered-db (d/filter db
-                                (fn [db datom]
-                                  (let [ns (namespace (:a datom))]
-                                    (and
-                                     (not (contains? #{:block/file} (:a datom)))
-                                     (not= ns "file")
-                                     (or
-                                      (not (exported-namespace? ns))
-                                      (and (= ns "block")
-                                           (or
-                                            (contains? public-pages (:e datom))
-                                            (contains? public-pages (:db/id (:block/page (d/entity db (:e datom))))))))))))
-          datoms (d/datoms filtered-db :eavt)
-          assets (get-assets db datoms)]
-      [@(d/conn-from-datoms datoms (:schema db)) assets])))
+  {:post [(some? %) (sequential? %)]}
+  (let [public-pages* (seq (if db-graph? (get-db-public-pages db) (get-public-pages db)))
+        public-pages (set/union (set public-pages*)
+                                (get-aliases-for-page-ids db public-pages*))
+        exported-namespace? #(contains? #{"block" "recent"} %)
+        filtered-db (d/filter db
+                              (fn [db datom]
+                                (let [ns (namespace (:a datom))]
+                                  (and
+                                   (not (contains? #{:block/file} (:a datom)))
+                                   (not= ns "file")
+                                   (or
+                                    (not (exported-namespace? ns))
+                                    (and (= ns "block")
+                                         (or
+                                          (contains? public-pages (:e datom))
+                                          (contains? public-pages (:db/id (:block/page (d/entity db (:e datom))))))))))))
+        datoms (d/datoms filtered-db :eavt)
+        assets (get-assets db datoms)]
+    [@(d/conn-from-datoms datoms (:schema db)) assets]))

+ 4 - 4
deps/publishing/yarn.lock

@@ -189,10 +189,10 @@ mimic-fn@^2.0.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 
-mldoc@^1.5.1:
-  version "1.5.3"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.3.tgz#98d5bb276ac6908d72e1c58c27916e488ef9d395"
-  integrity sha512-hkI3PtjBHhbZqTr1U5/A8TIrIzg9DGZzCMLrfzePAdM+97GNeZijmPqUQXWEAyEQsDPnkipMoQZsBXxhnwzfJA==
+mldoc@^1.5.8:
+  version "1.5.8"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.8.tgz#5433950c9124f8917075bafa4f1ed886959504c5"
+  integrity sha512-wNUGgwdgB/5c3GTp2qRPzWD8CpeTmA/HDlGJjTJUo2WXJttiBaz8cHQh2OdAshiLdVxteqIaSTXSPFRf7z1YRw==
   dependencies:
     yargs "^12.0.2"
 

文件差異過大導致無法顯示
+ 0 - 10
resources/js/tabler.ext.js


+ 2 - 2
scripts/package.json

@@ -6,8 +6,8 @@
     "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v8"
   },
   "dependencies": {
-    "better-sqlite3": "8.0.1",
+    "better-sqlite3": "9.3.0",
     "fs-extra": "9.1.0",
-    "mldoc": "^1.5.1"
+    "mldoc": "^1.5.8"
   }
 }

+ 2 - 0
scripts/src/logseq/tasks/lang.clj

@@ -139,6 +139,8 @@
                           (map #(keyword (subs % 4)))
                           (concat (mapcat val manual-ui-dicts))
                           (concat (whiteboard-dicts))
+                          ;; Temporarily unused as they will be brought back soon
+                          (concat [:download])
                           set)
         expected-dicts (set (remove #(re-find #"^(command|shortcut)\." (str (namespace %)))
                                     (keys (:en (get-dicts)))))

+ 10 - 10
scripts/yarn.lock

@@ -28,13 +28,13 @@ base64-js@^1.3.1:
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
 
-better-sqlite3@8.0.1:
-  version "8.0.1"
-  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.0.1.tgz#3a596d21fbcefadf36f94e126c5cf24d5697d0b8"
-  integrity sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==
+better-sqlite3@9.3.0:
+  version "9.3.0"
+  resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.3.0.tgz#2a8aaad65fa0210a4df5e8a0bcbc9156f6138d56"
+  integrity sha512-ww73jVpQhRRdS9uMr761ixlkl4bWoXi8hMQlBGhoN6vPNlUHpIsNmw4pKN6kjknlt/wopdvXHvLk1W75BI+n0Q==
   dependencies:
     bindings "^1.5.0"
-    prebuild-install "^7.1.0"
+    prebuild-install "^7.1.1"
 
 bindings@^1.5.0:
   version "1.5.0"
@@ -305,10 +305,10 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
   resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
   integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
 
-mldoc@^1.5.1:
-  version "1.5.3"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.3.tgz#98d5bb276ac6908d72e1c58c27916e488ef9d395"
-  integrity sha512-hkI3PtjBHhbZqTr1U5/A8TIrIzg9DGZzCMLrfzePAdM+97GNeZijmPqUQXWEAyEQsDPnkipMoQZsBXxhnwzfJA==
+mldoc@^1.5.8:
+  version "1.5.8"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.8.tgz#5433950c9124f8917075bafa4f1ed886959504c5"
+  integrity sha512-wNUGgwdgB/5c3GTp2qRPzWD8CpeTmA/HDlGJjTJUo2WXJttiBaz8cHQh2OdAshiLdVxteqIaSTXSPFRf7z1YRw==
   dependencies:
     yargs "^12.0.2"
 
@@ -401,7 +401,7 @@ path-key@^2.0.0, path-key@^2.0.1:
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
   integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
 
-prebuild-install@^7.1.0:
+prebuild-install@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
   integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==

+ 1 - 2
src/main/frontend/common.css

@@ -679,12 +679,11 @@ img.small {
 }
 
 a.tag {
-  font-size: 0.9em;
+  @apply text-sm;
   text-align: center;
   text-decoration: none;
   display: inline-block;
   cursor: pointer;
-  padding: 0 2px;
   border-radius: 4px;
   color: or(--ls-tag-text, --lx-accent-11, --ls-tag-text-color, #045591);
   opacity: var(--ls-tag-text-opacity, 0.7);

+ 6 - 5
src/main/frontend/components/block.cljs

@@ -2318,7 +2318,7 @@
 (rum/defc tags
   [config block]
   (when (seq (:block/tags block))
-    [:div.flex.flex-row.flex-wrap.items-center.ml-4.gap-1.text-sm
+    [:div.flex.flex-row.flex-wrap.items-center.ml-4.gap-1
      (for [tag (:block/tags block)]
        (page-cp (assoc config
                        :tag? true
@@ -2386,7 +2386,8 @@
          "Large block will not be editable or searchable to not slow down the app, please use another editor to edit this block."])
       [:div.flex.flex-row.justify-between.block-content-inner
        (when-not plugin-slotted?
-         (let [block-tags (:block/tags block)]
+         (let [block-tags (:block/tags block)
+               db-based? (config/db-based-graph? (state/get-current-repo))]
            [:div.flex-1.w-full
             [:div.flex.flex-1.w-full.flex-row.flex-wrap.justify-between.items-center
              (cond
@@ -2402,7 +2403,7 @@
                nil)
 
              [:div.flex.flex-row.items-center.gap-1
-              (when (and (seq block-tags) (:block/name block))
+              (when (and db-based? (seq block-tags))
                 (tags config block))
               (when (and (:original-block config) (not (:block/name block)))
                 [:a.fade-link {:title "Embed block"
@@ -2508,8 +2509,8 @@
                                       :on-hide (fn [value event]
                                                  (let [select? (and (= event :esc)
                                                                       (not (string/includes? value "```")))]
-                                                     (editor-handler/escape-editing select?)
-                                                     (editor-handler/save-block! (editor-handler/get-state) value)))}
+                                                   (p/let [_ (editor-handler/save-block! (editor-handler/get-state) value)]
+                                                     (editor-handler/escape-editing select?))))}
                                      edit-input-id
                                      config))]
           (if (and named? (seq (:block/tags block)) db-based?)

+ 3 - 3
src/main/frontend/components/block.css

@@ -377,9 +377,9 @@
     border-radius: 2px;
   }
 
-  .bullet-container .selected {
-    border: 3px solid;
-  }
+  /* .bullet-container .selected { */
+  /*   border: 3px solid; */
+  /* } */
 }
 
 .ls-block {

+ 6 - 5
src/main/frontend/components/content.cljs

@@ -93,11 +93,12 @@
        :on-click #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
       (t :context-menu/toggle-number-list))
 
-     (ui/menu-link
-      {:key "cycle todos"
-       :on-click editor-handler/cycle-todos!
-       :shortcut (ui/keyboard-shortcut-from-config :editor/cycle-todo)}
-      (t :editor/cycle-todo))
+     (when-not (config/db-based-graph? (state/get-current-repo))
+       (ui/menu-link
+        {:key "cycle todos"
+         :on-click editor-handler/cycle-todos!
+         :shortcut (ui/keyboard-shortcut-from-config :editor/cycle-todo)}
+        (t :editor/cycle-todo)))
 
      [:hr.menu-separator]
 

+ 69 - 108
src/main/frontend/components/db_based/page.cljs

@@ -20,9 +20,8 @@
             [clojure.string :as string]))
 
 (rum/defc page-properties < rum/reactive
-  [page {:keys [configure? mode]}]
+  [page {:keys [mode configure?]}]
   (let [types (:block/type page)
-        class? (contains? types "class")
         property? (contains? types "property")
         edit-input-id-prefix (str "edit-block-" (:block/uuid page))
         configure-opts {:selected? false
@@ -31,63 +30,23 @@
         has-class-properties? (seq (:properties (:block/schema page)))]
     (when (or configure? has-viewable-properties? has-class-properties? property?)
       [:div.ls-page-properties.mb-4
-       (if configure?
-         (cond
-           (and class? has-class-properties? (= :class mode))
-           nil
-
-           (and class? (not has-class-properties?))
+       (cond
+         (= mode :class)
+         (if (and config/publishing? (not configure?))
            (component-block/db-properties-cp {:editor-box editor/box}
                                              page
-                                             (str edit-input-id-prefix "-schema")
-                                             (assoc configure-opts :class-schema? true))
-
-           (not (db-property-handler/block-has-viewable-properties? page))
+                                             (str edit-input-id-prefix "-page")
+                                             (assoc configure-opts :class-schema? false))
            (component-block/db-properties-cp {:editor-box editor/box}
                                              page
-                                             (str edit-input-id-prefix "-page")
-                                             (assoc configure-opts :class-schema? false)))
-         (if config/publishing?
-           [:div.flex.flex-col.gap-4
-            (when has-viewable-properties?
-              [:div
-               (when has-class-properties?
-                 [:div.mb-1.opacity-70.font-medium.text-sm "Page properties:"])
-               (component-block/db-properties-cp {:editor-box editor/box}
-                                                 page
-                                                 (str edit-input-id-prefix "-page")
-                                                 {:selected? false
-                                                  :page-configure? false
-                                                  :class-schema? false})])
-            (when has-class-properties?
-              [:div
-               (when has-viewable-properties?
-                 [:div.mb-1.opacity-70.font-medium.text-sm "Class properties:"])
-               (component-block/db-properties-cp {:editor-box editor/box}
-                                                 page
-                                                 (str edit-input-id-prefix "-schema")
-                                                 (assoc configure-opts :class-schema? true))])]
-
-           [:div.flex.flex-col.gap-4
-            (when has-class-properties?
-              [:div
-               (when has-viewable-properties?
-                 [:div.mb-1.opacity-70.font-medium.text-sm "Class properties:"])
-               (component-block/db-properties-cp {:editor-box editor/box}
-                                                 page
-                                                 (str edit-input-id-prefix "-schema")
-                                                 (assoc configure-opts :class-schema? true))])
+                                             (str edit-input-id-prefix "-schema")
+                                             (assoc configure-opts :class-schema? true)))
 
-            (when has-viewable-properties?
-              [:div
-               (when has-class-properties?
-                 [:div.mb-1.opacity-70.font-medium.text-sm "Page properties:"])
-               (component-block/db-properties-cp {:editor-box editor/box}
-                                                 page
-                                                 (str edit-input-id-prefix "-page")
-                                                 {:selected? false
-                                                  :page-configure? false
-                                                  :class-schema? false})])]))])))
+         (= mode :page)
+         (component-block/db-properties-cp {:editor-box editor/box}
+                                           page
+                                           (str edit-input-id-prefix "-page")
+                                           (assoc configure-opts :class-schema? false)))])))
 
 (rum/defc icon-row < rum/reactive
   [page]
@@ -118,7 +77,8 @@
     (pv/property-value page tags-property
                        (map :block/uuid (:block/tags page))
                        {:page-cp (fn [config page]
-                                   (component-block/page-cp (assoc config :tag? true) page))})))
+                                   (component-block/page-cp (assoc config :tag? true) page))
+                        :inline-text component-block/inline-text})))
 
 (rum/defc tags-row < rum/reactive
   [page]
@@ -148,6 +108,7 @@
           (class-component/configure page {:show-title? false}))
         (when-not config/publishing? (tags-row page))
         (when-not config/publishing? (icon-row page))
+        [:h2 "Properties: "]
         (page-properties page (assoc page-opts :mode mode))])]))
 
 (rum/defc page-properties-react < rum/reactive
@@ -178,76 +139,76 @@
      (for [mode modes]
        (let [mode' (keyword (string/lower-case mode))
              selected? (= mode' current-mode)]
-         (shui-ui/button {:variant (if selected? :outline :ghost) :size :sm
-                          :on-click (if config/publishing?
-                                      util/stop-propagation
-                                      (fn [e]
-                                        (util/stop-propagation e)
-                                        (reset! *mode mode')))}
+         (shui-ui/button {:class (when-not selected? "opacity-70")
+                          :variant (if selected? :outline :ghost) :size :sm
+                          :on-click (fn [e]
+                                      (util/stop-propagation e)
+                                      (reset! *mode mode'))}
                          mode)))]))
 
 (rum/defcs page-info < rum/reactive
   (rum/local false ::hover?)
   (rum/local nil ::mode)
-  {:init (if config/publishing?
-           (fn [state]
-             (let [page* (first (:rum/args state))
-                   page (db/sub-block (:db/id page*))]
-               (assoc state
-                      ::collapsed?
-                      (atom (not (seq (set/intersection #{"class" "property"} (:block/type page))))))))
-           (fn [state]
-             (let [page (first (:rum/args state))
-                   properties (:block/properties page)]
-               (assoc state ::collapsed? (atom (empty? properties))))))}
+  {:init (fn [state]
+           (assoc state ::collapsed? (atom true)))}
   [state page *hover-title?]
   (let [page (db/sub-block (:db/id page))
         *collapsed? (::collapsed? state)
         *hover? (::hover? state)
         *mode (::mode state)
         types (:block/type page)
+        class? (contains? types "class")
         hover-title? (rum/react *hover-title?)
         collapsed? (rum/react *collapsed?)
         has-tags? (seq (:block/tags page))
+        has-properties? (seq (:block/properties page))
         hover-or-expanded? (or @*hover? hover-title? (not collapsed?))]
     (when (if config/publishing?
             ;; Since publishing is read-only, hide this component if it has no info to show
             ;; as it creates a fair amount of empty vertical space
             (or has-tags? (some? types))
             true)
-     [:div.page-info {:on-mouse-over #(reset! *hover? true)
-                      :on-mouse-leave #(reset! *hover? false)}
-      (when (or hover-or-expanded? has-tags?)
-        [:div.fade-in.p-2 (cond-> {}
-                            (or @*hover? (not collapsed?))
-                            (assoc :class "border rounded"))
-         [:div.info-title.cursor {:on-click
-                                  (if config/publishing?
-                                    (fn [_]
-                                      (when (seq (set/intersection #{"class" "empty"} types))
-                                        (swap! *collapsed? not)))
-                                    #(swap! *collapsed? not))}
-          [:div.flex.flex-row.items-center.gap-2.justify-between
-           [:div.flex.flex-row.items-center.gap-2
-            (if collapsed?
-              [:<>
-               (shui-ui/button {:variant :ghost :size :sm :class "fade-link"}
-                               (ui/icon "tags"))
-               [:div {:on-click util/stop-propagation}
-                (tags page)]]
-              [:div.flex.flex-row.items-center.gap-1
-               (shui-ui/button {:variant :ghost :size :sm :class "fade-link"}
-                               (ui/icon "info-circle"))
-               [:a.text-sm.font-medium.fade-link
-                "Configure:"]
-               (mode-switch types *mode)])]
-           (when (or @*hover? (not collapsed?))
-             (shui-ui/button
-              {:variant :ghost :size :sm :class "fade-link"}
-              (ui/icon (if collapsed?
-                         "chevron-down"
-                         "chevron-up"))))]]
-
-         (when-not collapsed?
-           [:div.py-2.px-4
-            (page-configure page *mode)])])])))
+      [:div.page-info {:on-mouse-over #(reset! *hover? true)
+                       :on-mouse-leave #(reset! *hover? false)}
+       (when (or hover-or-expanded? has-tags? has-properties?)
+         [:div.fade-in.p-2 {:class (if (or @*hover? (not collapsed?))
+                                     "border rounded"
+                                     "border rounded border-transparent")}
+          [:div.info-title.cursor {:on-click
+                                   (if config/publishing?
+                                     (fn [_]
+                                       (when (seq (set/intersection #{"class" "property"} types))
+                                         (swap! *collapsed? not)))
+                                     #(swap! *collapsed? not))}
+           [:div.flex.flex-row.items-center.gap-2.justify-between.pl-1
+            [:div.flex.flex-row.items-center.gap-2
+             (if collapsed?
+               (if (or has-tags? @*hover? config/publishing?)
+                 [:<>
+                  (shui-ui/button {:variant :ghost :size :sm :class "fade-link"}
+                                  (ui/icon "tags"))
+                  (if (and config/publishing? (seq (set/intersection #{"class" "property"} types)))
+                    [:div
+                     [:div.opacity-50.pointer.text-sm "Expand for more info"]]
+                    [:div {:on-click util/stop-propagation}
+                     (tags page)])]
+                 [:div.page-info-title-placeholder])
+               [:div.flex.flex-row.items-center.gap-1
+                (shui-ui/button {:variant :ghost :size :sm :class "fade-link"}
+                                (ui/icon "info-circle"))
+                [:a.text-sm.font-medium.fade-link
+                 "Configure:"]
+                (mode-switch types *mode)])]
+            (when (or @*hover? (not collapsed?))
+              (shui-ui/button
+               {:variant :ghost :size :sm :class "fade-link"}
+               (ui/icon (if collapsed?
+                          "chevron-down"
+                          "chevron-up"))))]]
+          (if collapsed?
+            (when (or (seq (:block/properties page))
+                      (and class? (seq (:properties (:block/schema page)))))
+              [:div.py-2.px-4
+               (page-properties page {:mode (if class? :class :page)})])
+            [:div.py-2.px-4
+             (page-configure page *mode)])])])))

+ 1 - 1
src/main/frontend/components/page.cljs

@@ -521,7 +521,7 @@
                     (plugins/hook-ui-slot :page-head-actions-slotted nil)
                     (plugins/hook-ui-items :pagebar)]))])
 
-            (when db-based?
+            (when (and db-based? (not block?))
               [:div.pb-4
                (db-page/page-info page (::hover-title? state))])
 

+ 4 - 0
src/main/frontend/components/page.css

@@ -412,3 +412,7 @@ html.is-native-ios {
     min-height: 46px;
     margin-left: -21px;
 }
+
+.page-info-title-placeholder {
+    min-height: 28px;
+}

+ 8 - 1
src/main/frontend/components/property.cljs

@@ -650,6 +650,7 @@
      (when-not @*hide?
        (properties-section block hidden-properties opts))]))
 
+;; TODO: Remove :page-configure? as it only ever seems to be set to true
 (rum/defcs ^:large-vars/cleanup-todo properties-area < rum/reactive
   [state target-block edit-input-id {:keys [in-block-container? page-configure? class-schema?] :as opts}]
   (let [block (resolve-linked-block-if-exists target-block)
@@ -720,7 +721,13 @@
                    (not (:page-configure? opts)))
       [:div.ls-properties-area (cond-> (if in-block-container?
                                          {}
-                                         {:class [(if class-schema? "class-properties" "page-properties")]})
+                                         {:class [(cond
+                                                    class-schema?
+                                                    "class-properties"
+                                                    (config/db-based-graph? (state/get-current-repo))
+                                                    nil
+                                                    :else
+                                                    "page-properties")]})
                                  (:selected? opts)
                                  (update :class conj "select-none"))
        (properties-section block (if class-schema? properties own-properties) opts)

+ 1 - 1
src/main/frontend/components/property.css

@@ -42,7 +42,7 @@
 }
 
 .ls-properties-area {
-    @apply grid gap-2 pt-1;
+    @apply grid gap-2 py-2;
 
     .property-pair {
         @apply grid grid-cols-5 gap-1;

+ 1 - 2
src/main/frontend/db/conn.cljs

@@ -83,8 +83,7 @@
   ([repo tx-data]
    (transact! repo tx-data nil))
   ([repo tx-data tx-meta]
-   (when-let [conn (get-db repo false)]
-     (ldb/transact! conn tx-data tx-meta))))
+   (ldb/transact! repo tx-data tx-meta)))
 
 (defn start!
   ([repo]

+ 11 - 4
src/main/frontend/db_worker.cljs

@@ -131,7 +131,7 @@
     (when-not (= repo r)
       (close-db-aux! r db search))))
 
-(defn- close-db!
+(defn close-db!
   [repo]
   (let [{:keys [db search]} (@*sqlite-conns repo)]
     (close-db-aux! repo db search)))
@@ -258,8 +258,10 @@
      (bean/->js dbs)))
 
   (createOrOpenDB
-   [_this repo]
-   (p/let [_ (close-other-dbs! repo)]
+   [_this repo & {:keys [close-other-db?]
+                  :or {close-other-db? true}}]
+   (p/let [_ (when close-other-db?
+               (close-other-dbs! repo))]
      (create-or-open-db! repo)))
 
   (getMaxTx
@@ -292,7 +294,8 @@
              tx-meta' (if (:new-graph? tx-meta)
                         tx-meta
                         (cond-> tx-meta
-                          (not (:whiteboard/transact? tx-meta)) ; delay writes to the disk
+                          (and (not (:whiteboard/transact? tx-meta))
+                               (not (:rtc-download-graph? tx-meta))) ; delay writes to the disk
                           (assoc :skip-store? true)
 
                           true
@@ -317,6 +320,10 @@
      (->> (sqlite-common-db/get-initial-data @conn)
           dt/write-transit-str)))
 
+  (closeDB
+   [_this repo]
+   (close-db! repo))
+
   (unsafeUnlinkDB
    [_this repo]
    (p/let [pool (<get-opfs-pool repo)

+ 0 - 20
src/main/frontend/handler/db_based/status.cljs

@@ -1,20 +0,0 @@
-(ns frontend.handler.db-based.status
-  "Task status related util fns"
-  (:require [frontend.handler.db-based.property :as db-property-handler]
-            [frontend.handler.property.util :as pu]
-            [frontend.state :as state]))
-
-(defn set-status!
-  [block status-value-name]
-  (let [repo (state/get-current-repo)
-        status-id (:block/uuid (pu/get-closed-value-entity-by-name "status" status-value-name))]
-    (when status-id
-      (db-property-handler/set-block-property! repo
-                                               (:block/uuid block)
-                                               "status"
-                                               status-id
-                                               {}))))
-
-(comment
-  (defn cycle-status!
-   [block status]))

+ 21 - 20
src/main/frontend/handler/editor.cljs

@@ -638,21 +638,25 @@
 
 (defn cycle-todos!
   []
-  (when-let [blocks (seq (get-selected-blocks))]
-    (let [ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
-                                     (uuid id)) blocks))
-                   (remove nil?))]
-      (ui-outliner-tx/transact!
-       {:outliner-op :cycle-todos}
-       (doseq [id ids]
-         (let [block (db/pull [:block/uuid id])]
-           (when (not-empty (:block/content block))
-             (set-marker block))))))))
+  ;; TODO: closed values needs to be enriched to know which state to be the next one
+  (when-not (config/db-based-graph? (state/get-current-repo))
+    (when-let [blocks (seq (get-selected-blocks))]
+      (let [ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
+                                       (uuid id)) blocks))
+                     (remove nil?))]
+        (ui-outliner-tx/transact!
+         {:outliner-op :cycle-todos}
+         (doseq [id ids]
+           (let [block (db/pull [:block/uuid id])]
+             (when (not-empty (:block/content block))
+               (set-marker block)))))))))
 
 (defn cycle-todo!
   []
   #_:clj-kondo/ignore
-  (when-not (state/get-editor-action)
+  (when (and (not (state/get-editor-action))
+             ;; TODO: closed values needs to be enriched to know which state to be the next one
+             (not (config/db-based-graph? (state/get-current-repo))))
     (if-let [blocks (seq (get-selected-blocks))]
       (cycle-todos!)
       (when (state/get-edit-block)
@@ -669,10 +673,11 @@
 
 (defn set-priority
   [{:block/keys [priority content] :as block} new-priority]
-  (let [new-content (string/replace-first content
-                                          (util/format "[#%s]" priority)
-                                          (util/format "[#%s]" new-priority))]
-    (save-block-if-changed! block new-content)))
+  (when-not (config/db-based-graph? (state/get-current-repo))
+    (let [new-content (string/replace-first content
+                                           (util/format "[#%s]" priority)
+                                           (util/format "[#%s]" new-priority))]
+     (save-block-if-changed! block new-content))))
 
 (defn delete-block-aux!
   [{:block/keys [uuid repo] :as _block} children? & {:keys [_children-checks?] :as delete-opts}]
@@ -2870,11 +2875,7 @@
                                               (block-handler/get-top-level-blocks [block])
                                               indent?
                                               {:get-first-block-original block-handler/get-first-block-original
-                                               :logical-outdenting? (state/logical-outdenting?)})
-         (edit-block!
-           (db/pull (:db/id block))
-           (cursor/pos (state/get-input))
-           (:block/uuid block)))))))
+                                               :logical-outdenting? (state/logical-outdenting?)}))))))
 
 (defn keydown-tab-handler
   [direction]

+ 9 - 8
src/main/frontend/handler/export/common.cljs

@@ -90,13 +90,14 @@
                (mapv remove-block-ast-pos
                      (mldoc/->edn content format))))))
 
-(defn <get-page-content
-  ([page-name]
-   (<get-page-content (state/get-current-repo) page-name))
-  ([repo page-name]
-   (when-let [^object worker @db-browser/*worker]
-     (.block->content worker repo page-name nil
-                      (pr-str {:export-bullet-indentation (state/get-export-bullet-indentation)})))))
+;; TODO: Enable when unused
+#_(defn <get-page-content
+    ([page-name]
+     (<get-page-content (state/get-current-repo) page-name))
+    ([repo page-name]
+     (when-let [^object worker @db-browser/*worker]
+       (.block->content worker repo page-name nil
+                        (pr-str {:export-bullet-indentation (state/get-export-bullet-indentation)})))))
 
 (defn get-page-content
   [page-name]
@@ -206,7 +207,7 @@
   [repo suffix]
   (p/let [page->content (<get-all-page->content repo)]
     (clojure.core/map (fn [[page-title content]]
-                        {:path (str page-title "."suffix)
+                        {:path (str page-title "." suffix)
                          :content content
                          :title page-title
                          :format :markdown})

+ 3 - 5
src/main/frontend/handler/file_based/status.cljs

@@ -1,12 +1,10 @@
 (ns frontend.handler.file-based.status
   "Task (formerly todo) related util fns"
   (:require [clojure.string :as string]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [logseq.common.marker :as common-marker]))
 
-(defn marker-pattern [format]
-  (re-pattern
-   (str "^" (if (= format :markdown) "(#+\\s+)?" "(\\*+\\s+)?")
-        "(NOW|LATER|TODO|DOING|DONE|WAITING|WAIT|CANCELED|CANCELLED|IN-PROGRESS)?\\s?")))
+(def marker-pattern common-marker/marker-pattern)
 
 (def bare-marker-pattern
   #"(NOW|LATER|TODO|DOING|DONE|WAITING|WAIT|CANCELED|CANCELLED|IN-PROGRESS){1}\s+")

+ 4 - 3
src/main/frontend/persist_db/browser.cljs

@@ -79,10 +79,11 @@
                   _ (ask-persist-permission!)]
             (ldb/register-transact-fn!
              (fn worker-transact!
-               [_conn tx-data tx-meta]
-               (transact! wrapped-worker (state/get-current-repo) tx-data
+               [repo tx-data tx-meta]
+               (let [repo' (if (string? repo) repo (state/get-current-repo))]
+                 (transact! wrapped-worker repo' tx-data
                  ;; not from remote(rtc)
-                          (assoc tx-meta :local-tx? true)))))
+                            (assoc tx-meta :local-tx? true))))))
           (p/catch (fn [error]
                      (prn :debug "Can't init SQLite wasm")
                      (js/console.error error)

+ 15 - 2
src/main/frontend/worker/rtc/core.cljs

@@ -335,6 +335,17 @@
     (update-block-attrs repo conn date-formatter self op-value)
     (prn :apply-remote-update-ops self)))
 
+(defn- move-all-blocks-to-another-page
+  [repo conn from-page-name to-page-name]
+  (let [blocks (ldb/get-page-blocks @conn from-page-name {})
+        target-page-block (first (ldb/get-page-blocks @conn to-page-name {}))]
+    (when (and (seq blocks) target-page-block)
+      (outliner-tx/transact!
+       {:persist-op? true
+        :transact-opts {:repo repo
+                        :conn conn}}
+       (outliner-core/move-blocks! repo conn blocks target-page-block false)))))
+
 (defn apply-remote-update-page-ops
   [repo conn date-formatter update-page-ops]
   (let [config (worker-state/get-config repo)]
@@ -349,8 +360,10 @@
           ;; 1. rename local page's name to '<origin-name>-<ms-epoch>-Conflict'
           ;; 2. create page, name=<origin-name>, uuid=remote-uuid
           (and exist-page (not= (:block/uuid exist-page) self))
-          (do (worker-page-rename/rename! repo conn config original-name (common-util/format "%s-%s-CONFLICT" original-name (tc/to-long (t/now))))
-              (worker-page/create! repo conn config original-name create-opts))
+          (let [conflict-page-name (common-util/format "%s-%s-CONFLICT" original-name (tc/to-long (t/now)))]
+            (worker-page-rename/rename! repo conn config original-name conflict-page-name {:persist-op? false})
+            (worker-page/create! repo conn config original-name create-opts)
+            (move-all-blocks-to-another-page repo conn conflict-page-name original-name))
 
           ;; a client-page has same uuid as remote but different page-names,
           ;; then we need to rename the client-page to remote-page-name

+ 5 - 4
src/main/frontend/worker/rtc/full_upload_download_graph.cljs

@@ -61,7 +61,8 @@
   {:block-type/property   "property"
    :block-type/class      "class"
    :block-type/whiteboard "whiteboard"
-   :block-type/macros     "macros"})
+   :block-type/macros     "macros"
+   :block-type/hidden     "hidden"})
 
 
 (defn- replace-db-id-with-temp-id
@@ -122,10 +123,10 @@
          blocks-with-page-id (fill-block-fields blocks*)
          ^js worker-obj (:worker/object @worker-state/*state)
          work (p/do!
-               (.createOrOpenDB worker-obj repo)
+               (.createOrOpenDB worker-obj repo {:close-other-db? false})
                (.exportDB worker-obj repo)
-               (.transact worker-obj repo blocks-with-page-id nil (worker-state/get-context))
-               (.releaseAccessHandles worker-obj repo))]
+               (.transact worker-obj repo blocks-with-page-id {:rtc-download-graph? true} (worker-state/get-context))
+               (.closeDB worker-obj repo))]
      (<? (p->c work))
 
      (worker-util/post-message :add-repo (pr-str {:repo repo}))

+ 9 - 5
src/test/frontend/worker/rtc/asset_sync_effects_test.cljs

@@ -1,9 +1,11 @@
 (ns frontend.worker.rtc.asset-sync-effects-test
   "This ns include tests abouts asset-sync with other components.
   These tests need to start the asset-sync-loop."
+  #_:clj-kondo/ignore
   (:require [clojure.test :as t :refer [deftest is use-fixtures]]
             [frontend.test.helper :include-macros true :as test-helper]
             [frontend.worker.rtc.fixture :as rtc-fixture]
+            #_:clj-kondo/ignore
             [spy.core :as spy]))
 
 (use-fixtures :each
@@ -13,8 +15,10 @@
   rtc-fixture/clear-op-mem-stores-fixture)
 
 
-(deftest asset-sync-loop-init-test
-  (let [ws @(:*ws @rtc-fixture/*test-asset-sync-state)
-        handler-fn (:handler-fn ws)
-        ws-msg (first (spy/last-call handler-fn))]
-    (is (= "list-graphs" (:action ws-msg)))))
+;; FIXME: Re-enable when this test doesn't fail when whole test suite is run
+;; e.g. https://github.com/logseq/logseq/actions/runs/7627378707/job/20775904183
+#_(deftest asset-sync-loop-init-test
+    (let [ws @(:*ws @rtc-fixture/*test-asset-sync-state)
+          handler-fn (:handler-fn ws)
+          ws-msg (first (spy/last-call handler-fn))]
+      (is (= "list-graphs" (:action ws-msg)))))

部分文件因文件數量過多而無法顯示