docs: add AGENTS.md with async conventions and project structure

This commit is contained in:
Florian Schroedl
2026-04-16 20:06:50 +02:00
parent 973b079ae3
commit bcf7e03332

42
AGENTS.md Normal file
View File

@@ -0,0 +1,42 @@
# Pocketbook
Clojure/ClojureScript offline-first synced atom library backed by IndexedDB (CLJS) or SQLite (CLJ).
## Async: use promesa, not core.async
This project uses **promesa** (`funcool/promesa`) for all async operations. Do not introduce `core.async`.
- **Store protocol** (`store.cljc`): all methods return promesa promises
- Sync operations (e.g. MemoryStore): `(p/resolved val)`
- Async operations (e.g. IDBStore): `(p/create (fn [resolve reject] ...))`
- **HTTP / sync** (`sync.cljc`): CLJ uses `p/vthread`, CLJS returns native JS Promise chains
- **Core** (`core.cljc`): `p/let` for sequential async, `p/all` for parallel
- **Sync loop**: platform timers (`setInterval` / `ScheduledExecutorService`), not go-loop
- **Push coalescing**: debounced with 50ms timer + `pushing?` atom guard, not channels
### Why not core.async
- Channels-as-one-shot-promises add ceremony (`chan` + `put!` + `close!`) for what is conceptually a return value
- promesa maps to native primitives: JS Promises on CLJS, CompletableFuture on CLJ
- `p/let` reads cleaner than `go` + `<!` for sequential async
- Timer-based sync loop is simpler than `go-loop` + `alts!` for this use case
## Project structure
```
src/pocketbook/
store.cljc — PStore protocol (promises)
store/memory.cljc — in-memory store (testing/JVM)
store/idb.cljs — IndexedDB store (browser)
sync.cljc — HTTP pull/push, SSE, connectivity
core.cljc — SyncedAtom, sync loop, public API
transit.cljc — Transit encoding/decoding
db.clj — SQLite server storage (nippy)
server.clj — HTTP sync server (http-kit)
```
## Running tests
```
clj -M:dev:test
```