mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 14:14:55 +00:00
Merge branch 'master' into feat/capacitor-new
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -72,3 +72,4 @@ clj-e2e/.wally
|
||||
clj-e2e/resources
|
||||
clj-e2e/e2e-dump
|
||||
.dir-locals.el
|
||||
.projectile
|
||||
|
||||
@@ -8,10 +8,16 @@
|
||||
[wally.main :as w]))
|
||||
|
||||
(defn open-last-block
|
||||
"Open the last existing block or pressing add button to create a new block"
|
||||
[]
|
||||
(util/double-esc)
|
||||
(assert/assert-in-normal-mode?)
|
||||
(w/click (last (w/query ".ls-page-blocks .ls-block .block-content"))))
|
||||
(let [blocks-count (util/page-blocks-count)
|
||||
last-block (-> (if (zero? blocks-count)
|
||||
(w/query ".ls-page-blocks .block-add-button")
|
||||
(w/query ".ls-page-blocks .page-blocks-inner .ls-block .block-content"))
|
||||
(last))]
|
||||
(w/click last-block)))
|
||||
|
||||
(defn save-block
|
||||
[text]
|
||||
|
||||
@@ -98,11 +98,11 @@
|
||||
(defn blocks-count
|
||||
"Blocks count including page title"
|
||||
[]
|
||||
(count-elements ".ls-block"))
|
||||
(count-elements ".ls-block:not(.block-add-button)"))
|
||||
|
||||
(defn page-blocks-count
|
||||
[]
|
||||
(count-elements ".ls-page-blocks .ls-block"))
|
||||
(count-elements ".ls-page-blocks .page-blocks-inner .ls-block"))
|
||||
|
||||
(defn exit-edit
|
||||
[]
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
(defn get-page-blocks-contents
|
||||
[]
|
||||
(w/all-text-contents ".ls-page-blocks .ls-block .block-title-wrap"))
|
||||
(w/all-text-contents ".ls-page-blocks .ls-block:not(.block-add-button) .block-title-wrap"))
|
||||
|
||||
(def mac? (= "Mac OS X" (System/getProperty "os.name")))
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
(w/click (first (w/query (format "a.menu-link:has-text(\"%s\")" tag))))
|
||||
;; wait tag added on ui
|
||||
(assert/assert-is-visible
|
||||
(-> ".ls-block"
|
||||
(-> ".ls-block:not(.block-add-button)"
|
||||
(loc/filter :has ".editor-wrapper textarea")
|
||||
(loc/filter :has (format ".block-tag :text('%s')" tag)))))
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
[logseq.e2e.rtc :as rtc]
|
||||
[logseq.e2e.settings :as settings]
|
||||
[logseq.e2e.util :as util]
|
||||
[wally.main :as w]
|
||||
[wally.repl :as repl]))
|
||||
[wally.main :as w]))
|
||||
|
||||
(defn- prepare-rtc-graph-fixture
|
||||
"open 2 app instances, add a rtc graph, check this graph available on other instance"
|
||||
|
||||
2
deps.edn
2
deps.edn
@@ -25,7 +25,7 @@
|
||||
hiccups/hiccups {:mvn/version "0.3.0"}
|
||||
tongue/tongue {:mvn/version "0.4.4"}
|
||||
org.clojure/core.async {:mvn/version "1.6.673"}
|
||||
thheller/shadow-cljs {:mvn/version "2.19.0"}
|
||||
thheller/shadow-cljs {:mvn/version "2.28.23"}
|
||||
expound/expound {:mvn/version "0.8.6"}
|
||||
com.lambdaisland/glogi {:mvn/version "1.1.144"}
|
||||
binaryage/devtools {:mvn/version "1.0.5"}
|
||||
|
||||
6
deps/common/resources/templates/config.edn
vendored
6
deps/common/resources/templates/config.edn
vendored
@@ -327,10 +327,6 @@
|
||||
;; Default value: 2
|
||||
:ref/default-open-blocks-level 2
|
||||
|
||||
;; Configure the threshold for linked references before collapsing.
|
||||
;; Default value: 100
|
||||
:ref/linked-references-collapsed-threshold 50
|
||||
|
||||
;; Graph view configuration.
|
||||
;; Example usage:
|
||||
;; :graph/settings
|
||||
@@ -408,4 +404,4 @@
|
||||
;; :page-ref? true ;; Default value: true
|
||||
;; :properties? true ;; Default value: true
|
||||
;; :list? false} ;; Default value: false
|
||||
}
|
||||
}
|
||||
|
||||
6
deps/common/src/logseq/common/uuid.cljs
vendored
6
deps/common/src/logseq/common/uuid.cljs
vendored
@@ -40,7 +40,8 @@ the remaining chars for data of this type"
|
||||
- :journal-page-uuid, 00000001
|
||||
- :db-ident-block-uuid, 00000002
|
||||
- :migrate-new-block-uuid, 00000003
|
||||
- :builtin-block-uuid, 00000004"
|
||||
- :builtin-block-uuid, 00000004
|
||||
- :view-block-uuid, 00000006"
|
||||
([] (d/squuid))
|
||||
([type' v]
|
||||
(assert (some? v))
|
||||
@@ -48,7 +49,8 @@ the remaining chars for data of this type"
|
||||
:journal-page-uuid (gen-journal-page-uuid v)
|
||||
:db-ident-block-uuid (gen-db-ident-block-uuid v)
|
||||
:migrate-new-block-uuid (gen-block-uuid v "00000003")
|
||||
:builtin-block-uuid (gen-block-uuid v "00000004"))))
|
||||
:builtin-block-uuid (gen-block-uuid v "00000004")
|
||||
:view-block-uuid (gen-block-uuid v "00000006"))))
|
||||
|
||||
(defn gen-journal-template-block
|
||||
"Persistent uuid for journal template block"
|
||||
|
||||
12
deps/db/.carve/ignore
vendored
12
deps/db/.carve/ignore
vendored
@@ -33,4 +33,14 @@ logseq.db.common.initial-data/with-parent
|
||||
;; API
|
||||
logseq.db.common.initial-data/get-block-and-children
|
||||
;; API
|
||||
logseq.db.common.initial-data/get-initial-data
|
||||
logseq.db.common.initial-data/get-initial-data
|
||||
;; API
|
||||
logseq.db.sqlite.debug/find-missing-addresses
|
||||
;; API
|
||||
logseq.db.sqlite.debug/find-missing-addresses-node-version
|
||||
;; API
|
||||
logseq.db.sqlite.gc/gc-kvs-table!
|
||||
;; API
|
||||
logseq.db.sqlite.gc/gc-kvs-table-node-version!
|
||||
;; API
|
||||
logseq.db.sqlite.gc/ensure-no-garbage
|
||||
|
||||
43
deps/db/src/logseq/db/common/sqlite_cli.cljs
vendored
43
deps/db/src/logseq/db/common/sqlite_cli.cljs
vendored
@@ -32,16 +32,12 @@
|
||||
|
||||
(defn- upsert-addr-content!
|
||||
"Upsert addr+data-seq. Should be functionally equivalent to db-worker/upsert-addr-content!"
|
||||
[db data delete-addrs]
|
||||
[db data]
|
||||
(let [insert (.prepare db "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses")
|
||||
delete (.prepare db "Delete from kvs WHERE addr = ? AND NOT EXISTS (SELECT 1 FROM json_each(addresses) WHERE value = ?);")
|
||||
insert-many (.transaction ^object db
|
||||
(fn [data]
|
||||
(doseq [item data]
|
||||
(.run ^object insert item))
|
||||
(doseq [addr delete-addrs]
|
||||
(when addr
|
||||
(.run ^object delete addr)))))]
|
||||
(.run ^object insert item))))]
|
||||
(insert-many data)))
|
||||
|
||||
(defn- restore-data-from-addr
|
||||
@@ -61,16 +57,9 @@
|
||||
"Creates a datascript storage for sqlite. Should be functionally equivalent to db-worker/new-sqlite-storage"
|
||||
[db]
|
||||
(reify IStorage
|
||||
(-store [_ addr+data-seq delete-addrs]
|
||||
;; Only difference from db-worker impl is that js data maps don't start with '$' e.g. :$addr -> :addr
|
||||
(let [used-addrs (set (mapcat
|
||||
(fn [[addr data]]
|
||||
(cons addr
|
||||
(when (map? data)
|
||||
(:addresses data))))
|
||||
addr+data-seq))
|
||||
delete-addrs (remove used-addrs delete-addrs)
|
||||
data (map
|
||||
(-store [_ addr+data-seq _delete-addrs]
|
||||
;; Only difference from db-worker impl is that js data maps don't start with '$' e.g. :$addr -> :addr
|
||||
(let [data (map
|
||||
(fn [[addr data]]
|
||||
(let [data' (if (map? data) (dissoc data :addresses) data)
|
||||
addresses (when (map? data)
|
||||
@@ -80,16 +69,14 @@
|
||||
:content (sqlite-util/transit-write data')
|
||||
:addresses addresses}))
|
||||
addr+data-seq)]
|
||||
(upsert-addr-content! db data delete-addrs)))
|
||||
(upsert-addr-content! db data)))
|
||||
(-restore [_ addr]
|
||||
(restore-data-from-addr db addr))))
|
||||
|
||||
(defn open-db!
|
||||
"For a given database name, opens a sqlite db connection for it, creates
|
||||
needed sqlite tables if not created and returns a datascript connection that's
|
||||
connected to the sqlite db"
|
||||
(defn open-sqlite-datascript!
|
||||
"Returns a map including `conn` for datascript connection and `sqlite` for sqlite connection"
|
||||
([db-full-path]
|
||||
(open-db! nil db-full-path))
|
||||
(open-sqlite-datascript! nil db-full-path))
|
||||
([graphs-dir db-name]
|
||||
(let [[base-name db-full-path]
|
||||
(if (nil? graphs-dir)
|
||||
@@ -103,7 +90,17 @@
|
||||
(common-sqlite/create-kvs-table! db)
|
||||
(let [storage (new-sqlite-storage db)
|
||||
conn (common-sqlite/get-storage-conn storage schema)]
|
||||
conn))))
|
||||
{:sqlite db
|
||||
:conn conn}))))
|
||||
|
||||
(defn open-db!
|
||||
"For a given database name, opens a sqlite db connection for it, creates
|
||||
needed sqlite tables if not created and returns a datascript connection that's
|
||||
connected to the sqlite db"
|
||||
([db-full-path]
|
||||
(open-db! nil db-full-path))
|
||||
([graphs-dir db-name]
|
||||
(:conn (open-sqlite-datascript! graphs-dir db-name))))
|
||||
|
||||
(defn ->open-db-args
|
||||
"Creates args for open-db from a graph arg. Works for relative and absolute paths and
|
||||
|
||||
@@ -25,4 +25,7 @@ RTC won't start when major-schema-versions don't match"
|
||||
:logseq.kv/graph-backup-folder {:doc "Backup folder for automated backup feature"
|
||||
:rtc {:rtc/ignore-entity-when-init-upload true
|
||||
:rtc/ignore-entity-when-init-download true}}
|
||||
:logseq.kv/graph-initial-schema-version {:doc "Graph's schema version when created"})
|
||||
:logseq.kv/graph-initial-schema-version {:doc "Graph's schema version when created"}
|
||||
:logseq.kv/graph-last-gc-at {:doc "Last time graph gc at"
|
||||
:rtc {:rtc/ignore-entity-when-init-upload true
|
||||
:rtc/ignore-entity-when-init-download true}})
|
||||
|
||||
37
deps/db/src/logseq/db/sqlite/debug.cljs
vendored
Normal file
37
deps/db/src/logseq/db/sqlite/debug.cljs
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
(ns logseq.db.sqlite.debug
|
||||
"SQLite debug fns"
|
||||
(:require [cljs-bean.core :as bean]
|
||||
[clojure.set]
|
||||
[logseq.db.sqlite.util :as sqlite-util]))
|
||||
|
||||
(defn find-missing-addresses
|
||||
"WASM version to find missing addresses from the kvs table"
|
||||
[^Object db]
|
||||
(let [schema (some->> (.exec db #js {:sql "select content from kvs where addr = 0"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
ffirst
|
||||
sqlite-util/transit-read)
|
||||
result (->> (.exec db #js {:sql "select addr, addresses from kvs"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
(keep (fn [[addr addresses]]
|
||||
[addr (bean/->clj (js/JSON.parse addresses))])))
|
||||
used-addresses (set (concat (mapcat second result)
|
||||
[0 1 (:eavt schema) (:avet schema) (:aevt schema)]))]
|
||||
(clojure.set/difference used-addresses (set (map first result)))))
|
||||
|
||||
(defn find-missing-addresses-node-version
|
||||
"Node version to find missing addresses from the kvs table"
|
||||
[^Object db]
|
||||
(let [schema (let [stmt (.prepare db "select content from kvs where addr = ?")
|
||||
content (.-content (.get stmt 0))]
|
||||
(sqlite-util/transit-read content))
|
||||
stmt (.prepare db "select addr, addresses from kvs")
|
||||
result (->> (.all ^Object stmt)
|
||||
bean/->clj
|
||||
(keep (fn [{:keys [addr addresses]}]
|
||||
[addr (bean/->clj (js/JSON.parse addresses))])))
|
||||
used-addresses (set (concat (mapcat second result)
|
||||
[0 1 (:eavt schema) (:avet schema) (:aevt schema)]))]
|
||||
(clojure.set/difference used-addresses (set (map first result)))))
|
||||
120
deps/db/src/logseq/db/sqlite/gc.cljs
vendored
Normal file
120
deps/db/src/logseq/db/sqlite/gc.cljs
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
(ns logseq.db.sqlite.gc
|
||||
"GC unused addresses from `kvs` table"
|
||||
(:require [cljs-bean.core :as bean]
|
||||
[clojure.set :as set]
|
||||
[logseq.db.sqlite.util :as sqlite-util]))
|
||||
|
||||
(defn- walk-addresses
|
||||
"Given a map of parent address to children addresses and a root address,
|
||||
returns a set of all used addresses including the root and its descendants."
|
||||
[root addr->children]
|
||||
(println :debug :walk-addresses :root root)
|
||||
(time
|
||||
(letfn [(collect-addresses [addr]
|
||||
(let [children (addr->children addr)]
|
||||
(into #{addr} (mapcat collect-addresses children))))]
|
||||
(collect-addresses root))))
|
||||
|
||||
(defonce get-non-refed-addrs-sql
|
||||
"WITH all_referenced AS (
|
||||
SELECT CAST(value AS INTEGER) AS addr
|
||||
FROM kvs, json_each(kvs.addresses)
|
||||
)
|
||||
SELECT kvs.addr
|
||||
FROM kvs
|
||||
WHERE kvs.addr NOT IN (SELECT addr FROM all_referenced)")
|
||||
|
||||
(defn- get-unused-addresses
|
||||
[db]
|
||||
(let [schema (some->> (.exec db #js {:sql "select content from kvs where addr = 0"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
ffirst
|
||||
sqlite-util/transit-read)
|
||||
;; 0: Datascript sets 0 as the address to store the db's meta, including addresses for :eavt, :avet, and aevt index.
|
||||
;; 1: Datascript sets 1 for tail, to improve the performance
|
||||
internal-addrs (set [0 1 (:eavt schema) (:avet schema) (:aevt schema)])
|
||||
non-refed-addrs (->> (.exec db #js {:sql get-non-refed-addrs-sql
|
||||
:rowMode "array"})
|
||||
(map first)
|
||||
set)]
|
||||
(set/difference non-refed-addrs internal-addrs)))
|
||||
|
||||
(defn gc-kvs-table!
|
||||
"WASM version to GC kvs table to remove unused addresses"
|
||||
[^Object db {:keys [full-gc?] :as opts}]
|
||||
(when db
|
||||
(let [unused-addresses (get-unused-addresses db)]
|
||||
(if (seq unused-addresses)
|
||||
(do
|
||||
(println :debug :db-gc :unused-addresses unused-addresses)
|
||||
(.transaction db (fn [tx]
|
||||
(doseq [addr unused-addresses]
|
||||
(.exec tx #js {:sql "Delete from kvs where addr = ?"
|
||||
:bind #js [addr]}))))
|
||||
(when full-gc?
|
||||
(gc-kvs-table! db opts)))
|
||||
(println :debug :db-gc "There's no garbage data that's need to be collected.")))))
|
||||
|
||||
(defn- get-unused-addresses-node-version
|
||||
[db]
|
||||
(let [schema (let [stmt (.prepare db "select content from kvs where addr = ?")
|
||||
content (.-content (.get stmt 0))]
|
||||
(sqlite-util/transit-read content))
|
||||
internal-addrs (set [0 1 (:eavt schema) (:avet schema) (:aevt schema)])
|
||||
non-refed-addrs (let [stmt (.prepare db get-non-refed-addrs-sql)]
|
||||
(->> (.all ^object stmt)
|
||||
bean/->clj
|
||||
(map :addr)
|
||||
(set)))]
|
||||
(set/difference non-refed-addrs internal-addrs)))
|
||||
|
||||
(defn- get-unused-addresses-node-walk-version
|
||||
[db]
|
||||
(let [schema (let [stmt (.prepare db "select content from kvs where addr = ?")
|
||||
content (.-content (.get stmt 0))]
|
||||
(sqlite-util/transit-read content))
|
||||
set-addresses #{(:eavt schema) (:avet schema) (:aevt schema)}
|
||||
internal-addresses (conj set-addresses 0 1)
|
||||
parent->children (let [stmt (.prepare db "select addr, addresses from kvs")]
|
||||
(->> (.all ^object stmt)
|
||||
bean/->clj
|
||||
(map (fn [{:keys [addr addresses]}]
|
||||
[addr (bean/->clj (js/JSON.parse addresses))]))
|
||||
(into {})))
|
||||
used-addresses (->> (mapcat (fn [set-root-addr]
|
||||
(walk-addresses set-root-addr parent->children)) set-addresses)
|
||||
set
|
||||
(set/union internal-addresses))]
|
||||
(set/difference (set (keys parent->children)) used-addresses)))
|
||||
|
||||
(defn gc-kvs-table-node-version!
|
||||
"Node version to GC kvs table to remove unused addresses
|
||||
`walk?` - `true`: walk all used addresses, `false`: gc recursively"
|
||||
[^Object db walk?]
|
||||
(let [unused-addresses (if walk?
|
||||
(get-unused-addresses-node-walk-version db)
|
||||
(get-unused-addresses-node-version db))
|
||||
addrs-count (let [stmt (.prepare db "select count(*) as c from kvs")]
|
||||
(.-c (.get stmt)))]
|
||||
(println :debug "addrs total count: " addrs-count)
|
||||
(if (seq unused-addresses)
|
||||
(do
|
||||
(println :debug :db-gc :unused-addresses-count (count unused-addresses))
|
||||
(let [stmt (.prepare db "Delete from kvs where addr = ?")
|
||||
delete (.transaction
|
||||
db
|
||||
(fn [addrs]
|
||||
(doseq [addr addrs]
|
||||
(.run stmt addr))))]
|
||||
(delete (bean/->js unused-addresses))
|
||||
(when-not walk?
|
||||
(gc-kvs-table-node-version! db false))))
|
||||
(println :debug :db-gc "There's no garbage data that's need to be collected."))))
|
||||
|
||||
(defn ensure-no-garbage
|
||||
[^Object db]
|
||||
(let [unused-addresses (get-unused-addresses-node-version db)]
|
||||
;; (println :debug :db-gc :unused-addresses-count (count unused-addresses))
|
||||
;; (println :debug :unused-addresses unused-addresses)
|
||||
(empty? unused-addresses)))
|
||||
49
deps/db/test/logseq/db/sqlite/gc_test.cljs
vendored
Normal file
49
deps/db/test/logseq/db/sqlite/gc_test.cljs
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
(ns logseq.db.sqlite.gc-test
|
||||
(:require ["fs" :as fs]
|
||||
["path" :as node-path]
|
||||
[cljs.test :refer [deftest async use-fixtures is testing]]
|
||||
[datascript.core :as d]
|
||||
[logseq.db.common.sqlite-cli :as sqlite-cli]
|
||||
[logseq.db.sqlite.debug :as sqlite-debug]
|
||||
[logseq.db.sqlite.gc :as sqlite-gc]))
|
||||
|
||||
(use-fixtures
|
||||
:each
|
||||
;; Cleaning tmp/ before leaves last tmp/ after a test run for dev and debugging
|
||||
{:before
|
||||
#(async done
|
||||
(if (fs/existsSync "tmp")
|
||||
(fs/rm "tmp" #js {:recursive true} (fn [err]
|
||||
(when err (js/console.log err))
|
||||
(done)))
|
||||
(done)))})
|
||||
|
||||
(defn- create-graph-dir
|
||||
[dir db-name]
|
||||
(fs/mkdirSync (node-path/join dir db-name) #js {:recursive true}))
|
||||
|
||||
(deftest ^:long gc-kvs-table-test
|
||||
(testing "Create a datascript db, gc it and ensure there's no missing addrs and garbage addrs"
|
||||
(create-graph-dir "tmp/graphs" "test-db")
|
||||
|
||||
(let [{:keys [conn sqlite]} (sqlite-cli/open-sqlite-datascript! "tmp/graphs" "test-db")
|
||||
tx-data (map (fn [i] {:block/uuid (random-uuid)
|
||||
:block/title (str "title " i)})
|
||||
(range 0 500000))]
|
||||
(println "DB start transacting")
|
||||
(d/transact! conn tx-data)
|
||||
(println "DB transacted")
|
||||
(let [non-ordered-tx (->> (shuffle tx-data)
|
||||
(take 100000)
|
||||
(map (fn [block] [:db/retractEntity [:block/uuid (:block/uuid block)]])))]
|
||||
(d/transact! conn non-ordered-tx))
|
||||
(println "gc time")
|
||||
;; `true` to walk addresses and `false` to recursively run gc
|
||||
(time (sqlite-gc/gc-kvs-table-node-version! sqlite false))
|
||||
|
||||
;; ensure there's no missing address (broken db)
|
||||
(is (empty? (sqlite-debug/find-missing-addresses-node-version sqlite))
|
||||
"Found missing addresses!")
|
||||
|
||||
(is (true? (sqlite-gc/ensure-no-garbage sqlite))
|
||||
"Found garbage addresses!"))))
|
||||
@@ -271,10 +271,6 @@
|
||||
;; Default value: 2
|
||||
:ref/default-open-blocks-level 2
|
||||
|
||||
;; Configure the threshold for linked references before collapsing.
|
||||
;; Default value: 100
|
||||
:ref/linked-references-collapsed-threshold 50
|
||||
|
||||
;; Graph view configuration.
|
||||
;; Example usage:
|
||||
;; :graph/settings
|
||||
|
||||
@@ -98,9 +98,9 @@ const common = {
|
||||
'node_modules/@glidejs/glide/dist/css/glide.theme.min.css',
|
||||
]).pipe(gulp.dest(path.join(outputPath, 'js', 'glide'))),
|
||||
() => gulp.src([
|
||||
'node_modules/pdfjs-dist/build/pdf.js',
|
||||
'node_modules/pdfjs-dist/build/pdf.worker.js',
|
||||
'node_modules/pdfjs-dist/web/pdf_viewer.js',
|
||||
'node_modules/pdfjs-dist/legacy/build/pdf.mjs',
|
||||
'node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs',
|
||||
'node_modules/pdfjs-dist/legacy/web/pdf_viewer.mjs',
|
||||
]).pipe(gulp.dest(path.join(outputPath, 'js', 'pdfjs'))),
|
||||
() => gulp.src([
|
||||
'node_modules/pdfjs-dist/cmaps/*.*',
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
"mldoc": "^1.5.9",
|
||||
"path": "0.12.7",
|
||||
"path-complete-extname": "1.0.0",
|
||||
"pdfjs-dist": "^3.9.179",
|
||||
"pdfjs-dist": "4.2.67",
|
||||
"photoswipe": "^5.3.7",
|
||||
"pixi-graph-fork": "0.2.0",
|
||||
"pixi.js": "6.2.0",
|
||||
|
||||
@@ -49,6 +49,8 @@ const portal = new MagicPortal(worker);
|
||||
<script defer src="./js/highlight.min.js"></script>
|
||||
<script defer src="./js/interact.min.js"></script>
|
||||
<script defer src="./js/marked.min.js"></script>
|
||||
<script defer type="module" src="./js/pdfjs/pdf.mjs"></script>
|
||||
<script defer type="module" src="./js/pdf_viewer3.mjs"></script>
|
||||
<script defer src="./js/eventemitter3.umd.min.js"></script>
|
||||
<script defer src="./js/html2canvas.min.js"></script>
|
||||
<script defer src="./js/lsplugin.core.js"></script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
12391
resources/js/pdf_viewer3.mjs
Normal file
12391
resources/js/pdf_viewer3.mjs
Normal file
File diff suppressed because one or more lines are too long
@@ -326,7 +326,6 @@ h1.title, h1.title input, .ls-page-title-container {
|
||||
|
||||
.block-highlight,
|
||||
.ls-block.selected,
|
||||
.ls-dummy-block.selected,
|
||||
.ls-table-cell.selected
|
||||
{
|
||||
transition: background-color 0.2s cubic-bezier(0, 1, 0, 1);
|
||||
|
||||
@@ -2115,7 +2115,9 @@
|
||||
(or ref? query?)
|
||||
(assoc :ref-query-child? true)
|
||||
true
|
||||
(assoc :block-children? true))]
|
||||
(assoc :block-children? true)
|
||||
(integer? (:block-level config))
|
||||
(update :block-level inc))]
|
||||
(block-list config' children))]])))
|
||||
|
||||
(defn- block-content-empty?
|
||||
|
||||
@@ -539,8 +539,7 @@
|
||||
(p/let [result (cond
|
||||
create-class?
|
||||
(db-page-handler/<create-class! class
|
||||
{:redirect? false
|
||||
:create-first-block? false})
|
||||
{:redirect? false})
|
||||
create-whiteboard? (whiteboard-handler/<create-new-whiteboard-and-redirect! @!input)
|
||||
create-page? (page-handler/<create! @!input {:redirect? true}))]
|
||||
(shui/dialog-close! :ls-dialog-cmdk)
|
||||
|
||||
@@ -122,8 +122,7 @@
|
||||
(state/set-edit-content! (.-id input) value')
|
||||
(state/clear-editor-action!)
|
||||
(p/let [page (db/get-page chosen-item)
|
||||
_ (when-not page (page-handler/<create! chosen-item {:redirect? false
|
||||
:create-first-block? false}))
|
||||
_ (when-not page (page-handler/<create! chosen-item {:redirect? false}))
|
||||
page' (db/get-page chosen-item)
|
||||
current-block (state/get-edit-block)]
|
||||
(editor-handler/api-insert-new-block! chosen-item
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
[frontend.format.mldoc :as mldoc]
|
||||
[frontend.handler.common :as common-handler]
|
||||
[frontend.handler.config :as config-handler]
|
||||
[frontend.handler.dnd :as dnd]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.graph :as graph-handler]
|
||||
[frontend.handler.notification :as notification]
|
||||
@@ -36,7 +35,6 @@
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.mixins :as mixins]
|
||||
[frontend.mobile.util :as mobile-util]
|
||||
[frontend.rum :as frontend-rum]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
@@ -101,88 +99,39 @@
|
||||
|
||||
(declare page-cp)
|
||||
|
||||
(if config/publishing?
|
||||
(rum/defc dummy-block
|
||||
[_page]
|
||||
[:div])
|
||||
|
||||
(rum/defc dummy-block
|
||||
[page]
|
||||
(let [[hover set-hover!] (rum/use-state false)
|
||||
click-handler-fn (fn []
|
||||
(p/let [result (editor-handler/insert-first-page-block-if-not-exists! (:block/uuid page))
|
||||
result (:tx-data result)
|
||||
first-child-id (first (map :block/uuid result))
|
||||
first-child (when first-child-id (db/entity [:block/uuid first-child-id]))]
|
||||
(when first-child
|
||||
(editor-handler/edit-block! first-child :max {:container-id :unknown-container}))))
|
||||
drop-handler-fn (fn [^js event]
|
||||
(util/stop event)
|
||||
(p/let [block-uuids (state/get-selection-block-ids)
|
||||
lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
|
||||
selected (db/pull-many (state/get-current-repo) '[*] lookup-refs)
|
||||
blocks (if (seq selected) selected [@component-block/*dragging-block])
|
||||
_ (editor-handler/insert-first-page-block-if-not-exists! (:block/uuid page))]
|
||||
(js/setTimeout #(let [target-block page]
|
||||
(dnd/move-blocks event blocks target-block nil :sibling))
|
||||
0)))
|
||||
*dummy-block-uuid (rum/use-ref (random-uuid))
|
||||
*el-ref (rum/use-ref nil)
|
||||
_ (frontend-rum/use-atom (@state/state :selection/blocks))
|
||||
selection-ids (state/get-selection-block-ids)
|
||||
selected? (contains? (set selection-ids) (rum/deref *dummy-block-uuid))
|
||||
idstr (str (rum/deref *dummy-block-uuid))
|
||||
focus! (fn [] (js/setTimeout #(some-> (rum/deref *el-ref) (.focus)) 16))]
|
||||
|
||||
;; mounted
|
||||
;(hooks/use-effect! #(focus!) [])
|
||||
(hooks/use-effect! #(if selected? (focus!)
|
||||
(some-> (rum/deref *el-ref) (.blur))) [selected?])
|
||||
|
||||
(shui/trigger-as
|
||||
:div.ls-dummy-block.ls-block
|
||||
|
||||
{:style {:width "100%"
|
||||
;; The same as .dnd-separator
|
||||
:border-top (if hover
|
||||
"3px solid #ccc"
|
||||
nil)
|
||||
:margin-left 20}
|
||||
:ref *el-ref
|
||||
:tabIndex 0
|
||||
:on-click click-handler-fn
|
||||
:id idstr
|
||||
:blockid idstr
|
||||
:class (when selected? "selected")}
|
||||
|
||||
[:div.flex.items-center
|
||||
[:div.flex.items-center.mx-1 {:style {:height 24}}
|
||||
[:span.bullet-container.cursor
|
||||
[:span.bullet]]]
|
||||
|
||||
[:div.flex.flex-1.cursor-text
|
||||
{:on-drag-enter #(set-hover! true)
|
||||
:on-drag-over #(util/stop %)
|
||||
:on-drop drop-handler-fn
|
||||
:on-drag-leave #(set-hover! false)}
|
||||
[:span.opacity-70.text
|
||||
"Click here to edit..."]]]))))
|
||||
|
||||
(rum/defc add-button
|
||||
[args container-id]
|
||||
(let [*bullet-ref (rum/use-ref nil)]
|
||||
[:div.flex-1.flex-col.rounded-sm.add-button-link-wrap
|
||||
{:on-click (fn [e]
|
||||
[block container-id]
|
||||
(let [*ref (rum/use-ref nil)
|
||||
has-children? (:block/_parent block)]
|
||||
[:div.ls-block.block-add-button.flex-1.flex-col.rounded-sm.cursor-text.transition-opacity.ease-in.duration-100.!py-0
|
||||
{:class (if has-children?
|
||||
"opacity-0"
|
||||
"opacity-50")
|
||||
:data-blockId (:db/id block)
|
||||
:ref *ref
|
||||
:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(state/set-state! :editor/container-id container-id)
|
||||
(editor-handler/api-insert-new-block! "" args))
|
||||
:on-mouse-over #(dom/add-class! (rum/deref *bullet-ref) "opacity-50")
|
||||
:on-mouse-leave #(dom/remove-class! (rum/deref *bullet-ref) "opacity-50")
|
||||
(editor-handler/api-insert-new-block! ""
|
||||
{:block-uuid (:block/uuid block)}))
|
||||
:on-mouse-over (fn []
|
||||
(let [ref (rum/deref *ref)
|
||||
prev-block (util/get-prev-block-non-collapsed (rum/deref *ref) {:up-down? true})]
|
||||
(cond
|
||||
(and prev-block (dom/has-class? prev-block "is-blank"))
|
||||
(dom/add-class! ref "opacity-0")
|
||||
(and prev-block has-children?)
|
||||
(dom/add-class! ref "opacity-50")
|
||||
:else
|
||||
(dom/add-class! ref "opacity-100"))))
|
||||
:on-mouse-leave #(do
|
||||
(dom/remove-class! (rum/deref *ref) "opacity-50")
|
||||
(dom/remove-class! (rum/deref *ref) "opacity-100"))
|
||||
:on-key-down (fn [e]
|
||||
(util/stop e)
|
||||
(when (= "Enter" (util/ekey e))
|
||||
(state/set-state! :editor/container-id container-id)
|
||||
(editor-handler/api-insert-new-block! "" args)))
|
||||
(editor-handler/api-insert-new-block! "" block)))
|
||||
:tab-index 0}
|
||||
[:div.flex.flex-row
|
||||
[:div.flex.items-center {:style {:height 28
|
||||
@@ -219,8 +168,9 @@
|
||||
(cond
|
||||
(and
|
||||
(not block?)
|
||||
(not config/publishing?)
|
||||
(empty? children) block)
|
||||
(dummy-block block)
|
||||
(add-button block (:container-id config))
|
||||
|
||||
:else
|
||||
(let [document-mode? (state/sub :document/mode?)
|
||||
@@ -233,16 +183,9 @@
|
||||
config)
|
||||
config (common-handler/config-with-document-mode hiccup-config)
|
||||
blocks (if block? [block] (db/sort-by-order children block))]
|
||||
(let [add-button? (not (or config/publishing?
|
||||
(let [last-child-id (model/get-block-deep-last-open-child-id (db/get-db) (:db/id (last blocks)))
|
||||
block' (if last-child-id (db/entity last-child-id) (last blocks))
|
||||
link (:block/link block')]
|
||||
(string/blank? (:block/title (or link block'))))))]
|
||||
[:div.relative
|
||||
{:class (when add-button? "show-add-button")}
|
||||
(page-blocks-inner block blocks config sidebar? whiteboard? block-id)
|
||||
(let [args {:block-uuid block-id}]
|
||||
(add-button args (:container-id config)))]))))))
|
||||
[:div.relative
|
||||
(page-blocks-inner block blocks config sidebar? whiteboard? block-id)
|
||||
(add-button block (:container-id config))])))))
|
||||
|
||||
(rum/defc today-queries < rum/reactive
|
||||
[repo today? sidebar?]
|
||||
|
||||
@@ -214,21 +214,6 @@ html.is-native-ios {
|
||||
@apply focus:ring-0 focus:ring-offset-0;
|
||||
}
|
||||
|
||||
.ls-dummy-block {
|
||||
@apply mb-[20px] pt-[5px] pb-[3px] h-[28px];
|
||||
|
||||
&.selected {
|
||||
}
|
||||
|
||||
.bullet {
|
||||
@apply relative -top-[3px] left-[-2px];
|
||||
}
|
||||
|
||||
.text {
|
||||
@apply relative -top-[2px];
|
||||
}
|
||||
}
|
||||
|
||||
.ls-preview-popup {
|
||||
@apply pl-6;
|
||||
|
||||
@@ -251,16 +236,6 @@ html.is-native-ios {
|
||||
}
|
||||
}
|
||||
|
||||
.add-button-link-wrap {
|
||||
@apply invisible;
|
||||
}
|
||||
|
||||
.show-add-button {
|
||||
.add-button-link-wrap {
|
||||
@apply visible;
|
||||
}
|
||||
}
|
||||
|
||||
.ls-page-blocks {
|
||||
@apply min-h-[60px] overflow-hidden;
|
||||
}
|
||||
|
||||
@@ -76,8 +76,7 @@
|
||||
(when (string? value)
|
||||
(let [page-name (string/trim value)]
|
||||
(when-not (string/blank? page-name)
|
||||
(p/let [page (db-page-handler/<create-class! page-name {:redirect? false
|
||||
:create-first-block? false})]
|
||||
(p/let [page (db-page-handler/<create-class! page-name {:redirect? false})]
|
||||
(:block/uuid page))))))
|
||||
|
||||
(rum/defc class-select
|
||||
|
||||
@@ -388,8 +388,7 @@
|
||||
(let [journal (date/js-date->journal-title d)]
|
||||
(p/do!
|
||||
(when-not (db/get-page journal)
|
||||
(page-handler/<create! journal {:redirect? false
|
||||
:create-first-block? false}))
|
||||
(page-handler/<create! journal {:redirect? false}))
|
||||
(when (fn? on-change)
|
||||
(let [value (if datetime? (tc/to-long d) (db/get-page journal))]
|
||||
(on-change value)))
|
||||
@@ -596,7 +595,6 @@
|
||||
(do (log/error :msg "Given inline class does not exist" :inline-class inline-class)
|
||||
nil)))
|
||||
create-options {:redirect? false
|
||||
:create-first-block? false
|
||||
:tags (if inline-class-uuid
|
||||
[inline-class-uuid]
|
||||
;; Only 1st class b/c page normally has
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
[frontend.util :as util]
|
||||
[goog.dom :as gdom]
|
||||
[logseq.common.config :as common-config]
|
||||
[logseq.common.uuid :as common-uuid]
|
||||
[logseq.db :as ldb]
|
||||
[logseq.db.common.view :as db-view]
|
||||
[logseq.db.frontend.property :as db-property]
|
||||
@@ -1529,7 +1530,7 @@
|
||||
(let [lazy-item-render (fn [rows idx]
|
||||
(lazy-item rows idx (assoc option :list-view? true)
|
||||
(fn [block]
|
||||
(block-container (assoc config :list-view? true) block))))
|
||||
(block-container (assoc config :list-view? true :block-level 1) block))))
|
||||
list-cp (fn [rows]
|
||||
(when (seq rows)
|
||||
(ui/virtualized-list
|
||||
@@ -1699,7 +1700,7 @@
|
||||
(ldb/sort-by-order views)))
|
||||
|
||||
(defn- create-view!
|
||||
[view-parent view-feature-type]
|
||||
[view-parent view-feature-type {:keys [auto-triggered?]}]
|
||||
(when-let [page (db/get-case-page common-config/views-page-name)]
|
||||
(p/let [properties (cond->
|
||||
{:logseq.property/view-for (:db/id view-parent)
|
||||
@@ -1722,10 +1723,14 @@
|
||||
:all-pages
|
||||
"All pages"
|
||||
""))
|
||||
view-block-id (common-uuid/gen-uuid :view-block-uuid (str (:block/uuid view-parent) view-feature-type))
|
||||
result (editor-handler/api-insert-new-block! view-title
|
||||
{:page (:block/uuid page)
|
||||
:properties properties
|
||||
:edit-block? false})]
|
||||
(cond->
|
||||
{:page (:block/uuid page)
|
||||
:properties properties
|
||||
:edit-block? false}
|
||||
auto-triggered?
|
||||
(assoc :custom-uuid view-block-id)))]
|
||||
(db/entity [:block/uuid (:block/uuid result)]))))
|
||||
|
||||
(rum/defc views-tab < rum/reactive db-mixins/query
|
||||
@@ -1786,7 +1791,7 @@
|
||||
:title "Add new view"
|
||||
:class (str "!px-1 -ml-1 text-muted-foreground hover:text-foreground transition-opacity ease-in duration-300 " opacity)
|
||||
:on-click (fn []
|
||||
(p/let [view (create-view! view-parent view-feature-type)]
|
||||
(p/let [view (create-view! view-parent view-feature-type {:auto-triggered? false})]
|
||||
(set-views! (concat views [view]))))}
|
||||
(ui/icon "plus" {:size 15}))])
|
||||
|
||||
@@ -2147,7 +2152,7 @@
|
||||
(set-views! views)
|
||||
(when-not view-entity (set-view-entity! v)))
|
||||
(when (and view-parent view-feature-type (not view-entity))
|
||||
(let [new-view (c.m/<? (create-view! view-parent view-feature-type))]
|
||||
(let [new-view (c.m/<? (create-view! view-parent view-feature-type {:auto-triggered? true}))]
|
||||
(set-views! (concat views [new-view]))
|
||||
(set-view-entity! new-view))))))))))
|
||||
[])
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
[frontend.handler.property :as property-handler]
|
||||
[frontend.handler.property.util :as pu]
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.util.ref :as ref]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
[frontend.util.ref :as ref]
|
||||
[logseq.common.config :as common-config]
|
||||
[logseq.common.path :as path]
|
||||
[logseq.publishing.db :as publish-db]
|
||||
@@ -49,9 +49,9 @@
|
||||
url (if blob-res? href
|
||||
(assets-handler/normalize-asset-resource-url original-path))
|
||||
filename' (if (or asset-res? web-link? blob-res?) filename
|
||||
(some-> url (js/decodeURIComponent)
|
||||
(get-in-repo-assets-full-filename)
|
||||
(string/replace '"/" "_")))
|
||||
(some-> url (js/decodeURIComponent)
|
||||
(get-in-repo-assets-full-filename)
|
||||
(string/replace '"/" "_")))
|
||||
filekey (util/safe-sanitize-file-name
|
||||
(subs filename' 0 (- (count filename') (inc (count ext-name)))))]
|
||||
(when-let [key (and (not (string/blank? filekey))
|
||||
@@ -93,7 +93,7 @@
|
||||
(if-not page
|
||||
(let [label (:filename pdf-current)]
|
||||
(p/do!
|
||||
(page-handler/<create! page-name {:redirect? false :create-first-block? false
|
||||
(page-handler/<create! page-name {:redirect? false
|
||||
:split-namespace? false
|
||||
:format format
|
||||
:properties {:file
|
||||
|
||||
@@ -1062,9 +1062,7 @@
|
||||
;; load assets
|
||||
(hooks/use-effect!
|
||||
(fn []
|
||||
(p/then
|
||||
(pdf-utils/load-base-assets$)
|
||||
(fn [] (set-prepared! true))))
|
||||
(set-prepared! true))
|
||||
[])
|
||||
|
||||
;; refresh loader
|
||||
|
||||
@@ -123,11 +123,6 @@
|
||||
[]
|
||||
(common-uuid/gen-uuid))
|
||||
|
||||
(defn load-base-assets$
|
||||
[]
|
||||
(p/let [_ (util/js-load$ (str util/JS_ROOT "/pdfjs/pdf.js"))
|
||||
_ (util/js-load$ (str util/JS_ROOT "/pdf_viewer2.js"))]))
|
||||
|
||||
(defn get-page-from-el
|
||||
[^js/HTMLElement el]
|
||||
(when-let [^js page-el (and el (.closest el ".page"))]
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.util.ref :as ref]
|
||||
[frontend.state :as state]
|
||||
[frontend.util.ref :as ref]
|
||||
[promesa.core :as p]))
|
||||
|
||||
;; TODO: test
|
||||
@@ -64,7 +64,6 @@
|
||||
page-name
|
||||
{:redirect? false
|
||||
:format :markdown
|
||||
:create-first-block? false
|
||||
:properties properties}))
|
||||
|
||||
(defn create-zotero-page
|
||||
|
||||
@@ -474,7 +474,7 @@
|
||||
(comp
|
||||
(partition-by #(.-updated? ^FileTxn %))
|
||||
(map (fn [ts]
|
||||
(if (some-> (first ts) (.-updated?))
|
||||
(if (some-> ^js (first ts) (.-updated?))
|
||||
(partition-all n ts)
|
||||
(map list ts))))
|
||||
cat))
|
||||
@@ -1335,7 +1335,7 @@
|
||||
[^FileTxn filetxn origin-db-content]
|
||||
(go
|
||||
(cond
|
||||
(.renamed? filetxn)
|
||||
(.renamed? ^js filetxn)
|
||||
false
|
||||
(.-deleted? filetxn)
|
||||
false
|
||||
@@ -1532,66 +1532,66 @@
|
||||
|
||||
(defn- apply-filetxns
|
||||
[*sync-state graph-uuid base-path filetxns *paused]
|
||||
(go
|
||||
(cond
|
||||
(.renamed? (first filetxns))
|
||||
(let [^FileTxn filetxn (first filetxns)
|
||||
from-path (.-from-path filetxn)
|
||||
to-path (.-to-path filetxn)]
|
||||
(assert (= 1 (count filetxns)))
|
||||
(<! (<rename-local-file rsapi graph-uuid base-path
|
||||
(relative-path from-path)
|
||||
(relative-path to-path))))
|
||||
(let [^FileTxn filetxn (first filetxns)]
|
||||
(go
|
||||
(cond
|
||||
(.renamed? filetxn)
|
||||
(let [from-path (.-from-path filetxn)
|
||||
to-path (.-to-path filetxn)]
|
||||
(assert (= 1 (count filetxns)))
|
||||
(<! (<rename-local-file rsapi graph-uuid base-path
|
||||
(relative-path from-path)
|
||||
(relative-path to-path))))
|
||||
|
||||
(.-updated? (first filetxns))
|
||||
(let [repo (state/get-current-repo)
|
||||
txn->db-content-vec (->> filetxns
|
||||
(mapv
|
||||
#(when (is-journals-or-pages? %)
|
||||
[% (db/get-file repo (relative-path %))]))
|
||||
(remove nil?))]
|
||||
(.-updated? filetxn)
|
||||
(let [repo (state/get-current-repo)
|
||||
txn->db-content-vec (->> filetxns
|
||||
(mapv
|
||||
#(when (is-journals-or-pages? %)
|
||||
[% (db/get-file repo (relative-path %))]))
|
||||
(remove nil?))]
|
||||
|
||||
(doseq [relative-p (map relative-path filetxns)]
|
||||
(when-some [relative-p*
|
||||
(<! (<case-different-local-file-exist? graph-uuid rsapi base-path relative-p))]
|
||||
(let [recent-remote->local-file-item {:remote->local-type :delete
|
||||
:checksum nil
|
||||
:path relative-p*}]
|
||||
(println :debug "found case-different-same-local-file" relative-p relative-p*)
|
||||
(swap! *sync-state sync-state--add-recent-remote->local-files
|
||||
[recent-remote->local-file-item])
|
||||
(<! (<delete-local-files rsapi graph-uuid base-path [relative-p*]))
|
||||
(go (<! (timeout 5000))
|
||||
(swap! *sync-state sync-state--remove-recent-remote->local-files
|
||||
[recent-remote->local-file-item])))))
|
||||
(doseq [relative-p (map relative-path filetxns)]
|
||||
(when-some [relative-p*
|
||||
(<! (<case-different-local-file-exist? graph-uuid rsapi base-path relative-p))]
|
||||
(let [recent-remote->local-file-item {:remote->local-type :delete
|
||||
:checksum nil
|
||||
:path relative-p*}]
|
||||
(println :debug "found case-different-same-local-file" relative-p relative-p*)
|
||||
(swap! *sync-state sync-state--add-recent-remote->local-files
|
||||
[recent-remote->local-file-item])
|
||||
(<! (<delete-local-files rsapi graph-uuid base-path [relative-p*]))
|
||||
(go (<! (timeout 5000))
|
||||
(swap! *sync-state sync-state--remove-recent-remote->local-files
|
||||
[recent-remote->local-file-item])))))
|
||||
|
||||
(let [update-local-files-ch (if (state/enable-sync-diff-merge?)
|
||||
(<fetch-remote-and-update-local-files graph-uuid base-path (map relative-path filetxns))
|
||||
(<update-local-files rsapi graph-uuid base-path (map relative-path filetxns)))
|
||||
r (<! (<with-pause update-local-files-ch *paused))]
|
||||
(doseq [[filetxn origin-db-content] txn->db-content-vec]
|
||||
(when (<! (need-add-version-file? filetxn origin-db-content))
|
||||
(<! (<add-new-version rsapi repo (relative-path filetxn) origin-db-content))
|
||||
(put-sync-event! {:event :created-local-version-file
|
||||
:data {:graph-uuid graph-uuid
|
||||
:repo repo
|
||||
:path (relative-path filetxn)
|
||||
:epoch (tc/to-epoch (t/now))}})))
|
||||
r))
|
||||
(let [update-local-files-ch (if (state/enable-sync-diff-merge?)
|
||||
(<fetch-remote-and-update-local-files graph-uuid base-path (map relative-path filetxns))
|
||||
(<update-local-files rsapi graph-uuid base-path (map relative-path filetxns)))
|
||||
r (<! (<with-pause update-local-files-ch *paused))]
|
||||
(doseq [[filetxn origin-db-content] txn->db-content-vec]
|
||||
(when (<! (need-add-version-file? filetxn origin-db-content))
|
||||
(<! (<add-new-version rsapi repo (relative-path filetxn) origin-db-content))
|
||||
(put-sync-event! {:event :created-local-version-file
|
||||
:data {:graph-uuid graph-uuid
|
||||
:repo repo
|
||||
:path (relative-path filetxn)
|
||||
:epoch (tc/to-epoch (t/now))}})))
|
||||
r))
|
||||
|
||||
(.-deleted? (first filetxns))
|
||||
(let [filetxn (first filetxns)]
|
||||
(assert (= 1 (count filetxns)))
|
||||
(if (<! (<local-file-not-exist? graph-uuid rsapi base-path (relative-path filetxn)))
|
||||
(.-deleted? filetxn)
|
||||
(let [filetxn (first filetxns)]
|
||||
(assert (= 1 (count filetxns)))
|
||||
(if (<! (<local-file-not-exist? graph-uuid rsapi base-path (relative-path filetxn)))
|
||||
;; not exist, ignore
|
||||
true
|
||||
(let [r (<! (if (state/enable-sync-diff-merge?)
|
||||
(<apply-remote-deletion graph-uuid base-path [(relative-path filetxn)])
|
||||
(<delete-local-files rsapi graph-uuid base-path [(relative-path filetxn)])))]
|
||||
(if (and (instance? ExceptionInfo r)
|
||||
(string/index-of (str (ex-cause r)) "No such file or directory"))
|
||||
true
|
||||
r)))))))
|
||||
true
|
||||
(let [r (<! (if (state/enable-sync-diff-merge?)
|
||||
(<apply-remote-deletion graph-uuid base-path [(relative-path filetxn)])
|
||||
(<delete-local-files rsapi graph-uuid base-path [(relative-path filetxn)])))]
|
||||
(if (and (instance? ExceptionInfo r)
|
||||
(string/index-of (str (ex-cause r)) "No such file or directory"))
|
||||
true
|
||||
r))))))))
|
||||
|
||||
(declare sync-state-reset-full-remote->local-files)
|
||||
(defn apply-filetxns-partitions
|
||||
@@ -1646,7 +1646,7 @@
|
||||
:chan)))
|
||||
|
||||
(defmethod need-sync-remote? :max [_] true)
|
||||
(defmethod need-sync-remote? :txid [[txid remote->local-syncer]]
|
||||
(defmethod need-sync-remote? :txid [[txid ^Remote->LocalSyncer remote->local-syncer]]
|
||||
(let [remote-txid txid
|
||||
local-txid (.-txid remote->local-syncer)]
|
||||
(or (nil? local-txid)
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
is still some file-specific tech debt to remove from create!"
|
||||
(:require [clojure.string :as string]
|
||||
[datascript.core :as d]
|
||||
[dommy.core :as dom]
|
||||
[frontend.config :as config]
|
||||
[frontend.db :as db]
|
||||
[frontend.db.conn :as conn]
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.block :as block-handler]
|
||||
[frontend.handler.config :as config-handler]
|
||||
[frontend.handler.db-based.editor :as db-editor-handler]
|
||||
[frontend.handler.notification :as notification]
|
||||
@@ -39,12 +39,11 @@
|
||||
(defn <create!
|
||||
([title]
|
||||
(<create! title {}))
|
||||
([title {:keys [redirect?]
|
||||
([title {:keys [redirect? today-journal?]
|
||||
:or {redirect? true}
|
||||
:as options}]
|
||||
(when (string? title)
|
||||
(p/let [repo (state/get-current-repo)
|
||||
conn (db/get-db repo false)
|
||||
db-based? (config/db-based-graph? repo)
|
||||
title (if (and db-based? (string/includes? title " #")) ; tagged page
|
||||
(wrap-tags title)
|
||||
@@ -70,8 +69,14 @@
|
||||
page (db/get-page (or page-uuid title'))]
|
||||
(when redirect?
|
||||
(route-handler/redirect-to-page! page-uuid)
|
||||
(when-let [first-block (ldb/get-first-child @conn (:db/id page))]
|
||||
(block-handler/edit-block! first-block :max {:container-id :unknown-container})))
|
||||
(when-not today-journal?
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(when-let [block-add-button (->> (dom/sel ".block-add-button")
|
||||
(filter #(= (str (:db/id page)) (dom/attr % "data-blockId")))
|
||||
first)]
|
||||
(.click block-add-button)))
|
||||
200)))
|
||||
page)))))))
|
||||
|
||||
;; favorite fns
|
||||
|
||||
@@ -95,8 +95,7 @@
|
||||
[chosen chosen-result class? edit-content current-pos last-pattern]
|
||||
(let [tag (string/trim chosen)
|
||||
edit-block (state/get-edit-block)
|
||||
create-opts {:redirect? false
|
||||
:create-first-block? false}]
|
||||
create-opts {:redirect? false}]
|
||||
(when (:block/uuid edit-block)
|
||||
(p/let [result (when-not (de/entity? chosen-result) ; page not exists yet
|
||||
(if class?
|
||||
|
||||
@@ -2593,8 +2593,14 @@
|
||||
(string/trim value)))
|
||||
(save-block! repo uuid value))
|
||||
|
||||
(if property-value-container?
|
||||
(cond
|
||||
(dom/has-class? sibling-block "block-add-button")
|
||||
(.click sibling-block)
|
||||
|
||||
property-value-container?
|
||||
(focus-trigger current-block sibling-block)
|
||||
|
||||
:else
|
||||
(let [new-uuid (cljs.core/uuid sibling-block-id)
|
||||
block (db/entity [:block/uuid new-uuid])]
|
||||
(edit-block! block
|
||||
@@ -2650,18 +2656,25 @@
|
||||
(first (dom/by-class sibling-block "ls-block"))))
|
||||
sibling-block)]
|
||||
(when sibling-block
|
||||
(if-let [sibling-block-id (dom/attr sibling-block "blockid")]
|
||||
(do
|
||||
(let [content (:block/title block)
|
||||
value (state/get-edit-content)]
|
||||
(when (and value (not= (clean-content! repo format content) (string/trim value)))
|
||||
(save-block! repo uuid value)))
|
||||
|
||||
(let [content (:block/title block)
|
||||
value (state/get-edit-content)]
|
||||
(when (and value (not= (clean-content! repo format content) (string/trim value)))
|
||||
(save-block! repo uuid value)))
|
||||
(let [sibling-block-id (dom/attr sibling-block "blockid")]
|
||||
(cond
|
||||
sibling-block-id
|
||||
(let [container-id (some-> (dom/attr sibling-block "containerid") js/parseInt)
|
||||
block (db/entity repo [:block/uuid (cljs.core/uuid sibling-block-id)])]
|
||||
(edit-block! block pos {:container-id container-id})))
|
||||
(when (property-value-node? sibling-block)
|
||||
(focus-trigger editing-block sibling-block))))))
|
||||
(edit-block! block pos {:container-id container-id}))
|
||||
|
||||
(property-value-node? sibling-block)
|
||||
(focus-trigger editing-block sibling-block)
|
||||
|
||||
(dom/has-class? sibling-block "block-add-button")
|
||||
(.click sibling-block)
|
||||
|
||||
:else
|
||||
nil)))))
|
||||
|
||||
(defn keydown-arrow-handler
|
||||
[direction]
|
||||
@@ -3887,9 +3900,11 @@
|
||||
(let [block (or (db/entity (:db/id block)) block)]
|
||||
(or
|
||||
(util/collapsed? block)
|
||||
(and (or (:list-view? config) (:ref? config))
|
||||
(integer? (:block-level config))
|
||||
(>= (:block-level config) (state/get-ref-open-blocks-level)))
|
||||
(and (or (:view? config) (:popup? config))
|
||||
(or (ldb/page? block)
|
||||
(some? (:block/_parent block))
|
||||
(:table-block-title? config))))))
|
||||
|
||||
(defn batch-set-heading!
|
||||
|
||||
@@ -69,7 +69,6 @@
|
||||
(try (page-handler/<create! title {:redirect? false
|
||||
:format page-format
|
||||
:uuid uuid
|
||||
:create-first-block? false
|
||||
:properties properties
|
||||
:whiteboard? whiteboard?})
|
||||
(catch :default e
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
[frontend.mobile.util :as mobile-util]
|
||||
[frontend.modules.outliner.op :as outliner-op]
|
||||
[frontend.modules.outliner.ui :as ui-outliner-tx]
|
||||
[frontend.util.ref :as ref]
|
||||
[frontend.state :as state]
|
||||
[frontend.util :as util]
|
||||
[frontend.util.cursor :as cursor]
|
||||
[frontend.util.page :as page-util]
|
||||
[frontend.util.ref :as ref]
|
||||
[frontend.util.url :as url-util]
|
||||
[goog.functions :refer [debounce]]
|
||||
[goog.object :as gobj]
|
||||
@@ -278,7 +278,6 @@
|
||||
(when-not (de/entity? chosen-result)
|
||||
(<create! chosen'
|
||||
{:redirect? false
|
||||
:create-first-block? false
|
||||
:split-namespace? true})))
|
||||
ref-text' (if result
|
||||
(let [title (:block/title result)]
|
||||
@@ -335,9 +334,6 @@
|
||||
(p/do!
|
||||
(<create! title {:redirect? false
|
||||
:split-namespace? false
|
||||
:create-first-block? (if db-based?
|
||||
true
|
||||
(not (state/get-default-journal-template)))
|
||||
:today-journal? true})
|
||||
(when-not db-based? (state/pub-event! [:journal/insert-template today-page]))
|
||||
(ui-handler/re-render-root!)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
(when (> coll-size data-count-threshold)
|
||||
(vswap! *ref-hash->coll-size assoc @*ref-hash coll-size)
|
||||
(vswap! *ref-hash->ref assoc @*ref-hash ref))
|
||||
(let [watches-count (count (.-watches ref))]
|
||||
(let [watches-count (count (.-watches ^js ref))]
|
||||
(when (> watches-count watches-count-threshold)
|
||||
(vswap! *ref-hash->watches-count assoc @*ref-hash watches-count)
|
||||
(vswap! *ref-hash->ref assoc @*ref-hash ref))))))
|
||||
@@ -120,5 +120,4 @@
|
||||
:custom-key-fn (fn [args result] {:a args :r result}))
|
||||
|
||||
(mem-leak-detect)
|
||||
[@*ref-hash->coll-size @*ref-hash->watches-count]
|
||||
)
|
||||
[@*ref-hash->coll-size @*ref-hash->watches-count])
|
||||
|
||||
@@ -217,3 +217,11 @@
|
||||
(defn fix-broken-graph!
|
||||
[graph]
|
||||
(state/<invoke-db-worker :thread-api/fix-broken-graph graph))
|
||||
|
||||
(defn gc-graph!
|
||||
[graph]
|
||||
(p/do!
|
||||
(state/<invoke-db-worker :thread-api/gc-graph graph)
|
||||
(state/pub-event! [:notification/show
|
||||
{:content "Graph gc successfully!"
|
||||
:status :success}])))
|
||||
|
||||
@@ -599,6 +599,10 @@
|
||||
:db-graph? true
|
||||
:fn #(repo-handler/fix-broken-graph! (state/get-current-repo))}
|
||||
|
||||
:dev/gc-graph {:binding []
|
||||
:inactive (not (state/developer-mode?))
|
||||
:fn #(repo-handler/gc-graph! (state/get-current-repo))}
|
||||
|
||||
:dev/replace-graph-with-db-file {:binding []
|
||||
:inactive (or (not (util/electron?)) (not (state/developer-mode?)))
|
||||
:fn :frontend.handler.common.developer/replace-graph-with-db-file}
|
||||
@@ -876,6 +880,7 @@
|
||||
:dev/replace-graph-with-db-file
|
||||
:dev/validate-db
|
||||
:dev/fix-broken-graph
|
||||
:dev/gc-graph
|
||||
:dev/rtc-stop
|
||||
:dev/rtc-start
|
||||
:ui/customize-appearance])
|
||||
@@ -1072,6 +1077,7 @@
|
||||
:dev/replace-graph-with-db-file
|
||||
:dev/validate-db
|
||||
:dev/fix-broken-graph
|
||||
:dev/gc-graph
|
||||
:dev/rtc-stop
|
||||
:dev/rtc-start
|
||||
:ui/clear-all-notifications]
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
[frontend.modules.shortcut.data-helper :as dh]
|
||||
[frontend.modules.shortcut.utils :as shortcut-utils]
|
||||
[frontend.state :as state]
|
||||
[frontend.util :as util]
|
||||
[frontend.storage :as storage]
|
||||
[frontend.util :as util]
|
||||
[goog.events :as events]
|
||||
[goog.ui.KeyboardShortcutHandler.EventType :as EventType]
|
||||
[lambdaisland.glogi :as log])
|
||||
@@ -225,7 +225,7 @@
|
||||
(defn listen-all! []
|
||||
(doseq [{:keys [handler group dispatch-fn]} (vals @*installed-handlers)
|
||||
:when (not= group :shortcut.handler/misc)]
|
||||
(if (.isDisposed handler)
|
||||
(if (.isDisposed ^js handler)
|
||||
(install-shortcut-handler! group {})
|
||||
(events/listen handler EventType/SHORTCUT_TRIGGERED dispatch-fn))))
|
||||
|
||||
@@ -282,15 +282,15 @@
|
||||
(dissoc id)
|
||||
|
||||
(and global?
|
||||
(or (string? binding)
|
||||
(vector? binding)
|
||||
(boolean? binding)))
|
||||
(or (string? binding)
|
||||
(vector? binding)
|
||||
(boolean? binding)))
|
||||
(assoc id binding)))]
|
||||
;; TODO: exclude current graph config shortcuts
|
||||
(config-handler/set-config!
|
||||
:shortcuts (into-shortcuts (:shortcuts (state/get-graph-config))))
|
||||
:shortcuts (into-shortcuts (:shortcuts (state/get-graph-config))))
|
||||
(if (util/electron?)
|
||||
(global-config-handler/set-global-config-kv!
|
||||
:shortcuts (into-shortcuts (:shortcuts (state/get-global-config))))
|
||||
:shortcuts (into-shortcuts (:shortcuts (state/get-global-config))))
|
||||
;; web browser platform
|
||||
(storage/set :ls-shortcuts (into-shortcuts (storage/get :ls-shortcuts)))))))
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
[:or :string :keyword]
|
||||
:string]]
|
||||
[:ref/default-open-blocks-level :int]
|
||||
[:ref/linked-references-collapsed-threshold :int]
|
||||
[:graph/settings [:map-of :keyword [:or :boolean :int :nil]]]
|
||||
[:graph/forcesettings [:map-of :keyword :int]]
|
||||
[:favorites [:vector :string]]
|
||||
|
||||
@@ -619,24 +619,13 @@ should be done through this fn in order to get global config and config defaults
|
||||
(get-in @state [:me :settings :start-of-week])
|
||||
6))
|
||||
|
||||
;; TODO: support this later
|
||||
(comment
|
||||
(defn get-ref-open-blocks-level
|
||||
[]
|
||||
(or
|
||||
(when-let [value (:ref/default-open-blocks-level (get-config))]
|
||||
(when (integer? value)
|
||||
value))
|
||||
2)))
|
||||
|
||||
(comment
|
||||
(defn get-linked-references-collapsed-threshold
|
||||
[]
|
||||
(or
|
||||
(when-let [value (:ref/linked-references-collapsed-threshold (get-config))]
|
||||
(when (integer? value)
|
||||
value))
|
||||
100)))
|
||||
(defn get-ref-open-blocks-level
|
||||
[]
|
||||
(or
|
||||
(when-let [value (:ref/default-open-blocks-level (get-config))]
|
||||
(when (pos-int? value)
|
||||
(min value 9)))
|
||||
2))
|
||||
|
||||
(defn get-export-bullet-indentation
|
||||
[]
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
{:page-uuid (:block/uuid (d/entity db journal-day))}
|
||||
(let [formatter (:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))
|
||||
title (date-time-util/format (t/to-default-time-zone (tc/to-date-time next-time-long)) formatter)]
|
||||
(worker-db-page/create db title {:create-first-block? false})))
|
||||
(worker-db-page/create db title {})))
|
||||
value (if date? [:block/uuid page-uuid] next-time-long)]
|
||||
(concat
|
||||
tx-data
|
||||
|
||||
@@ -43,7 +43,9 @@
|
||||
[logseq.db.common.view :as db-view]
|
||||
[logseq.db.frontend.schema :as db-schema]
|
||||
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
|
||||
[logseq.db.sqlite.debug :as sqlite-debug]
|
||||
[logseq.db.sqlite.export :as sqlite-export]
|
||||
[logseq.db.sqlite.gc :as sqlite-gc]
|
||||
[logseq.db.sqlite.util :as sqlite-util]
|
||||
[logseq.outliner.op :as outliner-op]
|
||||
[me.tonsky.persistent-sorted-set :as set :refer [BTSet]]
|
||||
@@ -141,80 +143,14 @@
|
||||
(rebuild-db-from-datoms! conn sqlite-db)
|
||||
(worker-util/post-message :notification ["The graph has been successfully rebuilt." :success false]))))
|
||||
|
||||
(comment
|
||||
(defn- gc-kvs-table!
|
||||
[^Object db]
|
||||
(let [schema (some->> (.exec db #js {:sql "select content from kvs where addr = 0"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
ffirst
|
||||
sqlite-util/transit-read)
|
||||
result (->> (.exec db #js {:sql "select addr, addresses from kvs"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
(map (fn [[addr addresses]]
|
||||
[addr (bean/->clj (js/JSON.parse addresses))])))
|
||||
used-addresses (set (concat (mapcat second result)
|
||||
[0 1 (:eavt schema) (:avet schema) (:aevt schema)]))
|
||||
unused-addresses (clojure.set/difference (set (map first result)) used-addresses)]
|
||||
(when unused-addresses
|
||||
(prn :debug :db-gc :unused-addresses unused-addresses)
|
||||
(.transaction db (fn [tx]
|
||||
(doseq [addr unused-addresses]
|
||||
(.exec tx #js {:sql "Delete from kvs where addr = ?"
|
||||
:bind #js [addr]}))))))))
|
||||
|
||||
(defn- find-missing-addresses
|
||||
[conn ^Object db & {:keys [delete-addrs]}]
|
||||
(let [schema (some->> (.exec db #js {:sql "select content from kvs where addr = 0"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
ffirst
|
||||
sqlite-util/transit-read)
|
||||
result (->> (.exec db #js {:sql "select addr, addresses from kvs"
|
||||
:rowMode "array"})
|
||||
bean/->clj
|
||||
(keep (fn [[addr addresses]]
|
||||
(when-not (and delete-addrs (delete-addrs addr))
|
||||
[addr (bean/->clj (js/JSON.parse addresses))]))))
|
||||
used-addresses (-> (set (concat (mapcat second result)
|
||||
[0 1 (:eavt schema) (:avet schema) (:aevt schema)]))
|
||||
(clojure.set/difference delete-addrs))
|
||||
missing-addresses (clojure.set/difference used-addresses (set (map first result)))]
|
||||
(when (seq missing-addresses)
|
||||
(let [version-in-db (when conn (db-schema/parse-schema-version (or (:kv/value (d/entity @conn :logseq.kv/schema-version)) 0)))
|
||||
compare-result (when version-in-db (db-schema/compare-schema-version version-in-db "64.8"))]
|
||||
(when (and compare-result (not (neg? compare-result))) ; >= 64.8
|
||||
(worker-util/post-message :capture-error
|
||||
{:error "db-missing-addresses-v2"
|
||||
:payload {:missing-addresses (str missing-addresses)
|
||||
:db-schema-version (str version-in-db)}}))))
|
||||
missing-addresses))
|
||||
|
||||
(defn upsert-addr-content!
|
||||
"Upsert addr+data-seq. Update sqlite-cli/upsert-addr-content! when making changes"
|
||||
[db data delete-addrs*]
|
||||
(let [_delete-addrs (clojure.set/difference (set delete-addrs*) #{0 1})]
|
||||
(assert (some? db) "sqlite db not exists")
|
||||
(.transaction db (fn [tx]
|
||||
(doseq [item data]
|
||||
(.exec tx #js {:sql "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses"
|
||||
:bind item}))))
|
||||
;; (when (seq delete-addrs)
|
||||
;; (let [result (.exec db #js {:sql get-to-delete-unused-addresses-sql
|
||||
;; :bind (js/JSON.stringify (clj->js delete-addrs))
|
||||
;; :rowMode "array"})
|
||||
;; non-refed-addrs (map #(aget % 0) result)]
|
||||
;; (when (seq non-refed-addrs)
|
||||
;; (.transaction db (fn [tx]
|
||||
;; (doseq [addr non-refed-addrs]
|
||||
;; (.exec tx #js {:sql "Delete from kvs where addr = ?"
|
||||
;; :bind #js [addr]})))))
|
||||
;; (let [missing-addrs (when worker-util/dev?
|
||||
;; (seq (find-missing-addresses nil db {:delete-addrs non-refed-addrs})))]
|
||||
;; (when (seq missing-addrs)
|
||||
;; (worker-util/post-message :notification [(str "Bug!! Missing addresses: " missing-addrs) :error false])))))
|
||||
))
|
||||
[db data]
|
||||
(assert (some? db) "sqlite db not exists")
|
||||
(.transaction db (fn [tx]
|
||||
(doseq [item data]
|
||||
(.exec tx #js {:sql "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses"
|
||||
:bind item})))))
|
||||
|
||||
(defn restore-data-from-addr
|
||||
"Update sqlite-cli/restore-data-from-addr when making changes"
|
||||
@@ -236,15 +172,8 @@
|
||||
"Update sqlite-cli/new-sqlite-storage when making changes"
|
||||
[^Object db]
|
||||
(reify IStorage
|
||||
(-store [_ addr+data-seq delete-addrs]
|
||||
(let [used-addrs (set (mapcat
|
||||
(fn [[addr data]]
|
||||
(cons addr
|
||||
(when (map? data)
|
||||
(:addresses data))))
|
||||
addr+data-seq))
|
||||
delete-addrs (remove used-addrs delete-addrs)
|
||||
data (map
|
||||
(-store [_ addr+data-seq _delete-addrs]
|
||||
(let [data (map
|
||||
(fn [[addr data]]
|
||||
(let [data' (if (map? data) (dissoc data :addresses) data)
|
||||
addresses (when (map? data)
|
||||
@@ -254,7 +183,7 @@
|
||||
:$content (sqlite-util/transit-write data')
|
||||
:$addresses addresses}))
|
||||
addr+data-seq)]
|
||||
(upsert-addr-content! db data delete-addrs)))
|
||||
(upsert-addr-content! db data)))
|
||||
|
||||
(-restore [_ addr]
|
||||
(restore-data-from-addr db addr))))
|
||||
@@ -313,6 +242,20 @@
|
||||
(.exec db "PRAGMA locking_mode=exclusive")
|
||||
(.exec db "PRAGMA journal_mode=WAL"))
|
||||
|
||||
(defn- gc-sqlite-dbs!
|
||||
"Gc main db weekly and rtc ops db each time when opening it"
|
||||
[sqlite-db client-ops-db datascript-conn {:keys [full-gc?]}]
|
||||
(let [last-gc-at (:kv/value (d/entity @datascript-conn :logseq.kv/graph-last-gc-at))]
|
||||
(when (or full-gc?
|
||||
(nil? last-gc-at)
|
||||
(not (number? last-gc-at))
|
||||
(> (- (common-util/time-ms) last-gc-at) (* 3 24 3600 1000))) ; 3 days ago
|
||||
(println :debug "gc current graph")
|
||||
(doseq [db [sqlite-db client-ops-db]]
|
||||
(sqlite-gc/gc-kvs-table! db {:full-gc? full-gc?}))
|
||||
(d/transact! datascript-conn [{:db/ident :logseq.kv/graph-last-gc-at
|
||||
:kv/value (common-util/time-ms)}]))))
|
||||
|
||||
(defn- create-or-open-db!
|
||||
[repo {:keys [config import-type datoms] :as opts}]
|
||||
(when-not (worker-state/get-sqlite-conn repo)
|
||||
@@ -354,10 +297,19 @@
|
||||
(select-keys opts [:import-type :graph-git-sha]))]
|
||||
(d/transact! conn initial-data {:initial-db? true})))
|
||||
|
||||
(gc-sqlite-dbs! db client-ops-db conn {})
|
||||
|
||||
;; TODO: remove this once we can ensure there's no bug for missing addresses
|
||||
;; because it's slow for large graphs
|
||||
(when-not import-type
|
||||
(when-let [missing-addresses (seq (find-missing-addresses conn db))]
|
||||
(when-let [missing-addresses (seq (sqlite-debug/find-missing-addresses db))]
|
||||
(let [version-in-db (when conn (db-schema/parse-schema-version (or (:kv/value (d/entity @conn :logseq.kv/schema-version)) 0)))
|
||||
compare-result (when version-in-db (db-schema/compare-schema-version version-in-db "64.8"))]
|
||||
(when (and compare-result (not (neg? compare-result))) ; >= 64.8
|
||||
(worker-util/post-message :capture-error
|
||||
{:error "db-missing-addresses-v2"
|
||||
:payload {:missing-addresses (str missing-addresses)
|
||||
:db-schema-version (str version-in-db)}})))
|
||||
(worker-util/post-message :notification ["It seems that the DB has been broken. Please run the command `Fix current broken graph`." :error false])
|
||||
(throw (ex-info "DB missing addresses" {:missing-addresses missing-addresses}))))
|
||||
|
||||
@@ -777,6 +729,14 @@
|
||||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(file-reset/reset-file! repo conn file-path content opts)))
|
||||
|
||||
(def-thread-api :thread-api/gc-graph
|
||||
[repo]
|
||||
(let [{:keys [db client-ops]} (get @*sqlite-conns repo)
|
||||
conn (get @*datascript-conns repo)]
|
||||
(when (and db conn)
|
||||
(gc-sqlite-dbs! db client-ops conn {:full-gc? true})
|
||||
nil)))
|
||||
|
||||
(comment
|
||||
(def-thread-api :general/dangerousRemoveAllDbs
|
||||
[]
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
(defn create!
|
||||
"Create page. Has the following options:
|
||||
|
||||
* :create-first-block? - when true, create an empty block if the page is empty.
|
||||
* :uuid - when set, use this uuid instead of generating a new one.
|
||||
* :class? - when true, adds a :block/tags ':logseq.class/Tag'
|
||||
* :whiteboard? - when true, adds a :block/tags ':logseq.class/Whiteboard'
|
||||
|
||||
@@ -7,13 +7,11 @@
|
||||
[logseq.common.util.namespace :as ns-util]
|
||||
[logseq.db :as ldb]
|
||||
[logseq.db.common.entity-plus :as entity-plus]
|
||||
[logseq.db.common.order :as db-order]
|
||||
[logseq.db.frontend.class :as db-class]
|
||||
[logseq.db.frontend.entity-util :as entity-util]
|
||||
[logseq.db.frontend.malli-schema :as db-malli-schema]
|
||||
[logseq.db.frontend.property :as db-property]
|
||||
[logseq.db.frontend.property.build :as db-property-build]
|
||||
[logseq.db.sqlite.util :as sqlite-util]
|
||||
[logseq.graph-parser.block :as gp-block]
|
||||
[logseq.graph-parser.text :as text]
|
||||
[logseq.outliner.validate :as outliner-validate]))
|
||||
@@ -75,16 +73,6 @@
|
||||
title (common-util/remove-boundary-slashes title)]
|
||||
title))
|
||||
|
||||
(defn build-first-block-tx
|
||||
[page-uuid]
|
||||
(let [page-id [:block/uuid page-uuid]]
|
||||
[(sqlite-util/block-with-timestamps
|
||||
{:block/uuid (ldb/new-block-id)
|
||||
:block/page page-id
|
||||
:block/parent page-id
|
||||
:block/order (db-order/gen-key nil nil)
|
||||
:block/title ""})]))
|
||||
|
||||
(defn- get-page-by-parent-name
|
||||
[db parent-title child-title]
|
||||
(some->>
|
||||
@@ -168,10 +156,9 @@
|
||||
(defn create
|
||||
"Pure function without side effects"
|
||||
[db title*
|
||||
{:keys [create-first-block? tags properties uuid persist-op? whiteboard?
|
||||
{:keys [tags properties uuid persist-op? whiteboard?
|
||||
class? today-journal? split-namespace?]
|
||||
:or {create-first-block? true
|
||||
properties nil
|
||||
:or {properties nil
|
||||
uuid nil
|
||||
persist-op? true}
|
||||
:as options}]
|
||||
@@ -221,17 +208,10 @@
|
||||
|
||||
(let [page-uuid (:block/uuid page)
|
||||
page-txs (build-page-tx db properties page (select-keys options [:whiteboard? :class? :tags]))
|
||||
first-block-tx (when (and
|
||||
(nil? (d/entity db [:block/uuid page-uuid]))
|
||||
create-first-block?
|
||||
(not (or whiteboard? class?))
|
||||
page-txs)
|
||||
(build-first-block-tx (:block/uuid (first page-txs))))
|
||||
txs (concat
|
||||
;; transact doesn't support entities
|
||||
(remove de/entity? parents)
|
||||
page-txs
|
||||
first-block-tx)
|
||||
page-txs)
|
||||
tx-meta (cond-> {:persist-op? persist-op?
|
||||
:outliner-op :create-page}
|
||||
today-journal?
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
[logseq.db.common.order :as db-order]
|
||||
[logseq.graph-parser.block :as gp-block]
|
||||
[logseq.graph-parser.property :as gp-property]
|
||||
[logseq.graph-parser.text :as text]
|
||||
[logseq.outliner.core :as outliner-core]))
|
||||
[logseq.graph-parser.text :as text]))
|
||||
|
||||
(defn- file-based-properties-block
|
||||
[repo conn config date-formatter properties format page]
|
||||
@@ -53,21 +52,9 @@
|
||||
page-name (common-util/page-name-sanity-lc title)]
|
||||
[title page-name]))
|
||||
|
||||
(defn- build-first-block-tx
|
||||
[page-uuid format]
|
||||
(let [page-id [:block/uuid page-uuid]]
|
||||
[(outliner-core/block-with-timestamps
|
||||
{:block/uuid (ldb/new-block-id)
|
||||
:block/page page-id
|
||||
:block/parent page-id
|
||||
:block/order (db-order/gen-key nil nil)
|
||||
:block/title ""
|
||||
:block/format format})]))
|
||||
|
||||
(defn create!
|
||||
[repo conn config title {:keys [create-first-block? format properties uuid persist-op? whiteboard? today-journal?]
|
||||
:or {create-first-block? true
|
||||
format nil
|
||||
[repo conn config title {:keys [format properties uuid persist-op? today-journal?]
|
||||
:or {format nil
|
||||
properties nil
|
||||
uuid nil
|
||||
persist-op? true}
|
||||
@@ -105,16 +92,9 @@
|
||||
(fn [p]
|
||||
(assoc p :block/namespace [:block/uuid (:block/uuid (last txs))])))
|
||||
page-txs)
|
||||
first-block-tx (when (and
|
||||
(nil? (d/entity @conn [:block/uuid page-uuid]))
|
||||
create-first-block?
|
||||
(not whiteboard?)
|
||||
page-txs)
|
||||
(build-first-block-tx (:block/uuid (first page-txs)) format))
|
||||
txs (concat
|
||||
txs
|
||||
page-txs
|
||||
first-block-tx)]
|
||||
page-txs)]
|
||||
(when (seq txs)
|
||||
(ldb/transact! conn txs (cond-> {:persist-op? persist-op?
|
||||
:outliner-op :create-page}
|
||||
|
||||
@@ -656,7 +656,7 @@
|
||||
[name ^js properties ^js opts]
|
||||
(let [properties (bean/->clj properties)
|
||||
db-base? (config/db-based-graph? (state/get-current-repo))
|
||||
{:keys [redirect createFirstBlock format journal]} (bean/->clj opts)]
|
||||
{:keys [redirect format journal]} (bean/->clj opts)]
|
||||
(p/let [page (<pull-block name)
|
||||
new-page (when-not page
|
||||
(page-handler/<create!
|
||||
@@ -664,7 +664,6 @@
|
||||
(cond->
|
||||
{:redirect? (if (boolean? redirect) redirect true)
|
||||
:journal? journal
|
||||
:create-first-block? (if (boolean? createFirstBlock) createFirstBlock true)
|
||||
:format format}
|
||||
(not db-base?)
|
||||
(assoc :properties properties))))
|
||||
@@ -741,7 +740,7 @@
|
||||
page-name (when page-name (util/page-name-sanity-lc page-name))
|
||||
_ (when (and page-name
|
||||
(nil? (ldb/get-page (db/get-db) page-name)))
|
||||
(page-handler/<create! block-uuid-or-page-name {:create-first-block? false}))
|
||||
(page-handler/<create! block-uuid-or-page-name {}))
|
||||
custom-uuid (or customUUID (:id properties))
|
||||
custom-uuid (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
|
||||
edit-block? (if (nil? focus) true focus)
|
||||
@@ -1067,7 +1066,6 @@
|
||||
page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
|
||||
_ (and page-not-exist? (page-handler/<create! uuid-or-page-name
|
||||
{:redirect? false
|
||||
:create-first-block? false
|
||||
:format (state/get-preferred-format)}))]
|
||||
(when-let [block (db-model/get-page uuid-or-page-name)]
|
||||
(-> (api-block/<sync-children-blocks! block)
|
||||
@@ -1085,7 +1083,6 @@
|
||||
page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
|
||||
_ (and page-not-exist? (page-handler/<create! uuid-or-page-name
|
||||
{:redirect? false
|
||||
:create-first-block? false
|
||||
:format (state/get-preferred-format)}))]
|
||||
(when-let [block (db-model/get-page uuid-or-page-name)]
|
||||
(let [target (str (:block/uuid block))]
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
(when-let [page (some-> v (str) (string/trim))]
|
||||
(let [id (:db/id (ldb/get-case-page (conn/get-db) page))]
|
||||
(if (nil? id)
|
||||
(-> (page-handler/<create! page {:redirect? false :create-first-block? false})
|
||||
(-> (page-handler/<create! page {:redirect? false})
|
||||
(p/then #(:db/id %)))
|
||||
id))))
|
||||
(p/all)
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
:dev/replace-graph-with-db-file "(Dev) Replace graph with its db.sqlite file"
|
||||
:dev/validate-db "(Dev) Validate current graph"
|
||||
:dev/fix-broken-graph "Fix current broken graph"
|
||||
:dev/gc-graph "(Dev) Garbage collect graph (remove unused data in SQLite)"
|
||||
:dev/rtc-stop "(Dev) RTC Stop"
|
||||
:dev/rtc-start "(Dev) RTC Start"
|
||||
:window/close "Close window"}}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
(use-fixtures :each start-and-destroy-db)
|
||||
|
||||
(deftest get-all-classes-test
|
||||
(let [opts {:redirect? false :create-first-block? false :class? true}
|
||||
(let [opts {:redirect? false :class? true}
|
||||
_ (test-helper/create-page! "class1" opts)
|
||||
_ (test-helper/create-page! "class2" opts)]
|
||||
(is (= (set
|
||||
@@ -34,7 +34,7 @@
|
||||
(set (map :block/title (model/get-all-classes repo)))))))
|
||||
|
||||
(deftest ^:fix-me get-class-objects-test
|
||||
(let [opts {:redirect? false :create-first-block? false :class? true}
|
||||
(let [opts {:redirect? false}
|
||||
_ (test-helper/create-page! "class1" opts)
|
||||
class (db/get-case-page "class1")
|
||||
_ (test-helper/save-block! repo fbid "Block 1" {:tags ["class1"]})]
|
||||
@@ -53,14 +53,14 @@
|
||||
(:db/id (db/entity [:block/uuid sbid]))])))))
|
||||
|
||||
(deftest hidden-page-test
|
||||
(let [opts {:redirect? false :create-first-block? false}
|
||||
(let [opts {:redirect? false}
|
||||
_ (test-helper/create-page! "page 1" opts)]
|
||||
(is (false? (model/hidden-page? (db/get-page "page 1"))))
|
||||
(is (true? (model/hidden-page? "$$$test")))
|
||||
(is (true? (model/hidden-page? (str "$$$" (random-uuid)))))))
|
||||
|
||||
(deftest get-class-children-test
|
||||
(let [opts {:redirect? false :create-first-block? false :class? true}
|
||||
(let [opts {:redirect? false}
|
||||
_ (test-helper/create-page! "class1" opts)
|
||||
_ (test-helper/create-page! "class2" opts)
|
||||
_ (test-helper/create-page! "class3" opts)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(ns frontend.handler.db-based.recent-test
|
||||
(:require [frontend.handler.db-based.recent :as db-recent-handler]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[frontend.test.helper :as test-helper]
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[datascript.core :as d]
|
||||
[frontend.db :as db]))
|
||||
[frontend.db :as db]
|
||||
[frontend.handler.db-based.recent :as db-recent-handler]
|
||||
[frontend.test.helper :as test-helper]))
|
||||
|
||||
(def init-data (test-helper/initial-test-page-and-blocks))
|
||||
(defn start-and-destroy-db
|
||||
@@ -19,7 +19,7 @@
|
||||
(let [pages (map (fn [i] (str "Page " i)) (range 15))]
|
||||
;; create pages
|
||||
(doseq [page pages]
|
||||
(test-helper/create-page! page {:redirect? false :create-first-block? false :class? true})
|
||||
(test-helper/create-page! page {:redirect? false})
|
||||
(db-recent-handler/add-page-to-recent! (:db/id (db/get-page page)) false))
|
||||
(is (= (map :block/title (db-recent-handler/get-recent-pages)) (reverse pages)))
|
||||
(testing "Click existing recent item shouldn't update its position"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
(ns frontend.worker.handler.page.file-based.rename-test
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures are]]
|
||||
[frontend.test.helper :as test-helper]
|
||||
(:require [clojure.string :as string]
|
||||
[clojure.test :refer [deftest is testing use-fixtures are]]
|
||||
[datascript.core :as d]
|
||||
[frontend.db :as db]
|
||||
[clojure.string :as string]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.util :as util]
|
||||
[frontend.worker.handler.page.file-based.rename :as file-page-rename]
|
||||
[frontend.handler.editor :as editor-handler]))
|
||||
[frontend.worker.handler.page.file-based.rename :as file-page-rename]))
|
||||
|
||||
;; FIXME: merge properties from both pages
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
(is (= "New name" (:block/title (db/entity (:db/id page)))))))
|
||||
|
||||
(testing "Merge existing page"
|
||||
(test-helper/create-page! "Existing page" {:redirect? false :create-first-block? true})
|
||||
(test-helper/create-page! "Existing page" {:redirect? false})
|
||||
(let [page (db/get-page "new name")]
|
||||
(page-rename (:block/uuid page) "Existing page"))
|
||||
(let [e1 (db/get-page "new name")
|
||||
@@ -47,10 +47,10 @@
|
||||
;; Old page deleted
|
||||
(is (nil? e1))
|
||||
;; Blocks from both pages have been merged
|
||||
(is (= (count (:block/_page e2)) (+ 1 (dec (count init-data))))))))
|
||||
(is (= (count (:block/_page e2)) (dec (count init-data)))))))
|
||||
|
||||
(deftest merge-with-empty-page
|
||||
(test-helper/create-page! "Existing page" {:redirect? false :create-first-block? false})
|
||||
(test-helper/create-page! "Existing page" {:redirect? false})
|
||||
(let [page (db/get-page "test")]
|
||||
(page-rename (:block/uuid page) "Existing page"))
|
||||
(let [e1 (db/get-page "test")
|
||||
@@ -63,7 +63,7 @@
|
||||
(deftest merge-existing-pages-should-update-ref-ids
|
||||
(testing "Merge existing page"
|
||||
(editor-handler/save-block! repo fbid "Block 1 [[Test]]")
|
||||
(test-helper/create-page! "Existing page" {:redirect? false :create-first-block? true})
|
||||
(test-helper/create-page! "Existing page" {:redirect? false})
|
||||
(let [page (db/get-page "test")]
|
||||
(page-rename (:block/uuid page) "Existing page"))
|
||||
(let [e1 (db/get-page "test")
|
||||
@@ -71,7 +71,7 @@
|
||||
;; Old page deleted
|
||||
(is (nil? e1))
|
||||
;; Blocks from both pages have been merged
|
||||
(is (= (count (:block/_page e2)) (+ 1 (dec (count init-data)))))
|
||||
(is (= (count (:block/_page e2)) (dec (count init-data))))
|
||||
;; Content updated
|
||||
(is (= "Block 1 [[Existing page]]" (:block/title (db/entity [:block/uuid fbid])))))))
|
||||
|
||||
@@ -182,8 +182,8 @@
|
||||
(are [x y] (= (let [[content old-name new-name] x]
|
||||
(replace-old-page! content old-name new-name))
|
||||
y)
|
||||
["#foo bla [[foo]] bla #foo" "foo" "bar"]
|
||||
"#bar bla [[bar]] bla #bar"
|
||||
["#foo bla [[foo]] bla #foo" "foo" "bar"]
|
||||
"#bar bla [[bar]] bla #bar"
|
||||
|
||||
["#logseq/foo bla [[logseq/foo]] bla [[file:./pages/logseq.foo.org][logseq/foo]] bla #logseq/foo" "logseq/foo" "logseq/bar"]
|
||||
"#logseq/bar bla [[logseq/bar]] bla [[file:./pages/logseq.bar.org][logseq/bar]] bla #logseq/bar"))
|
||||
["#logseq/foo bla [[logseq/foo]] bla [[file:./pages/logseq.foo.org][logseq/foo]] bla #logseq/foo" "logseq/foo" "logseq/bar"]
|
||||
"#logseq/bar bla [[logseq/bar]] bla [[file:./pages/logseq.bar.org][logseq/bar]] bla #logseq/bar"))
|
||||
|
||||
@@ -130,8 +130,7 @@
|
||||
(testing "add page"
|
||||
(worker-page/create! repo conn (worker-state/get-config repo)
|
||||
"TEST-PAGE"
|
||||
{:uuid page-uuid
|
||||
:create-first-block? false})
|
||||
{:uuid page-uuid})
|
||||
(is (some? (d/pull @conn '[*] [:block/uuid page-uuid])))
|
||||
(is (= {page-uuid #{:update-page :update}}
|
||||
(ops-coll=>block-uuid->op-types (client-op/get&remove-all-block-ops repo)))))
|
||||
@@ -168,10 +167,10 @@
|
||||
:block/tags :block/title :db/cardinality}]
|
||||
#_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
|
||||
(is (->> (me/find (subject/generate-rtc-ops-from-property-entities [ent])
|
||||
([:move _ {:block-uuid ?block-uuid}]
|
||||
[:update-page _ {:block-uuid ?block-uuid}]
|
||||
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
|
||||
!av-coll-attrs)
|
||||
([:move _ {:block-uuid ?block-uuid}]
|
||||
[:update-page _ {:block-uuid ?block-uuid}]
|
||||
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
|
||||
!av-coll-attrs)
|
||||
set
|
||||
(set/difference av-coll-attrs)
|
||||
empty?))))
|
||||
@@ -184,9 +183,9 @@
|
||||
:block/tags :block/title}]
|
||||
#_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
|
||||
(is (->> (me/find (subject/generate-rtc-ops-from-class-entities [ent])
|
||||
([:update-page _ {:block-uuid ?block-uuid}]
|
||||
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
|
||||
!av-coll-attrs)
|
||||
([:update-page _ {:block-uuid ?block-uuid}]
|
||||
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
|
||||
!av-coll-attrs)
|
||||
set
|
||||
(set/difference av-coll-attrs)
|
||||
empty?))))
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
[page-uuid
|
||||
uuid1-client uuid2-client
|
||||
uuid1-remote uuid2-remote] (repeatedly random-uuid)]
|
||||
(test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
|
||||
(test-helper/create-page! page-name {:redirect? false :uuid page-uuid})
|
||||
(outliner-tx/transact!
|
||||
opts
|
||||
(outliner-core/insert-blocks!
|
||||
@@ -236,7 +236,7 @@
|
||||
[page-uuid
|
||||
uuid1-client uuid2-client
|
||||
uuid1-not-exist] (repeatedly random-uuid)]
|
||||
(test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
|
||||
(test-helper/create-page! page-name {:redirect? false})
|
||||
(outliner-tx/transact!
|
||||
opts
|
||||
(outliner-core/insert-blocks!
|
||||
@@ -301,7 +301,7 @@ result:
|
||||
page-name "apply-remote-remove-ops-test2"
|
||||
[page-uuid
|
||||
uuid1 uuid2 uuid3] (repeatedly random-uuid)]
|
||||
(test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
|
||||
(test-helper/create-page! page-name {:redirect? false})
|
||||
(outliner-tx/transact!
|
||||
opts
|
||||
(outliner-core/insert-blocks!
|
||||
@@ -391,7 +391,7 @@ result:
|
||||
[page1-uuid page2-uuid
|
||||
uuid1-client uuid2-client
|
||||
uuid1-remote uuid2-remote] (repeatedly random-uuid)]
|
||||
(test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page1-uuid})
|
||||
(test-helper/create-page! page-name {:redirect? false})
|
||||
(outliner-tx/transact!
|
||||
opts
|
||||
(outliner-core/insert-blocks!
|
||||
|
||||
25
yarn.lock
25
yarn.lock
@@ -6531,17 +6531,10 @@ path-type@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||
|
||||
path2d-polyfill@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path2d-polyfill/-/path2d-polyfill-2.1.1.tgz#6098b7bf2fc24c306c6377bcd558b17ba437ea27"
|
||||
integrity sha512-4Rka5lN+rY/p0CdD8+E+BFv51lFaFvJOrlOhyQ+zjzyQrzyh3ozmxd1vVGGDdIbUFSBtIZLSnspxTgPT0iJhvA==
|
||||
dependencies:
|
||||
path2d "0.1.1"
|
||||
|
||||
path2d@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path2d/-/path2d-0.1.1.tgz#d3c3886cd2252fb2a7830c27ea7bb9a862d937ea"
|
||||
integrity sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==
|
||||
path2d@^0.2.0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/path2d/-/path2d-0.2.2.tgz#cc85d61ed7827e7863a2ee36713d4b5315a3d85d"
|
||||
integrity sha512-+vnG6S4dYcYxZd+CZxzXCNKdELYZSKfohrk98yajCo1PtRoDgCTrrwOvK1GT0UoAdVszagDVllQc0U1vaX4NUQ==
|
||||
|
||||
path@0.12.7:
|
||||
version "0.12.7"
|
||||
@@ -6562,13 +6555,13 @@ pbkdf2@^3.1.2:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
pdfjs-dist@^3.9.179:
|
||||
version "3.11.174"
|
||||
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz#5ff47b80f2d58c8dd0d74f615e7c6a7e7e704c4b"
|
||||
integrity sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==
|
||||
pdfjs-dist@4.2.67:
|
||||
version "4.2.67"
|
||||
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-4.2.67.tgz#dd2a65a4b00d95cd4bc2c1f6a27c5e9eb31d512a"
|
||||
integrity sha512-rJmuBDFpD7cqC8WIkQUEClyB4UAH05K4AsyewToMTp2gSy3Rrx8c1ydAVqlJlGv3yZSOrhEERQU/4ScQQFlLHA==
|
||||
optionalDependencies:
|
||||
canvas "^2.11.2"
|
||||
path2d-polyfill "^2.0.1"
|
||||
path2d "^0.2.0"
|
||||
|
||||
pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
|
||||
Reference in New Issue
Block a user