Skip to main content

Crate salamander

Crate salamander 

Source
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§

AppendReceipt
The result of a successful append: the assigned positions, resulting stream revision, and the durability that was achieved.
AppendRequest
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
BincodeCodec
BranchId
BranchInfo
Durable identity and immutable ancestry for one branch.
BranchMigrationReport
Outcome of a legacy-fork-marker conversion, returned by migrate_legacy_branches.
BranchName
Validated, stable human-readable branch label.
CodecId
CommitPolicy
When crate::Salamander::append should trigger an automatic commit() on the caller’s behalf.
DatabaseId
DiffRequest
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.
DiffSide
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
EventType
FormatLimits
IdempotencyKey
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).
JsonCodec
LogReader
The concrete bounded-memory reader over one log.
MigrationReport
Outcome of a v1-to-v2 import, returned by migrate_v1.
NewEvent
One event to be appended, carrying a typed payload B.
OwnedStoredRecord
RecordEnvelopeV2
ReplayPlan
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.
StoredRecord
StreamId
StreamName
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 compact StreamId internally.
StreamRevision
TimelineDiff
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 below divergence by construction; no record comparison is involved (DIFF-1, DIFF-6).

Enums§

BranchStatus
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.
ExpectedRevision
Optimistic-concurrency expectation checked against a stream’s current revision, in the same critical section that assigns positions. A failed expectation appends nothing.
FrameKind
ReceiptDurability
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.
ReplayEnd
Where a replay stops (exclusive), resolved against the log head when the reader is constructed.
SalamanderError
The error type returned by every fallible operation in this crate.
StreamSelector
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.
VerificationMode
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: Body rather than the four-trait mouthful everywhere).
NamespaceScoped
Projections that need to know their namespace before any events are applied (DESIGN.md §2) — e.g. SessionProjection filters to one namespace, so it can’t be built via plain Default the way KvProjection can.
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).
RecordReader
The object-safe pull interface over any record reader. next lends a record borrowing the reader’s internal buffer; callers that need to hold records across calls use next_owned.
TypedCodec

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 Result whose error is SalamanderError.