Sfoglia il codice sorgente

fix: publishing app fails to load initial and then user data

fixes https://linear.app/logseq/issue/LOG-3257/publishing-app-fails-to-load-initial-and-then-user-data
Tienson Qin 1 anno fa
parent
commit
7d084abc5e

+ 14 - 14
deps/db/src/logseq/db/frontend/property.cljs

@@ -132,8 +132,8 @@
    ;;                                :public? false}}
 
    ;; Task props
-   :logseq.task/status
-   {:title "Status"
+   :logseq.task/priority
+   {:title "Priority"
     :schema
     {:type :default
      :public? true
@@ -144,14 +144,12 @@
              :value value
              :uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident)
              :icon {:type :tabler-icon :id icon}})
-          [[:logseq.task/status.backlog "Backlog" "Backlog"]
-           [:logseq.task/status.todo "Todo" "Todo"]
-           [:logseq.task/status.doing "Doing" "InProgress50"]
-           [:logseq.task/status.in-review "In Review" "InReview"]
-           [:logseq.task/status.done "Done" "Done"]
-           [:logseq.task/status.canceled "Canceled" "Cancelled"]])}
-   :logseq.task/priority
-   {:title "Priority"
+          [[:logseq.task/priority.low "Low" "priorityLvlLow"]
+           [:logseq.task/priority.medium "Medium" "priorityLvlMedium"]
+           [:logseq.task/priority.high "High" "priorityLvlHigh"]
+           [:logseq.task/priority.urgent "Urgent" "priorityLvlUrgent"]])}
+   :logseq.task/status
+   {:title "Status"
     :schema
     {:type :default
      :public? true
@@ -162,10 +160,12 @@
              :value value
              :uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident)
              :icon {:type :tabler-icon :id icon}})
-          [[:logseq.task/priority.low "Low" "priorityLvlLow"]
-           [:logseq.task/priority.medium "Medium" "priorityLvlMedium"]
-           [:logseq.task/priority.high "High" "priorityLvlHigh"]
-           [:logseq.task/priority.urgent "Urgent" "priorityLvlUrgent"]])}
+          [[:logseq.task/status.backlog "Backlog" "Backlog"]
+           [:logseq.task/status.todo "Todo" "Todo"]
+           [:logseq.task/status.doing "Doing" "InProgress50"]
+           [:logseq.task/status.in-review "In Review" "InReview"]
+           [:logseq.task/status.done "Done" "Done"]
+           [:logseq.task/status.canceled "Canceled" "Cancelled"]])}
    :logseq.task/deadline
    {:title "Deadline"
     :schema {:type :date

+ 3 - 3
deps/publishing/src/logseq/publishing/export.cljs

@@ -8,7 +8,7 @@
 
 (def ^:api js-files
   "js files from publishing release build"
-  ["shared.js" "main.js" "code-editor.js" "excalidraw.js" "tldraw.js" "db-worker.js"])
+  ["shared.js" "shared.js.map" "main.js" "main.js.map" "code-editor.js" "excalidraw.js" "tldraw.js" "db-worker.js" "db-worker.js.map"])
 
 (def ^:api static-dirs
   "dirs under static dir to copy over"
@@ -97,8 +97,8 @@
                 custom-js (if (fs/existsSync custom-js-path) (str (fs/readFileSync custom-js-path)) "")
                 _ (fs/writeFileSync (node-path/join output-static-dir "js" "custom.js") custom-js)
                 _ (cleanup-js-dir output-static-dir static-dir options)]
-               (notification-fn {:type "success"
-                                 :payload (str "Export public pages and publish assets to " output-dir " successfully 🎉")}))
+          (notification-fn {:type "success"
+                            :payload (str "Export public pages and publish assets to " output-dir " successfully 🎉")}))
         (p/catch (fn [error]
                    (notification-fn {:type "error"
                                      :payload (str "Export public pages unexpectedly failed with: " error)}))))))

+ 3 - 5
deps/publishing/src/logseq/publishing/html.cljs

@@ -5,8 +5,7 @@ necessary db filtering"
             [goog.string :as gstring]
             [goog.string.format]
             [datascript.transit :as dt]
-            [logseq.publishing.db :as db]
-            [logseq.db.sqlite.util :as sqlite-util]))
+            [logseq.publishing.db :as db]))
 
 ;; Copied from hiccup but tweaked for publish usage
 ;; Any changes here should also be made in frontend.publishing/unescape-html
