alkstore 0.1.0

The alkstore contract crate: one reactive store trait surface — notify, streams, durable queues, TTL locks, outbox, scheduler — implemented by the alkstore-sqlite/-postgres/-mem engine crates; no driver dependencies
Documentation
//! Stream event value (ADR-015 §3).
//!
//! `#[non_exhaustive]` per ADR-017 §3 — consumers read but never
//! construct.

use serde::de::DeserializeOwned;

use crate::payload;

/// A stream event — honker's shape with one rename (`topic` →
/// `stream`, ADR-015 §3).
///
/// `#[non_exhaustive]` (ADR-017 §3). Offsets are positions in the
/// stream's log — immutable, never renumbered; order is global FIFO
/// under publish sequence. The key is carried metadata only: not a
/// partitioning instruction, not a dedup key, not an ordering key.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct StreamEvent {
    /// Position in the stream's log; immutable.
    pub offset: i64,
    /// The stream name.
    pub stream: String,
    /// The carried key; `None` unless published keyed.
    pub key: Option<String>,
    /// Payload bytes — the serde_json serialization of the trait
    /// `Value` at publish time (ADR-020 §4); decode with
    /// [`StreamEvent::payload_as`].
    pub payload: Vec<u8>,
    /// Unix seconds at publish (the engines' single clock source).
    pub created_at: i64,
}

impl StreamEvent {
    /// Engine-construction-only constructor taking the full field set.
    ///
    /// # Contract posture
    ///
    /// Not consumer API and not part of the contract surface: engines
    /// (in-repo, lockstep-updated with core) use it to build
    /// [`StreamEvent`] values from row data, since
    /// `#[non_exhaustive]` (ADR-017 §3) bans struct-literal
    /// construction downstream. Not covered by ADR-017's
    /// semver-minor field-addition promise — a `StreamEvent` field
    /// addition changes this signature, which is an engine breaking
    /// change under a core change and a lockstep-duty event
    /// (ADR-017 §5). Hidden from consumer-facing docs.
    #[doc(hidden)]
    pub fn from_row(
        offset: i64,
        stream: String,
        key: Option<String>,
        payload: Vec<u8>,
        created_at: i64,
    ) -> Self {
        Self {
            offset,
            stream,
            key,
            payload,
            created_at,
        }
    }

    /// Decode the stored payload bytes into a concrete target type.
    ///
    /// The stored bytes are the serde_json serialization of the
    /// publish-time `Value` (ADR-020 §4); any deserialization failure
    /// is [`Error::Codec`](crate::Error::Codec).
    pub fn payload_as<T: DeserializeOwned>(&self) -> crate::Result<T> {
        payload::payload_as(&self.payload)
    }
}