Skip to content

Commit

Permalink
Test two ways to get regular atoms work in reactive context
Browse files Browse the repository at this point in the history
Related to #546
  • Loading branch information
Deraen committed Sep 3, 2021
1 parent b71fc36 commit 93f2590
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/reagent/ratom.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,69 @@
(flush!)))
(dispose! res))))
(ratom-perf))

(deftype WrappedAtom [x]
IAtom
IReactiveAtom

IEquiv
(-equiv [o other] (identical? o other))

IDeref
(-deref [this]
(notify-deref-watcher! x)
@x)

IReset
(-reset! [a new-value]
(reset! x new-value))

ISwap
(-swap! [a f] (swap! x f))
(-swap! [a f x] (swap! x f x))
(-swap! [a f x y] (swap! x f x y))
(-swap! [a f x y more] (swap! x f x y more))

IWithMeta
(-with-meta [_ new-meta]
(WrappedAtom. (with-meta x new-meta)))

IMeta
(-meta [_] (meta x))

IPrintWithWriter
(-pr-writer [a w opts] (pr-atom a w opts "WrappedAtom" {:atom x}))

IWatchable
(-notify-watches [this old new] (-notify-watches x old new))
(-add-watch [this key f] (-add-watch x key f))
(-remove-watch [this key] (-remove-watch x key))

IHash
(-hash [this] (goog/getUid this)))

(defn ->ratom
"Wraps Atom like object so that it notifies current reactive context
on deref.
The object must implement be a cljs.core.Atom or
implement IDeref, IWatchable, IReset, ISwap, IMeta and IWithMeta."
[v]
(WrappedAtom. v))

;; Or:
;; Both wouldn't be implemented, but not sure right now which
;; is better.

;; TODO: Better name
(defn reagent-deref
"Deref a Atom and register watcher to current Reactive
context, so that the context will be notified if the Atom
value is updated.
This will enable using Atom in place of RAtom and Reactions,
as long as you remember to use this function instead of directly
dereferecing the Atom."
[a]
(notify-deref-watcher! a)
@a)
45 changes: 45 additions & 0 deletions test/reagenttest/testratom.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -483,3 +483,48 @@
(pr-str (r/track (fn foo [] (:foo @x))))))
(is (= "#object[reagent.ratom.Reaction {:val 1}]"
(pr-str (reaction (:foo @x)))))))

(deftest adapt-regular-atom-test
(testing "WrappedAtom"
(let [runs (running)
start (rv/->ratom (atom 0))
sv (reaction @start)
comp (reaction @sv (+ 2 @sv))
c2 (reaction (inc @comp))
count (rv/atom 0)
out (rv/atom 0)
res (reaction
(swap! count inc)
@sv @c2 @comp)
const (run!
(reset! out @res))]
(is (= @count 1) "constrain ran")
(is (= @out 2))
(reset! start 1)
(r/flush)
(is (= @out 3))
(is (<= 2 @count 3))
(dispose const)
(is (= (running) runs))))

(testing "reagent-deref"
(let [runs (running)
start (atom 0)
sv (reaction (rv/reagent-deref start))
comp (reaction @sv (+ 2 @sv))
c2 (reaction (inc @comp))
count (rv/atom 0)
out (rv/atom 0)
res (reaction
(swap! count inc)
@sv @c2 @comp)
const (run!
(reset! out @res))]
(is (= @count 1) "constrain ran")
(is (= @out 2))
(reset! start 1)
(r/flush)
(is (= @out 3))
(is (<= 2 @count 3))
(dispose const)
(is (= (running) runs)))))

0 comments on commit 93f2590

Please sign in to comment.