Complete reference for Eve's public API surface.
| Namespace | Platform | Purpose |
|---|---|---|
eve.alpha |
CLJS + CLJ | Public API entry point |
eve.shared-atom |
CLJS only | SAB-backed atom internals |
eve.obj |
CLJS + CLJ | Typed shared objects (AoS/SoA) |
eve.array |
CLJS + CLJ | Typed array API |
eve.deftype.int-map |
CLJS only | Integer map (PATRICIA trie) |
eve.deftype.rb-tree |
CLJS only | Sorted set (red-black tree) |
(ns my-app.core
(:require [eve.alpha :as e]))Dispatches between SAB-backed (in-memory) and mmap-backed (persistent) atoms based on the presence of :persistent in the config.
;; --- In-memory (SAB-backed on CLJS, heap-backed on JVM) ---
;; Anonymous atom
(e/atom {:count 0})
;; Named atom (keyword shorthand)
(e/atom ::counter {:count 0})
;; Named atom (config map)
(e/atom {:id ::counter} {:count 0})
;; --- Persistent (mmap-backed, disk files) ---
;; Named persistent atom, explicit domain path
(e/atom {:id ::counter :persistent "./my-db"} {:count 0})
;; Named persistent atom, default domain (./eve/)
(e/atom {:id ::counter :persistent true} {:count 0})Parameters:
- First arg: either a keyword (shorthand for
{:id kw}), a config map, or omitted (anonymous) - Second arg: initial value (any Clojure value)
Config map keys:
:id— namespace-qualified keyword (e.g.,::counter,:my.app/state). Required for persistent atoms.:persistent—true(default domain at./eve/) or a string path ("./my-db")
Returns: An atom implementing IDeref, IReset, ISwap, IWatchable (SAB), or IDeref, IReset, ISwap (persistent).
All atoms support @, swap!, reset!.
Creates a standalone SharedArrayBuffer-backed AtomDomain with its own memory region.
(def my-domain
(eve/atom-domain {:counter 0 :name "world"}
:sab-size (* 4 1024 1024) ;; 4MB (default: 256MB)
:max-blocks 4096)) ;; max descriptor slots (default: 65536)Standard atom operations work on an AtomDomain:
@my-domain ;; deref
(swap! my-domain update :counter inc) ;; swap
(reset! my-domain {:counter 0}) ;; reset
(add-watch my-domain :log (fn [k r o n] ...)) ;; watch
(remove-watch my-domain :log) ;; unwatchThese are rarely needed — standard Clojure literals ({}, [], #{}, '()) are automatically converted to Eve types when stored in an atom.
(e/hash-map :a 1 :b 2) ;; Eve HAMT map
(e/empty-hash-map) ;; Empty Eve HAMT map
(e/hash-set :a :b :c) ;; Eve hash set
(e/empty-hash-set) ;; Empty Eve hash set(e/aget my-array 0) ;; Read element (atomic for integer types)
(e/aset! my-array 0 42) ;; Write element (atomic for integer types)
(e/get-typed-view my-array) ;; Get raw JS TypedArray view(e/shared-atom? counter) ;; true if SharedAtom;; Extract SAB references for cross-worker transfer
(e/sab-transfer-data my-domain)
;; => {:sab <SharedArrayBuffer> :reader-map-sab <SharedArrayBuffer>}(ns my-app.advanced
(:require [eve.alpha :as eve :include-macros true]))
;; Define a SAB-backed type
(eve/deftype Counter [^:mutable ^:int32 count label]
ICounted
(-count [this] count))
;; Extend protocols on an existing eve/deftype
(eve/extend-type Counter
IMyProtocol
(-my-method [this] ...))Schema-based typed objects backed by SharedArrayBuffer. Two layouts:
eve-obj(AoS — Array of Structures): Single object with named typed fields.eve-obj-array(SoA — Structure of Arrays): Collection of objects stored column-wise.
(require '[eve.obj :as obj])(def node-schema
(obj/create-schema {:key :int32
:left :int32
:right :int32
:value :float64}))Supported field types: :int8, :uint8, :int16, :uint16, :int32, :uint32, :float32, :float64, :obj (offset reference), :array (offset reference).
Integer types (:int32, :uint32) support atomic operations. Fields are sorted by alignment (descending) for optimal memory packing.
;; Create inside atom transaction
(swap! state assoc :tree
(obj/obj node-schema {:key 42 :left -1 :right -1 :value 3.14}))
;; Field access (ILookup, IFn, ISeqable)
(:key node) ;; => 42
(node :key) ;; => 42
(seq node) ;; => ([:key 42] [:value 3.14] ...)
;; Mutation
(obj/assoc! node :key 100)
;; Atomic operations (int32/uint32 fields only)
(obj/cas! node :key 100 200) ;; compare-and-swap, returns true/false
(obj/add! node :key 10) ;; atomic add, returns old value
(obj/sub! node :key 5) ;; atomic subtract, returns old value
(obj/exchange! node :key 999) ;; atomic exchange, returns old value;; Create array of N objects
(swap! state assoc :particles
(obj/obj-array 1000 {:x :int32 :y :int32 :velocity :int32}))
;; Element access
(obj/assoc-in! data [0 :x] 42)
(obj/get-in data [0 :x]) ;; => 42
(nth data 0) ;; row view
;; Column access (SIMD/batch)
(obj/column data :x) ;; raw Int32Array
(obj/column-reduce data :x 0 (fn [acc idx val] (+ acc val)))
(obj/column-map! data :x (fn [idx val] (* val 2)))Typed array storage in SharedArrayBuffer with optional atomic operations.
(require '[eve.array :as arr])(arr/eve-array :int32 10) ;; 10 zero-filled int32 elements
(arr/eve-array :float64 10 0.0) ;; 10 float64 filled with 0.0
(arr/eve-array :uint8 [1 2 3]) ;; from collectionSupported types: :int8, :uint8, :uint8-clamped, :int16, :uint16, :int32, :uint32, :float32, :float64
(arr/aget my-array 0) ;; read (atomic for integer types)
(arr/aset! my-array 0 42) ;; write (atomic for integer types)(arr/cas! my-array idx expected new-val) ;; compare-and-swap
(arr/add! my-array idx delta) ;; atomic add
(arr/sub! my-array idx delta) ;; atomic subtract
(arr/band! my-array idx mask) ;; atomic bitwise AND
(arr/bor! my-array idx mask) ;; atomic bitwise OR
(arr/bxor! my-array idx mask) ;; atomic bitwise XOR(arr/wait! my-array idx expected) ;; block until value changes
(arr/wait! my-array idx expected timeout) ;; with timeout (ms)
(arr/notify! my-array idx) ;; wake one waiting worker
(arr/notify! my-array idx count) ;; wake N waiting workers(arr/get-sab my-array) ;; underlying SharedArrayBuffer
(arr/get-typed-view my-array) ;; raw JS TypedArray view
(arr/array-type my-array) ;; type keyword (:int32, etc.)
(arr/retire! my-array) ;; mark for GCNot atomic — use only with exclusive access:
(arr/afill-simd! my-array 42) ;; fill all elements
(arr/afill-simd! my-array 42 start end) ;; fill range
(arr/acopy-simd! dest src) ;; copy array
(arr/asum-simd my-array) ;; sum all elements
(arr/areduce my-array init-val f) ;; reduce
(arr/amap my-array f) ;; map16-way branching PATRICIA trie with 32-bit integer keys.
(require '[eve.deftype.int-map :as im])(def state (e/atom {:data (im/int-map)}))
;; Standard map operations inside swap!
(swap! state update :data assoc 1 :a)
(swap! state update :data assoc 2 :b)
;; Full 32-bit key range (including negative keys)
(swap! state update :data assoc -10 "cold");; Right-wins merge
(im/merge map-a map-b)
;; Custom conflict resolution
(im/merge-with + counts-a counts-b);; Returns a sub-map with keys in [lo, hi]
(im/range my-int-map 3 7)Okasaki-style persistent red-black tree.
(require '[eve.deftype.rb-tree :as rb])(def state (e/atom {:tags (rb/sorted-set)}))
(swap! state update :tags conj "clojure")
(swap! state update :tags conj "python")
;; With initial elements
(rb/sorted-set 5 3 8 1 4)
;; Membership testing
(rb/member? my-set "clojure") ;; => true
;; Supports any comparable type (strings, keywords, numbers)
(rb/sorted-set :z :a :m :f) ;; iterates as (:a :f :m :z)Define types with fields stored directly in SharedArrayBuffer:
(require '[eve.alpha :as eve :include-macros true])
(eve/deftype Counter [^:mutable ^:int32 count label]
ICounted
(-count [this] count))| Hint | Storage | Notes |
|---|---|---|
^:int32, ^:uint32 |
4-byte SAB slot | Atomic read/write |
^:float32 |
4-byte SAB slot | Non-atomic |
^:float64 |
8-byte SAB slot | Non-atomic |
^:MyEveType |
Offset reference | Links to another eve/deftype |
| (no hint) | Serialized | Any Clojure value, stored via pr-str/cljs.reader |
| Modifier | Behavior |
|---|---|
| (default) | Immutable — set at construction |
^:mutable |
Mutable via set! (single-worker) |
^:volatile-mutable |
Atomic via set!/cas! (cross-worker safe) |
(eve/extend-type Counter
IIncable
(-inc! [this]
(set! count (inc count))
this))Field names from the type's declaration are available as local bindings in method bodies. set! and cas! on declared fields are rewritten to SAB operations.
;; Internal namespace — diagnostic use only
(require '[eve.shared-atom :as a])
(a/validate-storage-model! (.-s-atom-env my-atom) {:width 80 :label "checkpoint"})
(a/xray-replay!)