Initial import of LogDarioSeq baseline
Establishes version control for the personal Logseq DB fork before starting the server-client architecture migration and domain features described in docs/agent-guide and the approved implementation plan. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
248
src/main/frontend/worker/publish.cljs
Normal file
248
src/main/frontend/worker/publish.cljs
Normal file
@@ -0,0 +1,248 @@
|
||||
(ns frontend.worker.publish
|
||||
"Publish"
|
||||
(:require [clojure.string :as string]
|
||||
[datascript.core :as d]
|
||||
[frontend.common.thread-api :refer [def-thread-api]]
|
||||
[frontend.worker.state :as worker-state]
|
||||
[logseq.common.util :as common-util]
|
||||
[logseq.db :as ldb]
|
||||
[logseq.db.frontend.content :as db-content]
|
||||
[logseq.db.frontend.entity-util :as entity-util]
|
||||
[logseq.db.frontend.property :as db-property]
|
||||
[logseq.db.frontend.schema :as db-schema]))
|
||||
|
||||
(defn- publish-entity-title
|
||||
[entity]
|
||||
(or (:block/title entity)
|
||||
"Untitled"))
|
||||
|
||||
(defn- page-tags
|
||||
[page-entity]
|
||||
(let [tags (:block/tags page-entity)]
|
||||
(->> tags
|
||||
(remove (fn [tag]
|
||||
(contains? #{:logseq.class/Page} (:db/ident tag))))
|
||||
(map (fn [tag]
|
||||
{:tag_uuid (:block/uuid tag)
|
||||
:tag_title (:block/title tag)})))))
|
||||
|
||||
(defn- publish-ref-eid [value]
|
||||
(cond
|
||||
(number? value) (when (pos? value) value)
|
||||
(map? value) (let [eid (:db/id value)]
|
||||
(when (and (number? eid) (pos? eid))
|
||||
eid))
|
||||
:else nil))
|
||||
|
||||
(def ^:private comments-class-ident :logseq.class/Comments)
|
||||
(def ^:private comment-class-ident :logseq.class/Comment)
|
||||
|
||||
(defn- comments-area?
|
||||
[db block]
|
||||
(ldb/class-instance? (d/entity db comments-class-ident) block))
|
||||
|
||||
(defn- comment-block?
|
||||
[db block]
|
||||
(or (ldb/class-instance? (d/entity db comment-class-ident) block)
|
||||
(comments-area? db (:block/parent block))))
|
||||
|
||||
(defn- publishable-block?
|
||||
[db block]
|
||||
(not (or (comments-area? db block)
|
||||
(comment-block? db block))))
|
||||
|
||||
(defn- publish-refs-from-blocks
|
||||
[db blocks page-entity graph-uuid]
|
||||
(let [page-uuid (:block/uuid page-entity)
|
||||
page-title (publish-entity-title page-entity)
|
||||
page? (entity-util/page? page-entity)
|
||||
graph-uuid (str graph-uuid)]
|
||||
(mapcat (fn [block]
|
||||
(let [block-uuid (:block/uuid block)
|
||||
block-uuid-str (some-> block-uuid str)]
|
||||
(when (and block-uuid-str
|
||||
(or (not page?)
|
||||
(not= block-uuid page-uuid)))
|
||||
(let [block-content (or (:block/title block)
|
||||
(:block/name block)
|
||||
"")
|
||||
block-format (name (or (:block/format block) :markdown))
|
||||
refs (:block/refs block)
|
||||
refs (if (sequential? refs) refs (when refs [refs]))
|
||||
targets (->> refs
|
||||
(map publish-ref-eid)
|
||||
(keep #(when % (d/entity db %)))
|
||||
(keep :block/uuid)
|
||||
(map str)
|
||||
distinct)]
|
||||
(when (seq targets)
|
||||
(map (fn [target]
|
||||
{:graph_uuid graph-uuid
|
||||
:target_page_uuid target
|
||||
:source_page_uuid (str page-uuid)
|
||||
:source_page_title page-title
|
||||
:source_block_uuid block-uuid-str
|
||||
:source_block_content block-content
|
||||
:source_block_format block-format
|
||||
:updated_at (common-util/time-ms)})
|
||||
targets))))))
|
||||
blocks)))
|
||||
|
||||
(defn- collect-publish-blocks
|
||||
[db entity]
|
||||
(if (entity-util/page? entity)
|
||||
(:block/_page entity)
|
||||
(ldb/get-block-and-children db (:block/uuid entity))))
|
||||
|
||||
(def ^:private publish-search-max-length 4096)
|
||||
|
||||
(defn- block-page-eid
|
||||
[block]
|
||||
(let [page (:block/page block)]
|
||||
(cond
|
||||
(map? page) (:db/id page)
|
||||
(number? page) page
|
||||
:else nil)))
|
||||
|
||||
(defn- block-search-content
|
||||
[block]
|
||||
(let [raw-content (or (:block/title block)
|
||||
(:block/name block)
|
||||
"")
|
||||
raw-content (string/trim raw-content)]
|
||||
(when-not (string/blank? raw-content)
|
||||
(let [content (db-content/recur-replace-uuid-in-block-title
|
||||
(assoc block :block/title raw-content))
|
||||
content (if (> (count content) publish-search-max-length)
|
||||
(subs content 0 publish-search-max-length)
|
||||
content)]
|
||||
(string/trim content)))))
|
||||
|
||||
(defn- collect-search-blocks
|
||||
[blocks page-eid page-uuid]
|
||||
(->> blocks
|
||||
(keep (fn [block]
|
||||
(when (and (= (block-page-eid block) page-eid)
|
||||
(not= (:db/id block) page-eid)
|
||||
(not (:logseq.property/created-from-property block)))
|
||||
(when-let [block-uuid (some-> (:block/uuid block) str)]
|
||||
(when-let [content (block-search-content block)]
|
||||
{:page_uuid (str page-uuid)
|
||||
:block_uuid block-uuid
|
||||
:block_content content})))))))
|
||||
|
||||
(defn- collect-embedded-blocks
|
||||
[db blocks]
|
||||
(let [linked-eids (->> blocks
|
||||
(map :block/link)
|
||||
(map publish-ref-eid)
|
||||
(remove nil?)
|
||||
distinct)]
|
||||
(loop [queue (vec linked-eids)
|
||||
visited #{}
|
||||
acc []]
|
||||
(if (empty? queue)
|
||||
acc
|
||||
(let [eid (first queue)
|
||||
queue (subvec queue 1)]
|
||||
(if (contains? visited eid)
|
||||
(recur queue visited acc)
|
||||
(let [entity (d/entity db eid)
|
||||
uuid (:block/uuid entity)
|
||||
children (when uuid
|
||||
(ldb/get-block-and-children db uuid))
|
||||
children (filter #(publishable-block? db %) children)
|
||||
child-links (->> children
|
||||
(map :block/link)
|
||||
(map publish-ref-eid)
|
||||
(remove nil?))]
|
||||
(recur (into queue child-links)
|
||||
(conj visited eid)
|
||||
(into acc children)))))))))
|
||||
|
||||
(defn- publish-collect-page-eids
|
||||
[db entity]
|
||||
(let [page-id (:db/id entity)
|
||||
blocks (filter #(publishable-block? db %) (collect-publish-blocks db entity))
|
||||
embedded-blocks (collect-embedded-blocks db blocks)
|
||||
blocks (concat blocks embedded-blocks)
|
||||
block-eids (map :db/id blocks)
|
||||
ref-eids (->> blocks
|
||||
(mapcat :block/refs)
|
||||
(map publish-ref-eid)
|
||||
(remove nil?))
|
||||
tag-eids (->> blocks
|
||||
(mapcat :block/tags)
|
||||
(map publish-ref-eid)
|
||||
(remove nil?))
|
||||
page-tag-eids (->> (if-let [tags (:block/tags entity)]
|
||||
(if (sequential? tags) tags [tags])
|
||||
[])
|
||||
(map publish-ref-eid)
|
||||
(remove nil?))
|
||||
page-eids (->> blocks (map :block/page) (keep :db/id))
|
||||
property-eids (->> (cons entity blocks)
|
||||
(map db-property/properties)
|
||||
(mapcat (fn [props]
|
||||
(mapcat (fn [[k v]]
|
||||
(let [property (d/entity db k)
|
||||
pid (:db/id property)
|
||||
ref-type? (= :db.type/ref (:db/valueType property))
|
||||
many? (= :db.cardinality/many (:db/cardinality property))]
|
||||
(cons pid
|
||||
(when ref-type?
|
||||
(if many?
|
||||
(map :db/id v)
|
||||
(list (:db/id v)))))))
|
||||
props)))
|
||||
(remove nil?))]
|
||||
{:blocks blocks
|
||||
:eids (->> (concat [page-id] block-eids ref-eids tag-eids page-tag-eids page-eids property-eids)
|
||||
(remove nil?)
|
||||
distinct)}))
|
||||
|
||||
(defn- normalize-block-publish-datoms
|
||||
[datoms block-eids root-eid]
|
||||
(map (fn [[e a v tx added]]
|
||||
(if (and (contains? block-eids e) (= a :block/page))
|
||||
[e a root-eid tx added]
|
||||
[e a v tx added]))
|
||||
datoms))
|
||||
|
||||
(defn- build-publish-page-payload
|
||||
[db entity]
|
||||
(let [{:keys [blocks eids]} (publish-collect-page-eids db entity)
|
||||
graph-uuid (or (ldb/get-graph-rtc-uuid db)
|
||||
(ldb/get-graph-local-uuid db))
|
||||
refs (when graph-uuid
|
||||
(publish-refs-from-blocks db blocks entity graph-uuid))
|
||||
tags (page-tags entity)
|
||||
search-blocks (collect-search-blocks blocks (:db/id entity) (:block/uuid entity))
|
||||
raw-datoms (->>
|
||||
(mapcat (fn [eid]
|
||||
(map (fn [d] [(:e d) (:a d) (:v d) (:tx d) (:added d)])
|
||||
(d/datoms db :eavt eid)))
|
||||
eids)
|
||||
(remove (fn [[_e a _v _tx _added]]
|
||||
(contains? #{:block/tx-id :logseq.property.user/email} a))))
|
||||
datoms (if (entity-util/page? entity)
|
||||
raw-datoms
|
||||
(normalize-block-publish-datoms raw-datoms (set (map :db/id blocks)) (:db/id entity)))]
|
||||
{:page (entity-util/entity->map entity)
|
||||
:page-uuid (:block/uuid entity)
|
||||
:page-title (publish-entity-title entity)
|
||||
:graph-uuid (some-> graph-uuid str)
|
||||
:block-count (count blocks)
|
||||
:schema-version (db-schema/schema-version->string db-schema/version)
|
||||
:refs refs
|
||||
:page-tags tags
|
||||
:blocks search-blocks
|
||||
:datoms datoms}))
|
||||
|
||||
(def-thread-api :thread-api/build-publish-page-payload
|
||||
[repo eid]
|
||||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(let [db @conn
|
||||
page-entity (d/entity db eid)]
|
||||
(when (and page-entity (:db/id page-entity))
|
||||
(build-publish-page-payload db page-entity)))))
|
||||
Reference in New Issue
Block a user