refactor: rename library from pocketbook to atomsync

This commit is contained in:
Florian Schroedl
2026-04-16 20:18:45 +02:00
parent bcf7e03332
commit b68f97247a
20 changed files with 73 additions and 73 deletions

View File

@@ -1,4 +1,4 @@
# Pocketbook
# Atomsync
Clojure/ClojureScript offline-first synced atom library backed by IndexedDB (CLJS) or SQLite (CLJ).
@@ -24,7 +24,7 @@ This project uses **promesa** (`funcool/promesa`) for all async operations. Do n
## Project structure
```
src/pocketbook/
src/atomsync/
store.cljc — PStore protocol (promises)
store/memory.cljc — in-memory store (testing/JVM)
store/idb.cljs — IndexedDB store (browser)

View File

@@ -1,10 +1,10 @@
# Pocketbook
# Atomsync
A Clojure-native synced atom. Offline-first key-value store with an `atom` interface that syncs to a SQLite-backed server over Transit.
```clojure
(def conn (<! (pocketbook/open "my-app")))
(def todos (pocketbook/synced-atom conn "todo" {:server "http://localhost:8090/sync"}))
(def conn (<! (atomsync/open "my-app")))
(def todos (atomsync/synced-atom conn "todo" {:server "http://localhost:8090/sync"}))
(swap! todos assoc "todo:1" {:text "Buy milk" :tags #{:groceries}})
@todos ;=> {"todo:1" {:text "Buy milk" :tags #{:groceries}}}
@@ -26,13 +26,13 @@ clj -M:server
# or: clj -M:server 8090 my-data.db
```
Starts on `http://localhost:8090` with a SQLite file at `pocketbook.db`.
Starts on `http://localhost:8090` with a SQLite file at `atomsync.db`.
### Client (CLJS)
```clojure
(ns my-app.core
(:require [pocketbook.core :as pb]
(:require [atomsync.core :as pb]
[cljs.core.async :refer [go <!]]))
(go
@@ -94,7 +94,7 @@ Client passes token:
```bash
# All server tests
clj -M:dev -e '(require (quote pocketbook.db-test) (quote pocketbook.transit-test) (quote pocketbook.server-test) (quote pocketbook.auth-test)) (clojure.test/run-all-tests #"pocketbook\..*")'
clj -M:dev -e '(require (quote atomsync.db-test) (quote atomsync.transit-test) (quote atomsync.server-test) (quote atomsync.auth-test)) (clojure.test/run-all-tests #"atomsync\..*")'
```
## License

24
bb.edn
View File

@@ -1,5 +1,5 @@
{:tasks
{server {:doc "Start the Pocketbook sync server (serves example app)"
{server {:doc "Start the Atomsync sync server (serves example app)"
:task (shell "clj" "-M:server" "--static-dir" "example/todomvc")}
cljs {:doc "Compile ClojureScript (one-shot)"
@@ -13,26 +13,26 @@
:task (shell "clj" "-M:cljs-dev")}
test {:doc "Run all server tests"
:task (let [expr (str "(require 'pocketbook.db-test 'pocketbook.transit-test"
" 'pocketbook.server-test 'pocketbook.core-test)"
" (let [r (clojure.test/run-all-tests #\"pocketbook\\..*\")]"
:task (let [expr (str "(require 'atomsync.db-test 'atomsync.transit-test"
" 'atomsync.server-test 'atomsync.core-test)"
" (let [r (clojure.test/run-all-tests #\"atomsync\\..*\")]"
" (System/exit (if (and (zero? (:fail r)) (zero? (:error r))) 0 1)))")]
(shell "clj" "-M:dev" "-e" expr))}
dev {:doc "Start server and CLJS watch in tmux"
:task (let [dir (System/getProperty "user.dir")]
(shell {:dir dir} "tmux new-session -d -s pocketbook-dev -n server -c" dir)
(shell {:dir dir} "tmux send-keys -t pocketbook-dev:server" "bb server" "Enter")
(shell {:dir dir} "tmux new-window -t pocketbook-dev -n cljs -c" dir)
(shell {:dir dir} "tmux send-keys -t pocketbook-dev:cljs" "bb cljs:watch" "Enter")
(println "🔶 tmux session 'pocketbook-dev' started")
(shell {:dir dir} "tmux new-session -d -s atomsync-dev -n server -c" dir)
(shell {:dir dir} "tmux send-keys -t atomsync-dev:server" "bb server" "Enter")
(shell {:dir dir} "tmux new-window -t atomsync-dev -n cljs -c" dir)
(shell {:dir dir} "tmux send-keys -t atomsync-dev:cljs" "bb cljs:watch" "Enter")
(println "🔶 tmux session 'atomsync-dev' started")
(println " App: http://localhost:8090")
(println " Server: http://localhost:8090/sync")
(println " Attach: tmux attach -t pocketbook-dev"))}
(println " Attach: tmux attach -t atomsync-dev"))}
dev:stop {:doc "Stop the dev tmux session"
:task (shell "tmux kill-session -t pocketbook-dev")}
:task (shell "tmux kill-session -t atomsync-dev")}
dev:restart {:doc "Restart the dev tmux session"
:task (do (shell {:continue true} "tmux kill-session -t pocketbook-dev")
:task (do (shell {:continue true} "tmux kill-session -t atomsync-dev")
(run 'dev))}}}

View File

@@ -1,4 +1,4 @@
{:main pocketbook.todomvc
{:main atomsync.todomvc
:output-to "example/todomvc/js/main.js"
:output-dir "example/todomvc/js/out"
:asset-path "js/out"

View File

@@ -13,7 +13,7 @@
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}}}
:test {:main-opts ["-m" "cognitect.test-runner"]}
:server {:main-opts ["-m" "pocketbook.server"]}
:server {:main-opts ["-m" "atomsync.server"]}
;; ClojureScript client build
:cljs {:extra-paths ["example/todomvc"]
@@ -24,4 +24,4 @@
:cljs-dev {:extra-paths ["example/todomvc"]
:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.132"}
com.cognitect/transit-cljs {:mvn/version "0.8.280"}}
:main-opts ["-m" "cljs.main" "-co" "build.edn" "-w" "src:example/todomvc/pocketbook" "-c"]}}}
:main-opts ["-m" "cljs.main" "-co" "build.edn" "-w" "src:example/todomvc/atomsync" "-c"]}}}

View File

@@ -1,4 +1,4 @@
(ns pocketbook.hiccup
(ns atomsync.hiccup
"Minimal hiccup → HTML string renderer."
(:require [clojure.string :as str]))

View File

@@ -1,8 +1,8 @@
(ns pocketbook.todomvc
"TodoMVC built on Pocketbook — offline-first, synced, Clojure-native."
(:require [pocketbook.core :as pb]
[pocketbook.store.idb :as idb]
[pocketbook.hiccup :refer [html]]
(ns atomsync.todomvc
"TodoMVC built on Atomsync — offline-first, synced, Clojure-native."
(:require [atomsync.core :as pb]
[atomsync.store.idb :as idb]
[atomsync.hiccup :refer [html]]
[promesa.core :as p]
[clojure.string :as str]))
@@ -232,7 +232,7 @@
;; ---------------------------------------------------------------------------
(defn ^:export init []
(p/let [store (idb/open "pocketbook-todomvc")]
(p/let [store (idb/open "atomsync-todomvc")]
(let [todos (pb/synced-atom store "todo"
{:server "http://localhost:8090/sync"
:interval 15000})]
@@ -248,6 +248,6 @@
(.addEventListener js/window "offline" (fn [_] (render!)))
;; Wait for IDB — watch triggers render automatically
(p/let [_ (pb/ready? todos)]
(js/console.log "🔶 Pocketbook TodoMVC loaded —" (count @todos) "todos")))))
(js/console.log "🔶 Atomsync TodoMVC loaded —" (count @todos) "todos")))))
(init)

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pocketbook · TodoMVC</title>
<title>Atomsync · TodoMVC</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Mono:wght@300;400;500&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;1,6..72,400&display=swap" rel="stylesheet">
@@ -399,14 +399,14 @@
<body>
<div class="wrapper">
<div class="brand">
<span class="brand-label">Pocketbook · TodoMVC</span>
<span class="brand-label">Atomsync · TodoMVC</span>
</div>
<div id="app">
<div class="loading">Loading from local store</div>
</div>
<div class="info">
<p>Double-click to edit a todo</p>
<p>Built with <a href="https://github.com/pocketbook">Pocketbook</a> — offline-first synced atoms for Clojure</p>
<p>Built with <a href="https://github.com/atomsync">Atomsync</a> — offline-first synced atoms for Clojure</p>
<p>Data persists in IndexedDB · syncs via Transit to SQLite</p>
</div>
</div>

View File

@@ -1,5 +1,5 @@
(ns pocketbook.core
"Pocketbook: a Clojure-native synced atom.
(ns atomsync.core
"Atomsync: a Clojure-native synced atom.
Usage:
(def store @(idb/open \"my-app\")) ;; or (memory/create)
@@ -9,8 +9,8 @@
(fn [_] (swap! todos assoc \"todo:1\" {:text \"Buy milk\"})))
@todos ;=> {\"todo:1\" {:text \"Buy milk\"}}
"
(:require [pocketbook.store :as store]
[pocketbook.sync :as sync]
(:require [atomsync.store :as store]
[atomsync.sync :as sync]
[clojure.string :as str]
[promesa.core :as p])
#?(:clj (:import [java.util.concurrent Executors ScheduledExecutorService TimeUnit])))

View File

@@ -1,4 +1,4 @@
(ns pocketbook.db
(ns atomsync.db
"SQLite storage layer with Nippy serialization.
Stores documents as binary blobs preserving all Clojure types."
(:require [next.jdbc :as jdbc]

View File

@@ -1,5 +1,5 @@
(ns pocketbook.server
"Pocketbook sync server. Single-file HTTP server backed by SQLite.
(ns atomsync.server
"Atomsync sync server. Single-file HTTP server backed by SQLite.
Endpoints:
GET /sync?since=T&group=G pull changes since timestamp
@@ -7,10 +7,10 @@
Start:
clj -M:server
bb -m pocketbook.server"
bb -m atomsync.server"
(:require [org.httpkit.server :as http]
[pocketbook.db :as db]
[pocketbook.transit :as t]
[atomsync.db :as db]
[atomsync.transit :as t]
[clojure.string :as str]
[clojure.java.io :as io])
(:gen-class))
@@ -21,7 +21,7 @@
(def default-config
{:port 8090
:db-path "pocketbook.db"
:db-path "atomsync.db"
:static-dir nil ;; nil = no static serving, or path like "example/todomvc"
:cors true})
@@ -205,7 +205,7 @@
;; ---------------------------------------------------------------------------
(defn start!
"Start the Pocketbook server. Returns a stop function."
"Start the Atomsync server. Returns a stop function."
([]
(start! {}))
([config]
@@ -213,7 +213,7 @@
ds (db/open (:db-path config))
handler (make-handler ds config)
server (http/run-server handler {:port (:port config)})]
(println (str "🔶 Pocketbook server running on http://localhost:" (:port config)))
(println (str "🔶 Atomsync server running on http://localhost:" (:port config)))
(println (str " Database: " (:db-path config)))
(when (:static-dir config)
(println (str " Static: " (:static-dir config)))

View File

@@ -1,5 +1,5 @@
(ns pocketbook.store
"Storage protocol for Pocketbook.
(ns atomsync.store
"Storage protocol for Atomsync.
All methods return promesa promises.")
(defprotocol PStore

View File

@@ -1,7 +1,7 @@
(ns pocketbook.store.idb
(ns atomsync.store.idb
"IndexedDB store implementing the PStore protocol."
(:require [pocketbook.store :as store]
[pocketbook.transit :as transit]
(:require [atomsync.store :as store]
[atomsync.transit :as transit]
[promesa.core :as p]))
;; ---------------------------------------------------------------------------

View File

@@ -1,6 +1,6 @@
(ns pocketbook.store.memory
(ns atomsync.store.memory
"In-memory store backed by atoms. Useful for testing and JVM clients."
(:require [pocketbook.store :as store]
(:require [atomsync.store :as store]
[promesa.core :as p]
[clojure.string :as str]))

View File

@@ -1,6 +1,6 @@
(ns pocketbook.sync
"HTTP sync client — pull and push documents to/from the Pocketbook server."
(:require [pocketbook.transit :as transit]
(ns atomsync.sync
"HTTP sync client — pull and push documents to/from the Atomsync server."
(:require [atomsync.transit :as transit]
[clojure.string :as str]
[promesa.core :as p])
#?(:clj (:import [java.net URI]

View File

@@ -1,4 +1,4 @@
(ns pocketbook.transit
(ns atomsync.transit
"Transit encoding/decoding helpers for the HTTP wire format."
(:require [cognitect.transit :as t])
#?(:clj (:import [java.io ByteArrayInputStream ByteArrayOutputStream])))

View File

@@ -1,10 +1,10 @@
(ns pocketbook.core-test
(ns atomsync.core-test
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[promesa.core :as p]
[pocketbook.core :as pb]
[pocketbook.store :as store]
[pocketbook.store.memory :as memory]
[pocketbook.server :as server])
[atomsync.core :as pb]
[atomsync.store :as store]
[atomsync.store.memory :as memory]
[atomsync.server :as server])
(:import [java.io File]))
;; ---------------------------------------------------------------------------
@@ -21,7 +21,7 @@
(use-fixtures :each
(fn [f]
(let [port (free-port)
db-path (str (File/createTempFile "pocketbook-core-test" ".db"))
db-path (str (File/createTempFile "atomsync-core-test" ".db"))
srv (server/start! {:port port :db-path db-path})]
(Thread/sleep 200)
(try

View File

@@ -1,12 +1,12 @@
(ns pocketbook.db-test
(ns atomsync.db-test
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[pocketbook.db :as db])
[atomsync.db :as db])
(:import [java.io File]))
(def ^:dynamic *ds* nil)
(defn- temp-db-path []
(str (File/createTempFile "pocketbook-test" ".db")))
(str (File/createTempFile "atomsync-test" ".db")))
(use-fixtures :each
(fn [f]

View File

@@ -1,7 +1,7 @@
(ns pocketbook.server-test
(ns atomsync.server-test
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[pocketbook.server :as server]
[pocketbook.transit :as t])
[atomsync.server :as server]
[atomsync.transit :as t])
(:import [java.io File]
[java.net URI]
[java.net.http HttpClient HttpRequest HttpResponse$BodyHandlers HttpRequest$BodyPublishers]))
@@ -16,7 +16,7 @@
(use-fixtures :each
(fn [f]
(let [port (free-port)
db-path (str (File/createTempFile "pocketbook-server-test" ".db"))
db-path (str (File/createTempFile "atomsync-server-test" ".db"))
srv (server/start! {:port port :db-path db-path})]
(Thread/sleep 200) ;; let server start
(try

View File

@@ -1,6 +1,6 @@
(ns pocketbook.transit-test
(ns atomsync.transit-test
(:require [clojure.test :refer [deftest is testing]]
[pocketbook.transit :as t]))
[atomsync.transit :as t]))
(deftest roundtrip-basic-types
(doseq [v [42