Merge branch 'master' into feat/capacitor-new

This commit is contained in:
charlie
2025-06-02 20:05:31 +08:00
58 changed files with 12940 additions and 8280 deletions

1
.gitignore vendored
View File

@@ -72,3 +72,4 @@ clj-e2e/.wally
clj-e2e/resources
clj-e2e/e2e-dump
.dir-locals.el
.projectile

View File

@@ -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]

View File

@@ -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)))))

View File

@@ -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"

View File

@@ -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"}

View File

@@ -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
}
}

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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
View 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)))

View 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!"))))

View File

@@ -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

View File

@@ -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/*.*',

View File

@@ -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",

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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);

View File

@@ -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?

View File

@@ -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)

View File

@@ -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

View File

@@ -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?]

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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))))))))))
[])

View File

@@ -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

View 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

View File

@@ -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"))]

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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?

View File

@@ -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!

View File

@@ -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

View File

@@ -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!)

View File

@@ -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])

View File

@@ -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}])))

View File

@@ -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]

View File

@@ -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)))))))

View File

@@ -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]]

View File

@@ -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
[]

View File

@@ -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

View File

@@ -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
[]

View File

@@ -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'

View File

@@ -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?

View File

@@ -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}

View File

@@ -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))]

View File

@@ -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)

View File

@@ -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"}}

View File

@@ -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)

View File

@@ -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"

View File

@@ -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"))

View File

@@ -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?))))

View File

@@ -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!

View File

@@ -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"