refactor: replace core.async with promesa for all async operations
- Store protocol now returns promesa promises instead of core.async channels - MemoryStore: `(p/resolved val)` replaces chan+put!+close! ceremony - IDBStore: `p/create` with resolve/reject wraps IDB callbacks - sync.cljc: CLJ uses `p/vthread`, CLJS returns native Promise chains - core.cljc: `p/let` replaces go blocks, timer-based sync loop replaces go-loop+alts!, debounced push replaces kick channel - Tests use `deref` with timeout on promesa promises - Todomvc example uses `p/let` instead of go/<!
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
(ns pocketbook.core-test
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[clojure.core.async :as async :refer [<!! go <! timeout]]
|
||||
[promesa.core :as p]
|
||||
[pocketbook.core :as pb]
|
||||
[pocketbook.store :as store]
|
||||
[pocketbook.store.memory :as memory]
|
||||
@@ -38,11 +38,10 @@
|
||||
;; Helpers
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defn- <!!timeout
|
||||
"Take from channel with timeout. Returns nil on timeout."
|
||||
[ch ms]
|
||||
(let [[v _] (<!! (go (async/alts! [ch (timeout ms)])))]
|
||||
v))
|
||||
(defn- await!
|
||||
"Deref a promise with timeout. Returns nil on timeout."
|
||||
[promise ms]
|
||||
(deref promise ms nil))
|
||||
|
||||
(defn- wait-synced
|
||||
"Wait until the synced atom has no pending changes."
|
||||
@@ -62,7 +61,7 @@
|
||||
(testing "SyncedAtom works without a server (local store only)"
|
||||
(let [store (memory/create)
|
||||
sa (pb/synced-atom store "todo")]
|
||||
(<!!timeout (pb/ready? sa) 1000)
|
||||
(await! (pb/ready? sa) 1000)
|
||||
(is (= {} @sa))
|
||||
|
||||
(swap! sa assoc "todo:1" {:text "Buy milk"})
|
||||
@@ -81,13 +80,13 @@
|
||||
(testing "Changes are persisted to the store"
|
||||
(let [store (memory/create)
|
||||
sa (pb/synced-atom store "todo")]
|
||||
(<!!timeout (pb/ready? sa) 1000)
|
||||
(await! (pb/ready? sa) 1000)
|
||||
|
||||
(swap! sa assoc "todo:1" {:text "Buy milk"})
|
||||
(Thread/sleep 50) ;; let async store write complete
|
||||
|
||||
;; Read from store directly
|
||||
(let [docs (<!!timeout (store/docs-by-prefix store "todo:") 1000)]
|
||||
(let [docs (await! (store/docs-by-prefix store "todo:") 1000)]
|
||||
(is (= 1 (count docs)))
|
||||
(is (= "todo:1" (:id (first docs))))
|
||||
(is (= {:text "Buy milk"} (:value (first docs)))))
|
||||
@@ -98,13 +97,13 @@
|
||||
(testing "SyncedAtom loads existing data from store on creation"
|
||||
(let [store (memory/create)]
|
||||
;; Pre-populate the store
|
||||
(<!!timeout (store/put-doc! store
|
||||
{:id "todo:1" :value {:text "Existing"}
|
||||
:version 1 :updated 1000 :deleted false :synced true})
|
||||
1000)
|
||||
(await! (store/put-doc! store
|
||||
{:id "todo:1" :value {:text "Existing"}
|
||||
:version 1 :updated 1000 :deleted false :synced true})
|
||||
1000)
|
||||
|
||||
(let [sa (pb/synced-atom store "todo")]
|
||||
(<!!timeout (pb/ready? sa) 1000)
|
||||
(await! (pb/ready? sa) 1000)
|
||||
(is (= {:text "Existing"} (get @sa "todo:1")))
|
||||
(pb/destroy! sa)))))
|
||||
|
||||
@@ -113,7 +112,7 @@
|
||||
(let [store (memory/create)
|
||||
sa (pb/synced-atom store "todo")
|
||||
changes (atom [])]
|
||||
(<!!timeout (pb/ready? sa) 1000)
|
||||
(await! (pb/ready? sa) 1000)
|
||||
|
||||
(add-watch sa :test (fn [_ _ old new]
|
||||
(swap! changes conj {:old old :new new})))
|
||||
@@ -133,7 +132,7 @@
|
||||
(let [store (memory/create)
|
||||
sa (pb/synced-atom store "todo"
|
||||
{:server (server-url)})]
|
||||
(<!!timeout (pb/ready? sa) 2000)
|
||||
(await! (pb/ready? sa) 2000)
|
||||
|
||||
(swap! sa assoc "todo:push1" {:text "Pushed!"})
|
||||
(Thread/sleep 500) ;; let push complete
|
||||
@@ -149,15 +148,15 @@
|
||||
{:server (server-url) :interval 500})
|
||||
sa-b (pb/synced-atom store-b "todo"
|
||||
{:server (server-url) :interval 500})]
|
||||
(<!!timeout (pb/ready? sa-a) 2000)
|
||||
(<!!timeout (pb/ready? sa-b) 2000)
|
||||
(await! (pb/ready? sa-a) 2000)
|
||||
(await! (pb/ready? sa-b) 2000)
|
||||
|
||||
;; Client A writes
|
||||
(swap! sa-a assoc "todo:sync1" {:text "From A"})
|
||||
(Thread/sleep 500) ;; let A push
|
||||
|
||||
;; Trigger a sync on B
|
||||
(<!!timeout (pb/sync-now! sa-b) 2000)
|
||||
(await! (pb/sync-now! sa-b) 2000)
|
||||
|
||||
;; B should have A's data
|
||||
(is (= {:text "From A"} (get @sa-b "todo:sync1")))
|
||||
@@ -169,7 +168,7 @@
|
||||
(testing "Standard atom operations work"
|
||||
(let [store (memory/create)
|
||||
sa (pb/synced-atom store "note")]
|
||||
(<!!timeout (pb/ready? sa) 1000)
|
||||
(await! (pb/ready? sa) 1000)
|
||||
|
||||
;; reset!
|
||||
(reset! sa {"note:1" {:body "Hello"}})
|
||||
|
||||
Reference in New Issue
Block a user