fix: CLI start time

Lazy load namespaces as start time goes up with more required namespaces
external to nbb-logseq or node. CLI now only loads ~6 namespaces instead
of 55 namespaces at start and then lazy loads a command ns as needed
This commit is contained in:
Gabriel Horner
2025-08-06 11:09:33 -04:00
committed by Gabriel Horner
parent b135b9c880
commit 3ae3ff2cd4
6 changed files with 70 additions and 50 deletions

6
deps/cli/.carve/ignore vendored Normal file
View File

@@ -0,0 +1,6 @@
;; Lazy loaded
logseq.cli.commands.export-edn/export
logseq.cli.commands.graph/show-graph
logseq.cli.commands.graph/list-graphs
logseq.cli.commands.query/query
logseq.cli.commands.search/search

View File

@@ -4,12 +4,10 @@
["path" :as node-path]
[babashka.cli :as cli]
[clojure.string :as string]
[logseq.cli.commands.export-edn :as cli-export-edn]
[logseq.cli.commands.graph :as cli-graph]
[logseq.cli.commands.query :as cli-query]
[logseq.cli.commands.search :as cli-search]
[logseq.cli.common.graph :as cli-common-graph]
[nbb.error :as error]))
[logseq.cli.spec :as cli-spec]
[nbb.error :as error]
[promesa.core :as p]))
(defn- format-commands [{:keys [table]}]
(let [table (mapv (fn [{:keys [cmds desc spec]}]
@@ -51,18 +49,32 @@
(cli/format-opts {:spec (:spec cmd-map)})))))
(println "Command" (pr-str command) "does not exist")))
(defn- lazy-load-fn
"Lazy load fn to speed up start time. After nbb requires ~30 namespaces, start time gets close to 1s"
[fn-sym]
(fn [& args]
(p/let [_ (require (symbol (namespace fn-sym)))]
(apply (resolve fn-sym) args))))
(def ^:private table
[{:cmds ["list"] :fn cli-graph/list-graphs :desc "List graphs"}
{:cmds ["show"] :fn cli-graph/show-graph :desc "Show DB graph(s) info"
[{:cmds ["list"] :desc "List graphs"
:fn (lazy-load-fn 'logseq.cli.commands.graph/list-graphs)}
{:cmds ["show"] :desc "Show DB graph(s) info"
:fn (lazy-load-fn 'logseq.cli.commands.graph/show-graph)
:args->opts [:graphs] :coerce {:graphs []}}
{:cmds ["search"] :fn cli-search/search :desc "Search current DB graph"
{:cmds ["search"]
:fn (lazy-load-fn 'logseq.cli.commands.search/search)
:desc "Search current DB graph"
:args->opts [:search-terms] :coerce {:search-terms []}
:spec cli-search/spec}
{:cmds ["query"] :fn cli-query/query :desc "Query DB graph(s)"
:spec cli-spec/search}
{:cmds ["query"] :desc "Query DB graph(s)"
:fn (lazy-load-fn 'logseq.cli.commands.query/query)
:args->opts [:graph :queries] :coerce {:queries []} :no-keyword-opts true
:spec cli-query/spec}
{:cmds ["export-edn"] :fn cli-export-edn/export :desc "Export DB graph as EDN"
:args->opts [:graph] :spec cli-export-edn/spec}
:spec cli-spec/query}
{:cmds ["export-edn"] :desc "Export DB graph as EDN"
:fn (lazy-load-fn 'logseq.cli.commands.export-edn/export)
:args->opts [:graph]
:spec cli-spec/export-edn}
{:cmds ["help"] :fn command-help :desc "Print a command's help"
:args->opts [:command]}
{:cmds []

View File

@@ -6,26 +6,6 @@
[logseq.db.sqlite.export :as sqlite-export]
[logseq.cli.util :as cli-util]))
(def spec
"Options spec"
{:include-timestamps? {:alias :T
:desc "Include timestamps in export"}
:file {:alias :f
:desc "Saves edn to file"}
:catch-validation-errors? {:alias :c
:desc "Catch validation errors for dev"}
:exclude-namespaces {:alias :e
:coerce #{}
:desc "Namespaces to exclude from properties and classes"}
:exclude-built-in-pages? {:alias :b
:desc "Exclude built-in pages"}
:exclude-files? {:alias :F
:desc "Exclude :file/path files"}
:export-type {:alias :t
:coerce :keyword
:desc "Export type"
:default :graph}})
(defn export [{{:keys [graph] :as options} :opts}]
(if (fs/existsSync (cli-util/get-graph-dir graph))
(let [conn (apply sqlite-cli/open-db! (cli-util/->open-db-args graph))

View File

@@ -10,14 +10,6 @@
[logseq.db.frontend.rules :as rules]
[promesa.core :as p]))
(def spec
"Query spec"
{:graphs {:alias :g
:coerce []
:desc "Additional graphs to query"}
:api-query-token {:alias :a
:desc "Query current graph with api server token"}})
(defn- api-query
[query token]
(let [datalog-query? (string/starts-with? query "[")

View File

@@ -6,15 +6,6 @@
[logseq.cli.text-util :as cli-text-util]
[promesa.core :as p]))
(def spec {:api-query-token {:alias :a
:require true
:desc "Api server token"}
:raw {:alias :r
:desc "Print raw response"}
:limit {:alias :l
:default 100
:desc "Limit max number of results"}})
(defn- highlight
"Shows up as soft red on terminals that support ANSI 24-bit color like iTerm"
[text]

39
deps/cli/src/logseq/cli/spec.cljs vendored Normal file
View File

@@ -0,0 +1,39 @@
(ns logseq.cli.spec
"Specs for commands. Normally these would live alongside their commands but are separate
because command namespaces are lazy loaded")
(def export-edn
{:include-timestamps? {:alias :T
:desc "Include timestamps in export"}
:file {:alias :f
:desc "Saves edn to file"}
:catch-validation-errors? {:alias :c
:desc "Catch validation errors for dev"}
:exclude-namespaces {:alias :e
:coerce #{}
:desc "Namespaces to exclude from properties and classes"}
:exclude-built-in-pages? {:alias :b
:desc "Exclude built-in pages"}
:exclude-files? {:alias :F
:desc "Exclude :file/path files"}
:export-type {:alias :t
:coerce :keyword
:desc "Export type"
:default :graph}})
(def query
{:graphs {:alias :g
:coerce []
:desc "Additional graphs to query"}
:api-query-token {:alias :a
:desc "Query current graph with api server token"}})
(def search
{:api-query-token {:alias :a
:require true
:desc "Api server token"}
:raw {:alias :r
:desc "Print raw response"}
:limit {:alias :l
:default 100
:desc "Limit max number of results"}})