Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stores API reference (0.2 alpha)

Practical API for content stores and client composition in the reference implementation. App wiring: Anatomy and Same domain, local or HTTP. Internals: Content Stores, Rooted Stores.

Application stores (always rooted)

(require '[dacite.store :as s]
         '[dacite.value :as v])

(def r (v/root (s/mem)))
(def r (v/root (s/file "target/my-app")))
(def r (v/root (s/file "target/my-app" {:reset true})))
(def r (v/root (s/lmdb "target/my-lmdb")))           ; JVM, nbb
(def r (v/root (s/remote "http://127.0.0.1:8080")))  ; JVM
(v/cas! r nil seed)
(v/swap! r domain-update)

s/file and s/lmdb persist pack Layer-1 items (budget 1024) on root commit, not every constructor node. Reopen hydrates literals on read. Raw file-store / lmdb-store remain exploded content dictionaries.

(def books (s/lens rs (v/vector rs "books")))
(v/swap! (v/root books) v/conj record)

(s/lens rs path) is the same rooted API at a nested path (one document cell). path is a Dacite vector of Dacite keys; a host seq is the same sugar v/get-in already takes. Empty path is rs. Nested lenses concatenate. This is local convenience, not an HTTP path: a lens over s/remote still CASes the document hash.

Hashes are 4-word vectors ([w0 w1 w2 w3]). Helpers:

(s/hash->hex h)
(s/hex->hash "…64 hex chars…")

See Values — root and Rooted Stores chapter.


Not part of the app API

IStore (s-get, s-put, s-snapshot, …) is the content dictionary used by backends. Application code should not call it.

StoreHostInternal ctor
mem contentall(store/mem-store)
layeredall(store/layered-store …)
LRUall(dacite.store.lru/lru-store n)
file contentJVM, babashka(dacite.store.file/file-store path)
file contentnbb(dacite.store.nbb/file-store path)
LMDB contentJVM(dacite.store.jvm/lmdb-store path)

store/*store* and store/with-store are test/REPL bindings for the content dictionary, not the way to write an app. Use s/mem / s/file and pass that context to constructors.

nbb LMDB uses the same data.mdb layout as JVM (wire-v1 node payloads or pack items). Prebuilt lmdb npm binaries are format v2 — rebuild with LMDB_DATA_V1=true npm rebuild lmdb.


Client composition (remote / sync)

Interactive clients usually stack:

application Values
    ↓
write-back cache     (dacite.store.client-cache/wrap … :write-back)
    ↓
pack / chunk transport   (IChunkTransport + pack/flush-from!)
    ↓
optional rate-limit      (dacite.store.rate-limit)
    ↓
remote HTTP store        (dacite.store.remote | dacite.store.browser)
ModuleRole
dacite.store.client-cacheLocal mem + flush reachable on CAS / explicit flush
dacite.store.packSoft budget packing, flush-from!, apply-chunk!, literals
dacite.store.rate-limitThrottle send path (outermost IChunkTransport wins). Server inbound admit is dacite.service.throttle (429), not this wrapper.
dacite.store.statsBandwidth accounting for store-protocol bodies
dacite.store.remoteJVM HTTP client (:binary true default for packs); watch-root is GET /events
dacite.store.browserBrowser sync XHR demo client (:binary true default)

pack/flush-from! finds the outermost IChunkTransport and sends budgeted chunks (default soft budget 1024 bytes).


Wire: EDN vs wire-v1

ContextFormat
Pack chunk GET /node/{hex}wire-v1 chunk (application/vnd.dacite.chunk.v1)
Pack chunk POST /nodeswire-v1 chunk
Novelty PUT body, /root, CASEDN
LMDB content valueswire-v1 node payload only (no chunk/literal framing)
File store on diskEDN (host-local; not multi-lang interop)
  • Spec: wire-v1 (repo) / book Serialization appendix
  • Codec: dacite.wire.binary (portable .cljc — JVM + CLJS/nbb)
  • EDN helpers: dacite.wire (read-edn / write-edn)
  • Opt out: {:binary false} on remote/browser store constructors

Service dual-stack: dacite.service honors Content-Type / Accept.


Alpha quality notes

  • HTTP service and remotes are experimental but usable for demos and tests
  • Browser remote is sync XHR (main-thread blocking) — not production networking
  • APIs may change before 1.0; see CHANGELOG