Vault
The shared database abstraction layer underneath Karango (ArangoDB) and Monko (MongoDB).
Why it matters
Switch between ArangoDB and MongoDB without rewriting your domain model. Your entities, queries, and repository patterns stay the same. Vault gives you a single set of abstractions so that choosing or changing a database backend is a wiring decision, not a rewrite.
What Vault provides
Every persistence layer needs the same building blocks: entity wrappers with metadata, lazy references, cursor-based result iteration, a repository interface with hooks, and an entity cache for deduplication. Rather than duplicating these across Karango and Monko, Vault defines them once.
Your data classes stay clean. Database metadata (_id, _key, _rev)
lives in the wrapper, not in your domain model:
// Your data — no database concerns
@Vault
data class Person(val name: String, val age: Int)
// After inserting into either ArangoDB or MongoDB:
val stored: Stored<Person> = repo.insert(Person("Alice", 30))
stored() // Person(name="Alice", age=30) — your data
stored._id // "persons/abc123" — database ID
stored._key // "abc123" — document key The Storable hierarchy
Three wrapper types represent different entity lifecycle stages:
New<T>— an entity before it has been persistedStored<T>— an entity loaded from or saved to the database, carrying full metadataRef<T>— a lazy reference to another entity, resolved on demand viasuspend resolve()
All three share a common base (Storable<T>) with uniform access via
suspend resolve() and suspend invoke().
For Stored and New, resolution is instant.
For Ref, it may suspend to load from the database.
What You Get
Entity Wrappers
Storable, Stored, New, and Ref — your data stays clean while database metadata lives in the wrapper.
Flow Cursors
Cursor<T> wraps Kotlin Flow with 29 suspend convenience extensions that mirror stdlib collections.
Lazy References
Ref<T> resolves on first access, with thread-safe caching. Eager and lazy construction supported.
Suspend-First
All repository and cursor operations are suspend functions. No blocking calls, no callbacks.
Dual-Backend
Same types and interfaces for ArangoDB (Karango) and MongoDB (Monko). Switch backends without rewriting domain code.
Type-Safe
Generic wrappers preserve your domain types end-to-end. Safe downcasting via castTyped and castUntyped.