Skip to content

Commit

Permalink
Merge pull request #13 from rafaeldelboni/main
Browse files Browse the repository at this point in the history
Refactor: flex.promise/resource accepts multi args fetcher function and no call on init
lilactown authored Feb 16, 2024
2 parents 25a96d6 + cc416ee commit 4b1bd05
Showing 3 changed files with 96 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@
/.cpcache/
/cljs-test-runner-out/
/.clj-kondo/.cache/
/.lsp/.cache/
83 changes: 62 additions & 21 deletions src/town/lilac/flex/promise.cljs
Original file line number Diff line number Diff line change
@@ -2,29 +2,70 @@
(:require
[town.lilac.flex :as flex]))

(defrecord Resource [state error value loading? fetcher ^:volatile-mutable p]
(defn fetcher-fn [state error value fetcher & args]
(flex/untrack
(case @state
(:unresolved :ready :error) (.then (apply fetcher args)
(fn [x]
(flex/batch
(state :ready)
(value x)))
(fn [e]
(flex/batch
(state :error)
(error e))))
nil)
(case @state
:unresolved (state :pending)
(:ready :error) (state :refreshing)
nil)))

(defrecord Resource [state error value loading? fetcher ^:volatile-mutable pr]
IDeref
(-deref [_] @value)
IFn
(-invoke [this]
(flex/untrack
(case @state
(:unresolved :ready :error)
(set! p (.then (fetcher)
(fn [x]
(flex/batch
(state :ready)
(value x)))
(fn [e]
(flex/batch
(state :error)
(error e)))))
nil)
(case @state
:unresolved (state :pending)
(:ready :error) (state :refreshing)
nil))
this))
(set! pr (fetcher-fn state error value fetcher)) this)
(-invoke [this a]
(set! pr (fetcher-fn state error value fetcher a)) this)
(-invoke [this a b]
(set! pr (fetcher-fn state error value fetcher a b)) this)
(-invoke [this a b c]
(set! pr (fetcher-fn state error value fetcher a b c)) this)
(-invoke [this a b c d]
(set! pr (fetcher-fn state error value fetcher a b c d)) this)
(-invoke [this a b c d e]
(set! pr (fetcher-fn state error value fetcher a b c d e)) this)
(-invoke [this a b c d e f]
(set! pr (fetcher-fn state error value fetcher a b c d e f)) this)
(-invoke [this a b c d e f g]
(set! pr (fetcher-fn state error value fetcher a b c d e f g)) this)
(-invoke [this a b c d e f g h]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h)) this)
(-invoke [this a b c d e f g h i]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i)) this)
(-invoke [this a b c d e f g h i j]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j)) this)
(-invoke [this a b c d e f g h i j k]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k)) this)
(-invoke [this a b c d e f g h i j k l]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l)) this)
(-invoke [this a b c d e f g h i j k l m]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m)) this)
(-invoke [this a b c d e f g h i j k l m n]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n)) this)
(-invoke [this a b c d e f g h i j k l m n o]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o)) this)
(-invoke [this a b c d e f g h i j k l m n o p]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o p)) this)
(-invoke [this a b c d e f g h i j k l m n o p q]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o p q)) this)
(-invoke [this a b c d e f g h i j k l m n o p q r]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o p q r)) this)
(-invoke [this a b c d e f g h i j k l m n o p q r s]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o p q r s)) this)
(-invoke [this a b c d e f g h i j k l m n o p q r s t]
(set! pr (fetcher-fn state error value fetcher a b c d e f g h i j k l m n o p q r s t)) this))

(defn resource
"Returns a flex source that updates its state based on a promise-returning
@@ -40,7 +81,7 @@
`:loading?` - a signal containing true/false whether currently waiting for a
promise returned by `fetcher` to fulfill
`:fetcher` - the original `fetcher` function
`:p` - the last promise returned by `fetcher`"
`:pr` - the last promise returned by `fetcher`"
[fetcher]
(let [state (flex/source :unresolved)
error (flex/source nil)
@@ -49,4 +90,4 @@
(case @state
(:pending :refreshing) true
false))]
((->Resource state error value loading? fetcher nil))))
(->Resource state error value loading? fetcher nil)))
35 changes: 33 additions & 2 deletions test/town/lilac/flex/promise_test.cljs
Original file line number Diff line number Diff line change
@@ -11,15 +11,16 @@
(fn [] (res))
ms))))

(deftest resource
(deftest fetcher-with-noargs-resource
(async
done
(let [r (p/resource (fn []
(-> (sleep 100)
(.then (constantly 42)))))
_call-r (r) ; initializing
*calls (atom [])
s (f/signal (inc @(:value r)))
fx (f/effect [] (swap! *calls conj @s))]
_fx (f/effect [] (swap! *calls conj @s))]
(is (= :pending @(:state r)))
;; (is (= :unresolved @(:state r)))
(is (= nil @(:value r)))
@@ -34,5 +35,35 @@
(is (= [1 43] @*calls))))
(.then done done)))))

(deftest fetcher-with-args-resource
(async
done
(let [r (p/resource (fn [ms]
(-> (sleep ms)
(.then (constantly 42)))))
_call-r (r 200) ; initializing
*calls (atom [])
s (f/signal (inc @(:value r)))
_fx (f/effect [] (swap! *calls conj @s))]
(is (= :pending @(:state r)))
;; (is (= :unresolved @(:state r)))
(is (= nil @(:value r)))
(is (= nil @(:error r)))
(is (= [1] @*calls))
;; (r)
;; (is (= :pending @(:state r)))
(-> (sleep 101)
(.then (fn []
(is (= :pending @(:state r)))
(is (= nil @(:value r)))
(is (= [1] @*calls))))
(.then done done))
(-> (sleep 201)
(.then (fn []
(is (= :ready @(:state r)))
(is (= 42 @(:value r)))
(is (= [1 43] @*calls))))
(.then done done)))))

(comment
(t/run-tests))

0 comments on commit 4b1bd05

Please sign in to comment.