Expand description
SalamanderDB — an embedded event-sourcing engine with instant recovery.
The append-only log is the only durable structure; everything else is a rebuildable projection. Losing a catalog, index, projection, snapshot, or sidecar may change performance, but never answers.
The engine is generic over its payload type: Salamander<B> frames,
orders, and persists bodies of any Body type but never interprets
them (P1 — “general engine underneath, agent memory as a labeled
beachhead”). The agent vocabulary — agent::EventBody,
agent::SessionProjection, session_view, fork — is a provided
module over that engine, in agent. Agent users open an
AgentDb and never see the type parameter.
The crate also provides named streams, atomic batches, optimistic concurrency, idempotent retries, branches, streaming replay, verified snapshots, and a committed-batch feed. See the repository README and roadmap for guides, operational boundaries, and planned work.
§Custom payloads
Any serde-serializable, Clone, 'static type is a valid payload —
the agent vocabulary is just one choice. Define your own events and
project them however you like:
use salamander::{Event, Salamander};
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize)]
enum Metric {
Cpu(f64),
Mem(u64),
}
let dir = tempfile::tempdir().unwrap();
let mut db: Salamander<Metric> = Salamander::open(dir.path())?;
db.append("host-1", Metric::Cpu(0.7))?;
db.append("host-1", Metric::Mem(2048))?;
db.commit()?;
drop(db); // release the single-writer lock before reopening
// Reopen from disk and read the custom payloads straight back out.
let db: Salamander<Metric> = Salamander::open(dir.path())?;
let mut count = 0;
db.replay("host-1", 0..db.head(), |_e: &Event<Metric>| count += 1)?;
assert_eq!(count, 2);Re-exports§
pub use view::Change;pub use view::IndexKey;pub use view::IndexedView;pub use view::View;pub use agent::AgentDb;pub use json::Json;pub use json::JsonDb;
Modules§
- agent
- The agent-memory vocabulary — SalamanderDB’s labeled beachhead (P1).
- json
- WP-5 seam — the dynamic-JSON payload surface the Python bindings bind to.
- view
- docs/phase-1.5.md §3 — the query layer.
Structs§
- Append
Receipt - The result of a successful append: the assigned positions, resulting stream revision, and the durability that was achieved.
- Append
Request - One append command: a batch of events for a single stream, appended atomically (all-or-nothing) under an optimistic-concurrency expectation and a durability level.
- BatchId
- Bincode
Codec - Branch
Id - Branch
Info - Durable identity and immutable ancestry for one branch.
- Branch
Migration Report - Outcome of a legacy-fork-marker conversion, returned by
migrate_legacy_branches. - Branch
Name - Validated, stable human-readable branch label.
- CodecId
- Commit
Policy - When
crate::Salamander::appendshould trigger an automaticcommit()on the caller’s behalf. - Database
Id - Diff
Request - What to diff: two timelines, each a branch bounded by an exclusive
until, plus a stream selector scoped onto the emitted plans. See
Salamander::diff. - Diff
Side - One side of a
TimelineDiff: the branch, its resolved until, and the replay plan for its divergent suffix[divergence, until). - Event
- One durable, offset-ordered fact carrying a payload of type
B. - EventId
- Event
Type - Format
Limits - Idempotency
Key - A caller-supplied key identifying an append command, scoped to a
database and branch, so that a retry with identical content is
idempotent (non-empty, at most
IdempotencyKey::MAX_BYTES). - Json
Codec - LogReader
- The concrete bounded-memory reader over one log.
- Migration
Report - Outcome of a v1-to-v2 import, returned by
migrate_v1. - NewEvent
- One event to be appended, carrying a typed payload
B. - Owned
Stored Record - Record
Envelope V2 - Replay
Plan - A declarative replay request (spec/04). Resolved against the log and
branch catalog by
Salamander::read. - Salamander
- The embedded event-sourcing engine, generic over its payload type
B. - Stored
Record - Stream
Id - Stream
Name - The user-facing name of a stream within a branch (UTF-8, non-empty, no
NUL bytes, at most
StreamName::MAX_BYTES). The engine maps it to a stable compactStreamIdinternally. - Stream
Revision - Timeline
Diff - The result of
Salamander::diff: where two timelines share history and what each says after that — a position plus three replay plans. Both timelines replay identically belowdivergenceby construction; no record comparison is involved (DIFF-1, DIFF-6).
Enums§
- Branch
Status - Whether a branch accepts new writes.
- Durability
- The durability level requested for an append. A stronger level includes the guarantees of the weaker ones; see the crate’s durability contract for the per-platform survival matrix.
- Expected
Revision - Optimistic-concurrency expectation checked against a stream’s current revision, in the same critical section that assigns positions. A failed expectation appends nothing.
- Frame
Kind - Receipt
Durability - The durability actually achieved for an append, as reported on the
AppendReceipt. The receipt states this rather than leaving the caller to infer it from the method used. - Replay
End - Where a replay stops (exclusive), resolved against the log head when the reader is constructed.
- Salamander
Error - The error type returned by every fallible operation in this crate.
- Stream
Selector - Which streams a plan selects. Evaluated per record from the envelope’s
StreamId— never from the stream catalog — so streams created after any derived state was built still route correctly. - Verification
Mode - How much re-verification the reader performs beyond per-frame CRCs.
Constants§
- DEFAULT_
BRANCH_ NAME - Name of the default branch every database has.
- MAX_
LINEAGE_ DEPTH - Maximum number of branch nodes accepted in one ancestry chain.
Traits§
- Body
- The bound set every payload type must satisfy, aliased under one name so
the engine’s generic signatures stay legible (
B: Bodyrather than the four-trait mouthful everywhere). - Namespace
Scoped - Projections that need to know their namespace before any events are
applied (DESIGN.md §2) — e.g.
SessionProjectionfilters to one namespace, so it can’t be built via plainDefaultthe wayKvProjectioncan. - Projection
- A deterministic fold of the log into derived state. Rebuild, time-travel, and fork are all the same fold stopped at a different point (INV-1).
- Record
Reader - The object-safe pull interface over any record reader.
nextlends a record borrowing the reader’s internal buffer; callers that need to hold records across calls usenext_owned. - Typed
Codec
Functions§
- migrate_
legacy_ branches - Rewrite a pre-WP-03 v2 database into a new database whose fork lineage is represented exclusively by engine-owned branch metadata.
- migrate_
v1 - Imports a v1 database directory into a fresh v2 directory offline.
Type Aliases§
- Metadata
- Result
- Shorthand for a
Resultwhose error isSalamanderError.