diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index 6e096ff..385331f 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -160,8 +160,9 @@ (declare fetch-posts!) (defn- fetch-application-settings [] - (->> (db/open-cursor ::db/application ::db/all) - (db/first-result (map #(js->clj % :keywordize-keys true))))) + (let [cursor (db/open-cursor ::db/application ::db/all)] + (. (db/first-result cursor) + (then #(js->clj % :keywordize-keys true))))) (defn setup-application! "Handles Mastodon application setup on the client side" @@ -287,29 +288,32 @@ (defn- refresh-displayed-posts! [{:keys [per-page query]}] - (let [; this `xform` is responsible for filtering and building the final list - ; of results by iterating through the posts in the database. + (let [; this `xform` is responsible for filtering and building the list of + ; results that is displayed to the user. it iterates through all stored + ; posts in the database and returns a result that will be rendered + ; by the `post` component below. xform (comp (filter (query->matching-fn query)) (take per-page) (map #(js->clj % :keywordize-keys true))) + posts-cursor (db/open-cursor ::db/posts + ::db/all + {:index ::db/post-created-at + :direction :desc}) refresh-id (now)] (swap! state update-in [:section/posts :loading] conj refresh-id) (. (promise-all [(db/count ::db/posts) - (->> (db/open-cursor ::db/posts ::db/all - {:index ::db/post-created-at - :direction :desc}) - (db/transduce-cursor xform))]) + (db/transduce-cursor xform posts-cursor)]) (then (fn [[total displayed-posts]] (swap! state update :section/posts #(-> (assoc % :total total) (assoc :displayed-posts displayed-posts) (update :loading disj refresh-id)))))))) +(def debounced-refresh! (debounce 48 refresh-displayed-posts!)) + ; we use reagent's machinery below to define a callback that runs whenever the ; values change that serve as input to the current search reults. -(def debounced-refresh! (debounce 48 refresh-displayed-posts!)) - (def search-result-inputs (r/reaction (select-keys (:section/posts @state) [:query :per-page :last-update]))) (defonce update-search-results (r/track! (fn [] @@ -378,14 +382,15 @@ ; run and time a query on the database (do (js/console.log :start (.toISOString (js/Date.))) - (. (->> (db/open-cursor ::db/posts ::db/all) - (db/transduce-cursor (comp (mapcat (j/get :tags)) - (map (j/get :name)) - (filter #(= "typescript" %)) - (take 50)) conj (sorted-set))) - (then (fn [result] - (js/console.log :end (.toISOString (js/Date.))) - (js/console.log :accts result))))) + (let [xform (comp (mapcat (j/get :tags)) + #_(filter #(= "typescript" (j/get % :name))) + (take 10)) + posts-cursor (db/open-cursor ::db/posts ::db/all)] + (.. (db/transduce-cursor xform conj! (transient #{}) posts-cursor) + (then persistent!) + (then (fn [result] + (js/console.log :end (.toISOString (js/Date.))) + (js/console.log :accts result)))))) ) (defn post [{:keys [post]}] @@ -450,9 +455,9 @@ "Returns a promise which resolves to the smallest or largest internal post id. This is useful to continue interrupted paginated requests." [max-or-min] - (->> (db/open-cursor ::db/posts ::db/all {:index ::db/post-internal-id - :direction (if (= max-or-min :min) :asc :desc)}) - (db/first-result (keep (j/get :internal_id))))) + (let [posts-cursor (db/open-cursor ::db/posts ::db/all {:index ::db/post-internal-id + :direction (if (= max-or-min :min) :asc :desc)})] + (db/first-result (keep (j/get :internal_id)) posts-cursor))) (defn- fetch-more-posts! [e] (.preventDefault e) @@ -553,11 +558,11 @@ (defn- convert-internal-ids! [] ; TODO figure out when we can remove this again - (. (->> (db/open-cursor ::db/posts ::db/all) - (db/transduce-cursor (filter (comp string? (j/get :internal_id))))) - (then (fn [rows] - (doseq [row rows] - (db/put! ::db/posts (j/update! row :internal_id parse-long))))))) + (let [cursor (db/open-cursor ::db/posts ::db/all) + result (db/transduce-cursor (filter (comp string? (j/get :internal_id))) cursor)] + (.then result (fn [rows] + (doseq [row rows] + (db/put! ::db/posts (j/update! row :internal_id parse-long))))))) ;; go go go diff --git a/src/computersandblues/lodestone/database.cljs b/src/computersandblues/lodestone/database.cljs index 406c82a..7f2beba 100644 --- a/src/computersandblues/lodestone/database.cljs +++ b/src/computersandblues/lodestone/database.cljs @@ -161,8 +161,15 @@ (.continue cursor)))) (resolve @result))))))))) -(defn first-result [xform cursor-req] - (transduce-cursor (comp xform (take 1)) (fn [_ x] x) nil cursor-req)) +(defn first-result + "Given a cursor, will return a promise that resolves to the first result. + + Optionally takes an `xform` that can be used to filter or transform values + returned by the cursor." + ([cursor-req] + (first-result (map identity) cursor-req)) + ([xform cursor-req] + (transduce-cursor (comp xform (take 1)) (fn [_ x] x) nil cursor-req))) (comment