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
//! Opts structs (ADR-008 §1, ADR-010 §3/§3a, ADR-020 §1–§3).
//!
//! Pinned v1 field sets, carried whole. Deliberately *not*
//! `#[non_exhaustive]` (ADR-017 §3): consumers construct these — an
//! opts *field* addition post-release is a class 3 breaking change,
//! priced that way deliberately.
//!
//! Field semantics (delay-over-`run_at` precedence, relative `expires`)
//! are engine-side resolution (ADR-020 §1–§2) — core carries only the
//! fields and their doc text.

/// Options for enqueueing a job (`Queue::enqueue`, `enqueue_tx`,
/// `outbox_enqueue_tx`).
///
/// Every field has a default-resolved meaning, so all are
/// constructor-settable with `..Default::default()` (`Default` gives
/// all-`None` and priority 0).
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct EnqueueOpts {
    /// Relative delay in seconds from the enqueue instant.
    ///
    /// When set, the row's ready time resolves to `now + delay` —
    /// **wins over `run_at`** if both are supplied (ADR-020 §1;
    /// precedence is defined, not rejected). `None` leaves the
    /// resolution to `run_at`, or to "now" when both are unset.
    pub delay: Option<i64>,
    /// Absolute ready time (unix seconds).
    ///
    /// The absolute-time counterpart of `delay`: used literally when
    /// set and `delay` is not (ADR-020 §1). `get_job` shows the
    /// resolved ready time, never the raw fields.
    pub run_at: Option<i64>,
    /// The claim-order key (priority DESC). Default 0.
    pub priority: i64,
    /// Per-job override of the queue-level max-attempts stamp.
    ///
    /// `None` = the queue-level stamp decides (ADR-010 §3a).
    pub max_attempts: Option<i64>,
    /// Relative job-level expiry: seconds from the enqueue instant.
    ///
    /// Resolved to an absolute row `expires_at` at enqueue (ADR-020
    /// §2); `None` = never expires.
    pub expires: Option<i64>,
}

/// Queue-level option stamps (ADR-010 §3/§3a).
///
/// Queues are names, not registered objects: these stamps resolve and
/// attach to every job row at enqueue — claims, heartbeats, retries,
/// and sweeps read the job's own stamps, never a live registry.
/// Opts changes apply to *future enqueues only*.
///
/// The numeric fields are trusted as given, engine-side — no domain
/// validation: ADR-023 §2's domain table enumerates its covered
/// arguments by call-site kind (extents, `try_lock`/`renew` TTLs,
/// `trim_to`'s horizon, enqueue `delay`/`run_at`/`expires`) and does
/// not cover these queue-stamp fields (a consumer-obligation note,
/// not a defect). A non-positive
/// `visibility_timeout_s` stamps claims instantly reclaimable, and
/// `max_attempts <= 0` stamps rows that are never claimed — see
/// deployment.md's consumer-obligation notes for the per-field
/// symptoms.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct QueueOpts {
    /// Claim visibility timeout in seconds — the default claim
    /// deadline stamped onto rows. Default 300.
    pub visibility_timeout_s: i64,
    /// Default max attempts before dead-letter; overridden per-job by
    /// `EnqueueOpts::max_attempts` when set. Default 3.
    pub max_attempts: i64,
    /// Base seconds for the retry backoff curve. Default 5.
    pub backoff_base_s: i64,
    /// Dead-letter retention in seconds; `None` = dead rows live
    /// forever (the default). Default `None`.
    pub dead_letter_retention_s: Option<i64>,
}

impl Default for QueueOpts {
    /// The pinned defaults (ADR-010 §3): 300 / 3 / 5 / none.
    fn default() -> Self {
        QueueOpts {
            visibility_timeout_s: 300,
            max_attempts: 3,
            backoff_base_s: 5,
            dead_letter_retention_s: None,
        }
    }
}

/// Options for `schedule()` — types identical to their `EnqueueOpts`
/// twins (no delay/run-at fields: boundary fires are ready at fire
/// time, ADR-009 §3).
///
/// Applied over the target queue's derived engine defaults at each
/// boundary fire (ADR-020 §3).
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct ScheduleOpts {
    /// The claim-order key for fired jobs; default 0.
    pub priority: i64,
    /// Per-schedule override of the queue-level max-attempts stamp;
    /// `None` = the default stamp decides.
    pub max_attempts: Option<i64>,
    /// Relative job-level expiry in seconds from the fire instant
    /// (ADR-020 §2); `None` = never expires.
    pub expires: Option<i64>,
}