feat: add TodoMVC example with editorial design
Full TodoMVC implementation using Pocketbook's synced atom: - Add, toggle, edit (double-click), destroy todos - Filter: All / Active / Completed - Toggle all, clear completed - Live sync status indicator (online/offline/pending) - Data persists in IndexedDB, syncs to server via Transit Design: Ink & Paper aesthetic — cream paper background with grain texture, Instrument Serif italic header, Newsreader body text, DM Mono UI chrome, terracotta accent with green completion marks, deckled left border on card. Also: - Server now serves static files from resources/public (/ → todomvc.html) - Fix CLJS compilation: resolve close!/put! naming conflicts with core.async, use qualified async/close!, add clojure.string require - Fix unbalanced parens in do-pull! - Remove old placeholder example
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"IndexedDB wrapper with Transit serialization.
|
||||
Stores documents as Transit-encoded strings preserving all Clojure types."
|
||||
(:require [cognitect.transit :as t]
|
||||
[cljs.core.async :refer [chan put! close!]]))
|
||||
[cljs.core.async :as async :refer [chan put!]]))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Transit
|
||||
@@ -40,11 +40,11 @@
|
||||
(set! (.-onsuccess req)
|
||||
(fn [e]
|
||||
(put! ch (.-result (.-target e)))
|
||||
(close! ch)))
|
||||
(async/close! ch)))
|
||||
(set! (.-onerror req)
|
||||
(fn [e]
|
||||
(js/console.error "IDB open error:" e)
|
||||
(close! ch)))
|
||||
(async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn- tx
|
||||
@@ -68,8 +68,8 @@
|
||||
:deleted (boolean (:deleted doc false))
|
||||
:synced (boolean (:synced doc false))}
|
||||
req (.put store obj)]
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (close! ch)))
|
||||
(set! (.-onerror req) (fn [e] (js/console.error "IDB put error:" e) (close! ch)))
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (async/close! ch)))
|
||||
(set! (.-onerror req) (fn [e] (js/console.error "IDB put error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn put-docs!
|
||||
@@ -86,8 +86,8 @@
|
||||
:deleted (boolean (:deleted doc false))
|
||||
:synced (boolean (:synced doc false))}]
|
||||
(.put store obj)))
|
||||
(set! (.-oncomplete txn) (fn [_] (put! ch true) (close! ch)))
|
||||
(set! (.-onerror txn) (fn [e] (js/console.error "IDB batch put error:" e) (close! ch)))
|
||||
(set! (.-oncomplete txn) (fn [_] (put! ch true) (async/close! ch)))
|
||||
(set! (.-onerror txn) (fn [e] (js/console.error "IDB batch put error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn get-doc
|
||||
@@ -107,9 +107,9 @@
|
||||
:updated (.-updated result)
|
||||
:deleted (.-deleted result)
|
||||
:synced (.-synced result)}))
|
||||
(close! ch))))
|
||||
(async/close! ch))))
|
||||
(set! (.-onerror req)
|
||||
(fn [e] (js/console.error "IDB get error:" e) (close! ch)))
|
||||
(fn [e] (js/console.error "IDB get error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn get-all-by-prefix
|
||||
@@ -137,9 +137,9 @@
|
||||
(.continue cursor))
|
||||
(do
|
||||
(put! ch @docs)
|
||||
(close! ch))))))
|
||||
(async/close! ch))))))
|
||||
(set! (.-onerror req)
|
||||
(fn [e] (js/console.error "IDB cursor error:" e) (close! ch)))
|
||||
(fn [e] (js/console.error "IDB cursor error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn get-unsynced
|
||||
@@ -166,9 +166,9 @@
|
||||
(.continue cursor))
|
||||
(do
|
||||
(put! ch @docs)
|
||||
(close! ch))))))
|
||||
(async/close! ch))))))
|
||||
(set! (.-onerror req)
|
||||
(fn [e] (js/console.error "IDB unsynced error:" e) (close! ch)))
|
||||
(fn [e] (js/console.error "IDB unsynced error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn delete-doc!
|
||||
@@ -178,8 +178,8 @@
|
||||
txn (tx db "docs" :readwrite)
|
||||
store (.objectStore txn "docs")
|
||||
req (.delete store id)]
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (close! ch)))
|
||||
(set! (.-onerror req) (fn [e] (js/console.error "IDB delete error:" e) (close! ch)))
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (async/close! ch)))
|
||||
(set! (.-onerror req) (fn [e] (js/console.error "IDB delete error:" e) (async/close! ch)))
|
||||
ch))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
@@ -197,8 +197,8 @@
|
||||
(fn [e]
|
||||
(let [result (.-result (.-target e))]
|
||||
(put! ch (when result (.-value result)))
|
||||
(close! ch))))
|
||||
(set! (.-onerror req) (fn [_] (close! ch)))
|
||||
(async/close! ch))))
|
||||
(set! (.-onerror req) (fn [_] (async/close! ch)))
|
||||
ch))
|
||||
|
||||
(defn set-meta!
|
||||
@@ -208,15 +208,15 @@
|
||||
txn (tx db "meta" :readwrite)
|
||||
store (.objectStore txn "meta")
|
||||
req (.put store #js {:key key :value value})]
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (close! ch)))
|
||||
(set! (.-onerror req) (fn [_] (close! ch)))
|
||||
(set! (.-onsuccess req) (fn [_] (put! ch true) (async/close! ch)))
|
||||
(set! (.-onerror req) (fn [_] (async/close! ch)))
|
||||
ch))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Close
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defn close!
|
||||
(defn close-db!
|
||||
"Close the IDB connection."
|
||||
[db]
|
||||
(when db (.close db)))
|
||||
|
||||
Reference in New Issue
Block a user