feltdb 0.3.0

Embedded durable state store: an append-only log with atomic multi-record transactions, version-conditional writes, and idempotent retries
Documentation

feltdb

An embedded, durable state store for Rust. Records live in an append-only log on local disk. Several records can change in one atomic transaction, a write can be conditional on the version you read, and a transaction can carry an identity so that a retry after an uncertain outcome is recognized instead of applied twice.

[dependencies]
feltdb = "0.2"
serde_json = "1"
use feltdb::{FeltDb, FlowError};
use serde_json::json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let db = FeltDb::open("app.db")?;

    // Create only if absent. A second create is refused in a way you can branch on.
    db.insert_if_absent("orders:o-1", json!({ "status": "pending" }))?;
    assert!(matches!(
        db.insert_if_absent("orders:o-1", json!({})),
        Err(FlowError::PreconditionFailed(_))
    ));
    Ok(())
}

The crate documentation on docs.rs has a longer, tested example covering atomic transactions and safe retries.

What you can rely on

  • Acknowledged writes and committed transaction ids survive closing and reopening the database, and a process kill.
  • An interrupted, unacknowledged append is discarded on open and reported; its retry is treated as a first use.
  • A transaction id names one payload. Reusing an id with a different payload hash fails with FlowError::TransactionIdPayloadMismatch and writes nothing.

What is not promised

  • Power-loss durability is unproven. A flush hands bytes to the operating system; it does not force them to stable storage. What survives a power cut depends on the filesystem, mount options and the drive. See the repository's crash durability note.
  • Only the supported API is covered by semver. While the version is 0.x, a breaking change to a supported item is a minor-version bump. Everything behind the unstable-internals feature (fault injection, diagnostics, implementation modules) carries no promise at all; do not enable it in application code. The supported surface is listed in the Rust API contract.
  • Plain insert, update and delete are unconditional: insert replaces, update of a missing key creates it, delete of a missing key succeeds. Use insert_if_absent or compare_and_set_json when you need a guard.

Targets

Built and tested on native targets. wasm32-wasip1 compiles. wasm32-unknown-unknown compiles only if your crate enables getrandom's js feature.

Binaries

The package also builds feltdb-authority, feltdb-authority-client and feltdb_node, the process authority and its client. cargo install feltdb installs them. Most applications want only the library.

Minimum Rust version

1.96, the oldest toolchain the project's CI builds and tests with.

License

MIT. See LICENSE.