refactor: rename library from pocketbook to atomsync
This commit is contained in:
@@ -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)
|
||||
|
||||
12
README.md
12
README.md
@@ -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
24
bb.edn
@@ -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))}}}
|
||||
|
||||
@@ -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"
|
||||
|
||||
4
deps.edn
4
deps.edn
@@ -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"]}}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns pocketbook.hiccup
|
||||
(ns atomsync.hiccup
|
||||
"Minimal hiccup → HTML string renderer."
|
||||
(:require [clojure.string :as str]))
|
||||
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
|
||||
@@ -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])))
|
||||
@@ -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]
|
||||
@@ -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)))
|
||||
@@ -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
|
||||
@@ -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]))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
@@ -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]))
|
||||
|
||||
@@ -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]
|
||||
@@ -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])))
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user