pub struct Salamander<B> { /* private fields */ }Expand description
The embedded event-sourcing engine, generic over its payload type B.
Frames, orders, and persists events of any Body type without
interpreting them; derived state is produced by Projections and
live Views folded from the log. See
AgentDb and JsonDb for ready-made
payload vocabularies.
Implementations§
Source§impl Salamander<EventBody>
Agent-vocabulary operations. These are inherent methods on the engine
specialized to EventBody, so they are only in scope for an
AgentDb — a Salamander<MyOwnPayload> never sees fork or
session_view, which is exactly the P1 boundary made real in the type
system.
impl Salamander<EventBody>
Agent-vocabulary operations. These are inherent methods on the engine
specialized to EventBody, so they are only in scope for an
AgentDb — a Salamander<MyOwnPayload> never sees fork or
session_view, which is exactly the P1 boundary made real in the type
system.
Sourcepub fn session_view(&self, namespace: &str) -> Result<SessionProjection>
pub fn session_view(&self, namespace: &str) -> Result<SessionProjection>
A SessionProjection for namespace on the default branch.
Sourcepub fn session_view_on_branch(
&self,
branch: BranchId,
namespace: &str,
) -> Result<SessionProjection>
pub fn session_view_on_branch( &self, branch: BranchId, namespace: &str, ) -> Result<SessionProjection>
A SessionProjection for namespace on a specific branch.
Source§impl<B: Body> Salamander<B>
impl<B: Body> Salamander<B>
Sourcepub fn open(dir: impl AsRef<Path>) -> Result<Self>
pub fn open(dir: impl AsRef<Path>) -> Result<Self>
Opens instantly in Phase 2; Phase 1 replays fully and measures it
(DESIGN.md §7). Phase 1 doesn’t cache any projection state on
Salamander itself — every accessor below rebuilds from the log on
demand (“no snapshot cleverness,” IMPLEMENTATION.md Step 5), so
there’s nothing to warm up here beyond recovering the log itself.
Registered views (query layer) start empty and are caught up on
register. Opens with the default Manual commit policy — the
caller drives durability; see open_with_policy.
Sourcepub fn open_with_policy(
dir: impl AsRef<Path>,
policy: CommitPolicy,
) -> Result<Self>
pub fn open_with_policy( dir: impl AsRef<Path>, policy: CommitPolicy, ) -> Result<Self>
Like open, but with a group-commit policy active from
the start (WP-4). The policy can also be changed later with
set_commit_policy.
Sourcepub fn set_commit_policy(&mut self, policy: CommitPolicy)
pub fn set_commit_policy(&mut self, policy: CommitPolicy)
Replace the group-commit policy. Takes effect on the next append; the uncommitted counters carry over unchanged (a smaller threshold may therefore fire on the very next append).
Sourcepub fn commit_policy(&self) -> CommitPolicy
pub fn commit_policy(&self) -> CommitPolicy
The active group-commit policy.
Sourcepub fn append(&mut self, namespace: &str, body: B) -> Result<u64>
pub fn append(&mut self, namespace: &str, body: B) -> Result<u64>
Appends a single body to namespace on the default branch and
returns its position. A convenience wrapper over
append_batch with buffered durability.
Sourcepub fn append_on_branch(
&mut self,
branch: BranchId,
namespace: &str,
body: B,
) -> Result<u64>
pub fn append_on_branch( &mut self, branch: BranchId, namespace: &str, body: B, ) -> Result<u64>
Like append, but targets a specific branch.
Sourcepub fn append_batch(
&mut self,
request: AppendRequest<B>,
) -> Result<AppendReceipt>
pub fn append_batch( &mut self, request: AppendRequest<B>, ) -> Result<AppendReceipt>
Appends a batch of events atomically, validating the
optimistic-concurrency expectation and idempotency key in the
writer-critical section, and returns the AppendReceipt.
Sourcepub fn branch(&self, id: BranchId) -> Option<&BranchInfo>
pub fn branch(&self, id: BranchId) -> Option<&BranchInfo>
Metadata for the branch with id, or None if it does not exist.
Sourcepub fn branch_named(&self, name: &str) -> Option<&BranchInfo>
pub fn branch_named(&self, name: &str) -> Option<&BranchInfo>
Metadata for the branch with the given name, or None.
Sourcepub fn branch_ancestry(&self, id: BranchId) -> Result<Vec<BranchInfo>>
pub fn branch_ancestry(&self, id: BranchId) -> Result<Vec<BranchInfo>>
The branch’s ancestry, root first, ending with id.
Sourcepub fn branch_children(&self, id: BranchId) -> Vec<BranchInfo>
pub fn branch_children(&self, id: BranchId) -> Vec<BranchInfo>
The direct child branches of id.
Sourcepub fn branch_common_ancestor(
&self,
left: BranchId,
right: BranchId,
) -> Result<BranchInfo>
pub fn branch_common_ancestor( &self, left: BranchId, right: BranchId, ) -> Result<BranchInfo>
The nearest common ancestor of two branches.
Sourcepub fn diff(&self, request: DiffRequest) -> Result<TimelineDiff>
pub fn diff(&self, request: DiffRequest) -> Result<TimelineDiff>
The divergence of two timelines as an engine operation — a
position plus three replay plans, computed from the branch catalog
alone (docs/specs/first-class-diff.md). No record is read or
compared: two timelines are identical below the divergence position
by construction, because inherited replay is positional (DIFF-1).
Feed the returned plans to read to enumerate the
shared prefix or either divergent suffix; computing the diff itself
performs no log I/O and writes nothing (DIFF-5).
Sourcepub fn read(&self, plan: ReplayPlan) -> Result<LogReader<'_>>
pub fn read(&self, plan: ReplayPlan) -> Result<LogReader<'_>>
Build a bounded-memory streaming reader for plan (WP-04). The
plan’s branch is resolved to its flattened ancestry scopes, so
inherited parent history is visible through the fork point; every
other selection (streams, position window, time, max events) is
applied by the reader from envelope data alone.
Sourcepub fn replay_branch(
&self,
branch: BranchId,
namespace: &str,
range: Range<u64>,
f: impl FnMut(&Event<B>),
) -> Result<()>
pub fn replay_branch( &self, branch: BranchId, namespace: &str, range: Range<u64>, f: impl FnMut(&Event<B>), ) -> Result<()>
Replays the events of namespace visible on branch within
range, in order, invoking f on each — inherited parent history
is included through the fork point.
Sourcepub fn fork_branch(
&mut self,
parent: BranchId,
at: u64,
name: BranchName,
metadata: Metadata,
) -> Result<BranchInfo>
pub fn fork_branch( &mut self, parent: BranchId, at: u64, name: BranchName, metadata: Metadata, ) -> Result<BranchInfo>
Creates a branch forked from parent at position at, which must
be a committed batch boundary visible in the parent. The child
inherits parent history up to at and then diverges; the parent is
unaffected.
Sourcepub fn archive_branch(&mut self, id: BranchId) -> Result<BranchInfo>
pub fn archive_branch(&mut self, id: BranchId) -> Result<BranchInfo>
Archives a branch: it keeps its readable history but rejects new writes. The default branch cannot be archived.
Sourcepub fn commit(&mut self) -> Result<u64>
pub fn commit(&mut self) -> Result<u64>
fsync the log and return the durable head (DESIGN.md §3.3). Always available regardless of the commit policy; resets the group-commit counters so the next auto-commit measures from here.
Sourcepub fn uncommitted_bytes(&self) -> u64
pub fn uncommitted_bytes(&self) -> u64
Payload bytes appended but not yet committed (fsynced). Reset to 0 by
commit() and by any auto-commit the policy triggers.
Sourcepub fn uncommitted_count(&self) -> u64
pub fn uncommitted_count(&self) -> u64
Events appended but not yet committed (fsynced).
Sourcepub fn projection<P: Projection<Body = B> + Default>(&self) -> Result<P>
pub fn projection<P: Projection<Body = B> + Default>(&self) -> Result<P>
Full rebuild: a fresh P, replayed to head(). The projection’s
Body must match this engine’s payload type B — you can’t fold a
log of one payload type with a projection written for another.
Sourcepub fn projection_for<P: NamespaceScoped<Body = B>>(
&self,
namespace: &str,
) -> Result<P>
pub fn projection_for<P: NamespaceScoped<Body = B>>( &self, namespace: &str, ) -> Result<P>
Full rebuild of a namespace-scoped projection, replayed to
head(). This is the plain, non-stitched view: for the agent
SessionProjection specifically, prefer crate::agent’s
session_view if namespace might be a fork (see its doc comment
for why).
Sourcepub fn view_at<P: Projection<Body = B> + Default>(&self, n: u64) -> Result<P>
pub fn view_at<P: Projection<Body = B> + Default>(&self, n: u64) -> Result<P>
Read-only projection as of offset n (DESIGN.md §5, time-travel).
For views that can’t be Default-constructed (e.g. IndexedView,
which owns closures), use replay_to instead.
Sourcepub fn register(&mut self, name: &str, view: Box<dyn View<B>>) -> Result<()>
pub fn register(&mut self, name: &str, view: Box<dyn View<B>>) -> Result<()>
Register a live view under name, catching it up from its cursor to
head before it starts receiving fan-out (so it’s immediately at
head, INV-2). Re-registering a name replaces the previous view.
Sourcepub fn deregister(&mut self, name: &str) -> Option<Box<dyn View<B>>>
pub fn deregister(&mut self, name: &str) -> Option<Box<dyn View<B>>>
Remove and return a registered view (query-layer design OQ-Q2 — a
long-lived host must be able to reclaim view memory). None if no
view is registered under name.
Sourcepub fn view<T: View<B>>(&self, name: &str) -> Option<&T>
pub fn view<T: View<B>>(&self, name: &str) -> Option<&T>
Typed, read-only access to a registered view: downcast the erased
dyn View<B> back to the concrete T the query methods live on.
None if name isn’t registered or the type doesn’t match.
The borrow checker enforces the one correctness rule for free: this
takes &self, append takes &mut self, so a query reference can
never be held across an append — you can’t query a half-updated view.
Sourcepub fn replay_to<P: Projection<Body = B>>(&self, view: P, n: u64) -> Result<P>
pub fn replay_to<P: Projection<Body = B>>(&self, view: P, n: u64) -> Result<P>
Time-travel for a caller-constructed view: hand in a fresh, empty
view/projection and get it back replayed to offset n. This is the
historical counterpart to register (which replays to head) and the
path for non-Default views like IndexedView (query-layer design
§4.3 — “one view type, two modes”).
Sourcepub fn durable_head(&self) -> u64
pub fn durable_head(&self) -> u64
Exclusive upper position proven durable by the latest successful sync.