@@ -136,7 +135,7 @@ necessary db filtering"
 (defn build-html
   "Given the graph's db, filters the db using the given options and returns the
 generated index.html string and assets used by the html"
-  [db* {:keys [app-state repo-config html-options db-graph?]}]
+  [db* {:keys [repo app-state repo-config html-options db-graph?]}]
   (let [all-pages-public? (if-let [value (:publishing/all-pages-public? repo-config)]
                             value
                             (:all-pages-public? repo-config))
@@ -146,11 +145,10 @@ generated index.html string and assets used by the html"
         asset-filenames (remove nil? asset-filenames')
 
         db-str (dt/write-transit-str db)
-        repo-name (if db-graph? (str sqlite-util/db-version-prefix "Demo") "Demo")
         ;; The repo-name is used by the client and thus determines whether
         ;; it's a db graph or not
         state (assoc app-state
-                     :config {repo-name repo-config})
+                     :config {repo repo-config})
         raw-html-str (publishing-html db-str state html-options)]
     {:html raw-html-str
      :asset-filenames asset-filenames}))

+ 11 - 4
scripts/src/logseq/tasks/dev/publishing.cljs

@@ -6,8 +6,8 @@
             ["fs" :as fs]
             ["path" :as node-path]
             [clojure.edn :as edn]
-            [datascript.core :as d]))
-
+            [datascript.core :as d]
+            [logseq.db.sqlite.util :as sqlite-util]))
 
 (defn- get-db [graph-dir]
   (let [{:keys [conn]} (gp-cli/parse-graph graph-dir {:verbose false})] @conn))
@@ -18,7 +18,10 @@
                        static-dir
                        graph-dir
                        output-path
-                       (merge options {:repo-config repo-config :ui/theme "dark" :ui/radix-color :purple}))))
+                       (merge options {:repo (node-path/basename graph-dir)
+                                       :repo-config repo-config
+                                       :ui/theme "dark"
+                                       :ui/radix-color :purple}))))
 
 (defn- publish-db-graph [static-dir graph-dir output-path opts]
   (let [db-name (node-path/basename graph-dir)
@@ -32,7 +35,11 @@
                        static-dir
                        graph-dir
                        output-path
-                       (merge opts {:repo-config repo-config :db-graph? true :ui/theme "dark" :ui/radix-color :cyan}))))
+                       (merge opts {:repo (str sqlite-util/db-version-prefix db-name)
+                                    :repo-config repo-config
+                                    :db-graph? true
+                                    :ui/theme "dark"
+                                    :ui/radix-color :cyan}))))
 
 (defn -main
   [& args]

+ 78 - 72
src/main/frontend/components/repo.cljs

@@ -47,10 +47,10 @@
   [repos]
   (if-let [m (and (seq repos) (graph/get-metadata-local))]
     (->> repos
-      (map (fn [r] (merge r (get m (:url r)))))
-      (sort (fn [r1 r2]
-              (compare (or (:last-seen-at r2) (:created-at r2))
-                (or (:last-seen-at r1) (:created-at r1))))))
+         (map (fn [r] (merge r (get m (:url r)))))
+         (sort (fn [r1 r2]
+                 (compare (or (:last-seen-at r2) (:created-at r2))
+                          (or (:last-seen-at r1) (:created-at r1))))))
     repos))
 
 (defn- safe-locale-date
@@ -71,17 +71,17 @@
      [:div
       [:span.flex.items-center.gap-1
        (normalized-graph-label repo
-         (fn []
-           (when-not (state/sub :rtc/downloading-graph-uuid)
-             (cond
-               root                                         ; exists locally
-               (state/pub-event! [:graph/switch url])
+                               (fn []
+                                 (when-not (state/sub :rtc/downloading-graph-uuid)
+                                   (cond
+                                     root                                         ; exists locally
+                                     (state/pub-event! [:graph/switch url])
 
-               (and db-based? remote?)
-               (state/pub-event! [:rtc/download-remote-graph GraphName GraphUUID])
+                                     (and db-based? remote?)
+                                     (state/pub-event! [:rtc/download-remote-graph GraphName GraphUUID])
 
-               :else
-               (state/pub-event! [:graph/pull-down-remote-graph repo])))))]
+                                     :else
+                                     (state/pub-event! [:graph/pull-down-remote-graph repo])))))]
       (when-let [time (some-> (or last-seen-at created-at) (safe-locale-date))]
         [:small.text-gray-400.opacity-50 (str "Last opened at: " time)])]
 
