User Guide
Welcome to the Eidetica User Guide. This guide will help you understand and use Eidetica effectively in your applications.
What is Eidetica?
Eidetica is a Rust library for managing structured data with built-in history tracking. It combines concepts from distributed systems, Merkle-CRDTs, and traditional databases to provide a unique approach to data management:
- Efficient data storage with customizable Databases
- History tracking for all changes via immutable Entries forming a DAG
- Structured data types via named, typed Stores within logical Databases
- Atomic changes across multiple data structures using Transactions
- Designed for distribution (future capability)
How to Use This Guide
This user guide is structured to guide you from basic setup to advanced concepts:
- Getting Started: Installation, basic setup, and your first steps.
- Basic Usage Pattern: A quick look at the typical workflow.
- Core Concepts: Understand the fundamental building blocks:
- Entries & Databases: The core DAG structure.
- Databases: How data is stored.
- Stores: Where structured data lives (
DocStore
,Table
,YDoc
). - Transactions: How atomic changes are made.
- Tutorial: Todo App: A step-by-step walkthrough using a simple application.
- Code Examples: Focused code snippets for common tasks.
Quick Overview: The Core Flow
Eidetica revolves around a few key components working together:
Database
: You start by choosing or creating a storageDatabase
(e.g.,InMemoryDatabase
).Instance
: You create aInstance
instance, providing it theDatabase
. This is your main database handle.Database
: Using theInstance
, you create or load aDatabase
, which acts as a logical container for related data and tracks its history.Transaction
: To read or write data, you start aTransaction
from theDatabase
. This ensures atomicity and consistent views.Store
: Within aTransaction
, you get handles to namedStore
s (likeDocStore
orTable<YourData>
). These provide methods (set
,get
,insert
,remove
, etc.) to interact with your structured data.Commit
: Changes made viaStore
handles within theTransaction
are staged. Callingcommit()
on theTransaction
finalizes these changes atomically, creating a new historicalEntry
in theDatabase
.
Basic Usage Pattern
Here's a quick examplee showing loading a database and writing new data.
extern crate eidetica; extern crate serde; use eidetica::{backend::database::InMemory, Instance, crdt::Doc, store::{DocStore, Table}}; use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize, Clone, Debug)] struct MyData { name: String, } fn main() -> eidetica::Result<()> { let backend = InMemory::new(); let db = Instance::new(Box::new(backend)); db.add_private_key("my_private_key")?; // Create/Load Database let database = match db.find_database("my_database") { Ok(mut databases) => databases.pop().unwrap(), // Found existing Err(e) if e.is_not_found() => { let mut doc = Doc::new(); doc.set_string("name", "my_database"); db.new_database(doc, "my_private_key")? } Err(e) => return Err(e), }; // --- Writing Data --- // Start a Transaction let txn = database.new_transaction()?; let inserted_id = { // Scope for store handles // Get Store handles let config = txn.get_store::<DocStore>("config")?; let items = txn.get_store::<Table<MyData>>("items")?; // Use Store methods config.set("version", "1.0")?; items.insert(MyData { name: "example".to_string() })? }; // Handles drop, changes are staged in txn // Commit changes let new_entry_id = txn.commit()?; println!("Committed changes, new entry ID: {}", new_entry_id); // --- Reading Data --- // Use Database::get_store_viewer for a read-only view let items_viewer = database.get_store_viewer::<Table<MyData>>("items")?; if let Ok(item) = items_viewer.get(&inserted_id) { println!("Read item: {:?}", item); } Ok(()) }
See Transactions and Code Examples for more details.
Project Status
Eidetica is currently under active development. The core functionality is working, but APIs are considered experimental and may change in future releases. It is suitable for evaluation and prototyping, but not yet recommended for production systems requiring long-term API stability.