@@ -109,11 +109,11 @@
              :on-click (fn []
                          (let [has-prompt? true
                                prompt-str (cond only-cloud?
-                                            (str "Are you sure to permanently delete the graph \"" GraphName "\" from our server?")
-                                            db-based?
-                                            (str "Are you sure to permanently delete the graph \"" url "\" from Logseq?")
-                                            :else
-                                            (str "Are you sure to unlink the graph \"" url "\" from local folder?"))
+                                                (str "Are you sure to permanently delete the graph \"" GraphName "\" from our server?")
+                                                db-based?
+                                                (str "Are you sure to permanently delete the graph \"" url "\" from Logseq?")
+                                                :else
+                                                (str "Are you sure to unlink the graph \"" url "\" from local folder?"))
                                unlink-or-remote-fn! (fn []
                                                       (repo-handler/remove-repo! repo)
                                                       (state/pub-event! [:graph/unlinked repo (state/get-current-repo)]))
@@ -125,19 +125,19 @@
                                                                              file-sync/<delete-graph)]
                                                           (state/set-state! [:file-sync/remote-graphs :loading] true)
                                                           (go (<! (delete-graph GraphUUID))
-                                                            (state/delete-repo! repo)
-                                                            (state/delete-remote-graph! repo)
-                                                            (state/set-state! [:file-sync/remote-graphs :loading] false)))))
+                                                              (state/delete-repo! repo)
+                                                              (state/delete-remote-graph! repo)
+                                                              (state/set-state! [:file-sync/remote-graphs :loading] false)))))
                                                     unlink-or-remote-fn!)
                                confirm-fn!
                                (fn []
                                  (-> (shui/dialog-confirm!
-                                       [:p.font-medium.-my-4 prompt-str
-                                        [:span.mt-1.flex.font-normal.opacity-70
-                                         (if (or db-based? only-cloud?)
-                                           [:small.text-red-rx-11 "⚠️ Notice that we can't recover this graph after being deleted. Make sure you have backups before deleting it."]
-                                           [:small.opacity-70 "⚠️ It won't remove your local files!"])]])
-                                   (p/then #(action-confirm-fn!))))]
+                                      [:p.font-medium.-my-4 prompt-str
+                                       [:span.mt-1.flex.font-normal.opacity-70
+                                        (if (or db-based? only-cloud?)
+                                          [:small.text-red-rx-11 "⚠️ Notice that we can't recover this graph after being deleted. Make sure you have backups before deleting it."]
+                                          [:small.opacity-70 "⚠️ It won't remove your local files!"])]])
+                                     (p/then #(action-confirm-fn!))))]
 
                            (if has-prompt?
                              (confirm-fn!)
@@ -272,18 +272,24 @@
                   (shui/tabler-icon "folder-plus")
                   [:span (t :new-graph)]))
 
-   (shui/button {:size :sm :variant :ghost
-                 :on-click #(state/pub-event! [:graph/new-db-graph])}
-     (shui/tabler-icon "database-plus") [:span (if util/electron? "Create db graph" "Create new graph")])
+   (when-not config/publishing?
+     (shui/button
+      {:size :sm :variant :ghost
+       :on-click #(state/pub-event! [:graph/new-db-graph])}
+      (shui/tabler-icon "database-plus")
+      [:span (if util/electron? "Create db graph" "Create new graph")]))
 
-   (shui/button {:size :sm :variant :ghost
-                 :on-click (fn [] (route-handler/redirect! {:to :import}))}
-                (shui/tabler-icon "database-import")
-                [:span (t :import-notes)])
+   (when-not config/publishing?
+     (shui/button
+      {:size :sm :variant :ghost
+       :on-click (fn [] (route-handler/redirect! {:to :import}))}
+      (shui/tabler-icon "database-import")
+      [:span (t :import-notes)]))
 
-   (shui/button {:size :sm :variant :ghost
-                 :on-click #(route-handler/redirect-to-all-graphs)}
-                (shui/tabler-icon "layout-2") [:span (t :all-graphs)])])
+   (when-not config/publishing?
+     (shui/button {:size :sm :variant :ghost
+                   :on-click #(route-handler/redirect-to-all-graphs)}
+                  (shui/tabler-icon "layout-2") [:span (t :all-graphs)]))])
 
 (rum/defcs repos-dropdown < rum/reactive
   (rum/local false ::electron-multiple-windows?)
@@ -375,40 +381,40 @@
 (defn invalid-graph-name-warning
   []
   (notification/show!
-    [:div
-     [:p "Graph name can't contain following reserved characters:"]
-     [:ul
-      [:li "< (less than)"]
-      [:li "> (greater than)"]
-      [:li ": (colon)"]
-      [:li "\" (double quote)"]
-      [:li "/ (forward slash)"]
-      [:li "\\ (backslash)"]
-      [:li "| (vertical bar or pipe)"]
-      [:li "? (question mark)"]
-      [:li "* (asterisk)"]
-      [:li "# (hash)"]
+   [:div
+    [:p "Graph name can't contain following reserved characters:"]
+    [:ul
+     [:li "< (less than)"]
+     [:li "> (greater than)"]
+     [:li ": (colon)"]
+     [:li "\" (double quote)"]
+     [:li "/ (forward slash)"]
+     [:li "\\ (backslash)"]
+     [:li "| (vertical bar or pipe)"]
+     [:li "? (question mark)"]
+     [:li "* (asterisk)"]
+     [:li "# (hash)"]
       ;; `+` is used to encode path that includes `:` or `/`
-      [:li "+ (plus)"]]]
-    :warning false))
+     [:li "+ (plus)"]]]
+   :warning false))
 
 (defn invalid-graph-name?
   "Returns boolean indicating if DB graph name is invalid. Must be kept in sync with invalid-graph-name-warning"
   [graph-name]
   (or (fs-util/include-reserved-chars? graph-name)
-    (string/includes? graph-name "+")
-    (string/includes? graph-name "/")))
+      (string/includes? graph-name "+")
+      (string/includes? graph-name "/")))
 
 (rum/defcs new-db-graph < rum/reactive
-                          (rum/local "" ::graph-name)
-                          (rum/local false ::cloud?)
-                          (rum/local false ::creating-db?)
-                          (rum/local (rum/create-ref) ::input-ref)
-                          {:did-mount (fn [s]
-                                        (when-let [^js input (some-> @(::input-ref s)
-                                                               (rum/deref))]
-                                          (js/setTimeout #(.focus input) 32))
-                                        s)}
+  (rum/local "" ::graph-name)
+  (rum/local false ::cloud?)
+  (rum/local false ::creating-db?)
+  (rum/local (rum/create-ref) ::input-ref)
+  {:did-mount (fn [s]
+                (when-let [^js input (some-> @(::input-ref s)
+                                             (rum/deref))]
+                  (js/setTimeout #(.focus input) 32))
+                s)}
   [state]
   (let [*creating-db? (::creating-db? state)
         *graph-name (::graph-name state)
@@ -440,22 +446,22 @@
                            (shui/dialog-close!))))))
         submit! (fn [^js e click?]
                   (when-let [value (and (or click? (= (gobj/get e "key") "Enter"))
-                                     (util/trim-safe (.-value (rum/deref input-ref))))]
+                                        (util/trim-safe (.-value (rum/deref input-ref))))]
                     (reset! *graph-name value)
                     (new-db-f)))]
     [:div.new-graph.flex.flex-col.gap-4.p-1.pt-2
      (shui/input
-       {:default-value @*graph-name
-        :disabled @*creating-db?
-        :ref input-ref
-        :placeholder "your graph name"
-        :on-key-down submit!})
+      {:default-value @*graph-name
+       :disabled @*creating-db?
+       :ref input-ref
+       :placeholder "your graph name"
+       :on-key-down submit!})
      (when (user-handler/logged-in?)
        [:div.flex.flex-row.items-center.gap-1
         (shui/checkbox
-          {:id "rtc-sync"
-           :value @*cloud?
-           :on-checked-change #(swap! *cloud? not)})
+         {:id "rtc-sync"
+          :value @*cloud?
+          :on-checked-change #(swap! *cloud? not)})
         [:label.opacity-70.text-sm
          {:for "rtc-sync"}
          "Use Logseq Sync?"]])

+ 2 - 1
src/main/frontend/handler/export.cljs

@@ -34,7 +34,8 @@
   (when-let [db (db/get-db repo)]
     (let [{:keys [asset-filenames html]}
           (publish-html/build-html db
-                                   {:app-state (select-keys @state/state
+                                   {:repo repo
+                                    :app-state (select-keys @state/state
                                                             [:ui/theme
                                                              :ui/sidebar-collapsed-blocks])
                                     :repo-config (get-in @state/state [:config repo])

+ 17 - 21
src/main/frontend/publishing.cljs

@@ -1,31 +1,28 @@
 (ns frontend.publishing
   "Entry ns for publishing build. Provides frontend for publishing single page
   application"
-  (:require [frontend.state :as state]
-            [datascript.core :as d]
-            [datascript.transit :as dt]
-            [frontend.db :as db]
-            [rum.core :as rum]
-            [frontend.handler.route :as route-handler]
-            [frontend.page :as page]
+  (:require [cljs.reader :as reader]
             [clojure.string :as string]
-            [frontend.routes :as routes]
-            [frontend.context.i18n :as i18n]
-            [reitit.frontend :as rf]
-            [reitit.frontend.easy :as rfe]
-            [cljs.reader :as reader]
             [frontend.components.block :as block]
             [frontend.components.editor :as editor]
             [frontend.components.page :as page-component]
             [frontend.components.reference :as reference]
             [frontend.components.whiteboard :as whiteboard]
-            [frontend.modules.shortcut.core :as shortcut]
-            [frontend.handler.events :as events]
+            [frontend.context.i18n :as i18n]
             [frontend.handler.command-palette :as command-palette]
+            [frontend.handler.events :as events]
+            [frontend.handler.repo :as repo-handler]
+            [frontend.handler.route :as route-handler]
+            [frontend.handler.ui :as ui-handler]
+            [frontend.modules.shortcut.core :as shortcut]
+            [frontend.page :as page]
             [frontend.persist-db.browser :as db-browser]
+            [frontend.routes :as routes]
+            [frontend.state :as state]
             [promesa.core :as p]
-            [frontend.handler.repo :as repo-handler]
-            [frontend.handler.ui :as ui-handler]))
+            [reitit.frontend :as rf]
+            [reitit.frontend.easy :as rfe]
+            [rum.core :as rum]))
 
 ;; The publishing site should be as thin as possible.
 ;; Both files and git libraries can be removed.
@@ -58,11 +55,10 @@
     (let [repo (-> @state/state :config keys first)]
       (state/set-current-repo! repo)
       (p/let [_ (repo-handler/restore-and-setup-repo! repo)
-              _ (let [data (unescape-html data)
-                      db (dt/read-transit-str data)
-                      datoms (d/datoms db :eavt)]
-                  (db/transact! repo datoms {:init-db? true
-                                             :new-graph? true}))]
+              _ (let [db-transit-str (unescape-html data)]
+                  (when-let [^js worker @state/*db-worker]
+                    (.resetDB worker repo db-transit-str)))
+              _ (repo-handler/restore-and-setup-repo! repo)]
         (state/set-db-restoring! false)
         (ui-handler/re-render-root!)))))
 

+ 18 - 2
src/main/frontend/worker/db_worker.cljs

@@ -35,7 +35,8 @@
             [goog.object :as gobj]
             [promesa.core :as p]
             [shadow.cljs.modern :refer [defclass]]
-            [logseq.db.frontend.schema :as db-schema]))
+            [logseq.db.frontend.schema :as db-schema]
+            [me.tonsky.persistent-sorted-set :as set :refer [BTSet]]))
 
 (defonce *sqlite worker-state/*sqlite)
 (defonce *sqlite-conns worker-state/*sqlite-conns)
@@ -258,9 +259,20 @@
 
 (defn close-db!
   [repo]
-  (let [{:keys [db search client-ops]} (@*sqlite-conns repo)]
+  (let [{:keys [db search client-ops]} (get @*sqlite-conns repo)]
     (close-db-aux! repo db search client-ops)))
 
+(defn reset-db!
+  [repo db-transit-str]
+  (when-let [conn (get @*datascript-conns repo)]
+    (let [new-db (ldb/read-transit-str db-transit-str)
+          new-db' (update new-db :eavt (fn [^BTSet s]
+                                         (set! (.-storage s) (.-storage (:eavt @conn)))
+                                         s))]
+      (d/reset-conn! conn new-db')
+      (d/reset-schema! conn (:schema new-db))
+      nil)))
+
 (defn- get-dbs
   [repo]
   (if @*publishing?
@@ -588,6 +600,10 @@
    [_this repo]
    (close-db! repo))
 
+  (resetDB
+   [_this repo db-transit]
+   (reset-db! repo db-transit))
+
   (unsafeUnlinkDB
    [_this repo]
    (p/let [pool (<get-opfs-pool repo)

+ 2 - 3
src/main/frontend/worker/state.cljs

@@ -26,14 +26,13 @@
 
                        ;; new implementation
                        :undo/repo->ops (atom {})
-                       :redo/repo->ops (atom {})
-                       }))
+                       :redo/repo->ops (atom {})}))
 
 (defonce *rtc-ws-url (atom nil))
 
 (defonce *sqlite (atom nil))
 ;; repo -> {:db conn :search conn :client-ops conn}
-(defonce *sqlite-conns (atom nil))
+(defonce *sqlite-conns (atom {}))
 ;; repo -> conn
 (defonce *datascript-conns (atom nil))