Skip to main content

stateset_sdk/
lib.rs

1#![deny(unsafe_code)]
2#![cfg_attr(not(test), deny(clippy::unwrap_used))]
3#![cfg_attr(not(test), warn(unused_crate_dependencies))]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5#![doc(
6    html_logo_url = "https://raw.githubusercontent.com/stateset/stateset-icommerce/main/assets/stateset.png",
7    html_favicon_url = "https://raw.githubusercontent.com/stateset/stateset-icommerce/main/assets/favicon.ico",
8    issue_tracker_base_url = "https://github.com/stateset/stateset-icommerce/issues/"
9)]
10
11//! # StateSet SDK
12//!
13//! Rust-facing facade for the StateSet iCommerce platform.
14//!
15//! This crate provides a curated set of feature-gated re-exports for Rust
16//! consumers who want a single dependency for the core commerce engine and
17//! optional sync, crypto, policy, and macro surfaces.
18//!
19//! ## Quick Start
20//!
21//! ```toml
22//! [dependencies]
23//! stateset-sdk = "1.23.4"
24//! ```
25//!
26//! ```rust,ignore
27//! use stateset_sdk::prelude::*;
28//!
29//! let commerce = Commerce::new("store.db")?;
30//! let customer = commerce.customers().create(CreateCustomer {
31//!     email: "alice@example.com".into(),
32//!     first_name: "Alice".into(),
33//!     last_name: "Smith".into(),
34//!     ..Default::default()
35//! })?;
36//! ```
37//!
38//! ## Features
39//!
40//! | Feature | Description | Default |
41//! |---------|-------------|---------|
42//! | `core` | Primitives + Core + DB + Embedded + Observability | Yes |
43//! | `crypto` | VES v1.0 cryptographic operations | No |
44//! | `policy` | Declarative policy engine | No |
45//! | `macros` | Proc macros (`StateSetId`, `GenerateDto`, `JsonSchema`) | No |
46//! | `sync` | Outbox-driven sync engine and sequencer transport facade | No |
47//! | `full` | All features enabled | No |
48//!
49//! With `sync` enabled, [`SyncRuntime`] and [`SyncRuntimeConfig`] bundle the
50//! sync engine, sequencer HTTP transport, and runtime auth/options into a
51//! single Rust-facing helper surface for config loading, sync operations,
52//! JSON-ready runtime snapshots, kernel receipt queries, and local
53//! confirmation/dead-letter inspection. [`SyncRuntimeConfig`] can also load
54//! from JSON or environment variables via `from_file`, `from_json_str`, and
55//! `from_env`.
56
57// ── Core (always available) ──────────────────────────────────────────
58
59/// Primitive types: Money, `CurrencyCode`, Sku, typed IDs.
60#[cfg(feature = "core")]
61pub use stateset_primitives as primitives;
62
63/// Domain models, errors, events, validation, and repository traits.
64#[cfg(feature = "core")]
65pub use stateset_core as core;
66
67/// Database abstraction layer (SQLite, PostgreSQL).
68#[cfg(feature = "core")]
69pub use stateset_db as db;
70
71/// High-level Commerce API wrapping core + db.
72#[cfg(feature = "core")]
73pub use stateset_embedded as embedded;
74
75/// Metrics and observability.
76#[cfg(feature = "core")]
77pub use stateset_observability as observability;
78
79// ── Feature-gated re-exports ─────────────────────────────────────────
80
81/// VES v1.0 cryptographic operations (JCS, hashing, signing, encryption, Merkle trees).
82#[cfg(feature = "crypto")]
83pub use stateset_crypto as crypto;
84
85/// Declarative policy engine with deny-overrides and explainable denials.
86#[cfg(feature = "policy")]
87pub use stateset_policy as policy;
88
89/// Procedural macros: `#[derive(StateSetId)]`, `#[derive(GenerateDto)]`, `#[derive(JsonSchema)]`.
90#[cfg(feature = "macros")]
91pub use stateset_macros as macros;
92
93/// Outbox-driven sync engine, transport abstraction, and sequencer HTTP client.
94#[cfg(feature = "sync")]
95pub use stateset_sync as sync;
96
97#[cfg(feature = "sync")]
98pub mod sync_runtime;
99
100#[cfg(feature = "sync")]
101pub use sync_runtime::{SyncRuntime, SyncRuntimeAuth, SyncRuntimeConfig, SyncRuntimeSnapshot};
102
103// ── Prelude ──────────────────────────────────────────────────────────
104
105/// Commonly used types, re-exported for convenience.
106///
107/// ```rust,ignore
108/// use stateset_sdk::prelude::*;
109/// ```
110#[cfg(feature = "core")]
111pub mod prelude {
112    // Commerce API
113    pub use stateset_embedded::Commerce;
114
115    // Primitive types
116    pub use stateset_primitives::{CurrencyCode, Money, Sku};
117
118    // Typed IDs
119    pub use stateset_core::{
120        CustomerId, FulfillmentId, OrderId, OrderItemId, PaymentId, ProductId, ReturnId, ShipmentId,
121    };
122
123    // Common models
124    pub use stateset_core::{
125        // Cart
126        AddCartItem,
127        // Address
128        Address,
129        // Inventory
130        AdjustInventory,
131        Cart,
132        CreateCart,
133        // Customer
134        CreateCustomer,
135        CreateInventoryItem,
136        // Order
137        CreateOrder,
138        CreateOrderItem,
139        // Payment
140        CreatePayment,
141        // Product
142        CreateProduct,
143        // Return
144        CreateReturn,
145        // Shipment
146        CreateShipment,
147        Customer,
148        CustomerFilter,
149        CustomerStatus,
150        InventoryItem,
151        Order,
152        OrderFilter,
153        OrderItem,
154        OrderStatus,
155        Payment,
156        PaymentFilter,
157        PaymentStatus,
158        Product,
159        ProductFilter,
160        ProductStatus,
161        Return,
162        ReturnFilter,
163        ReturnStatus,
164        Shipment,
165    };
166
167    // Events
168    pub use stateset_core::CommerceEvent;
169
170    // Errors and Result
171    pub use stateset_core::{CommerceError, Result};
172
173    // Database
174    pub use stateset_db::Database;
175
176    // Observability
177    pub use stateset_observability::{Metrics, MetricsConfig};
178
179    // Sync
180    #[cfg(feature = "sync")]
181    pub use crate::{SyncRuntime, SyncRuntimeAuth, SyncRuntimeConfig, SyncRuntimeSnapshot};
182
183    #[cfg(feature = "sync")]
184    pub use stateset_sync::{
185        AttestationError, BudgetAuthorization, BudgetCheckpoint, CommandAttestation,
186        CommandConvergence, CommandInclusionProof, CommitmentManifest, CommitmentTrustPolicy,
187        CounterpartyCommitment, CounterpartyConvergenceStatus, DeadLetter, KernelExecutionError,
188        KernelMetadata, KernelReceipt, KernelReceiptStatus, KernelTransaction,
189        ManifestVerificationError, PolicyCheckpoint, PolicyDecision, PullResult, PushConfirmation,
190        PushResult, RemoteHead, SequenceAuthority, SequencerHttpTransport, SignerTrustMode,
191        SyncConfig, SyncEngine, SyncError, SyncEvent, SyncStatus, VerifiedCommitmentManifest,
192        compute_commitment_manifest_hash, sign_commitment_manifest, verify_commitment_manifest,
193        verify_commitment_manifest_against_state,
194    };
195}
196
197#[cfg(test)]
198mod tests {
199    use super::*;
200
201    #[cfg(feature = "core")]
202    #[test]
203    fn prelude_imports_compile() {
204        // Verify key types are accessible through the prelude
205        use crate::prelude::*;
206        let _: Money = Money::zero(CurrencyCode::USD);
207        let _: OrderId = OrderId::new();
208
209        #[cfg(feature = "sync")]
210        {
211            let _: SyncConfig = SyncConfig::new("agent-1", "tenant-1", "store-1");
212            let _: SequenceAuthority = SequenceAuthority::LocalOutbox;
213            let runtime = SyncRuntimeConfig::new(
214                "https://sequencer.stateset.com",
215                SyncConfig::new("agent-1", "tenant-1", "store-1"),
216            )
217            .with_agent_key_id(5)
218            .build()
219            .unwrap();
220            let _: SyncRuntimeSnapshot = runtime.snapshot();
221            assert_eq!(runtime.transport().agent_id(), "agent-1");
222            assert_eq!(runtime.transport().agent_key_id(), 5);
223        }
224    }
225
226    #[cfg(feature = "core")]
227    #[test]
228    fn core_reexport_accessible() {
229        let _ = core::CommerceError::NotFound;
230    }
231
232    #[cfg(feature = "core")]
233    #[test]
234    fn primitives_reexport_accessible() {
235        let _id = primitives::OrderId::new();
236    }
237
238    #[cfg(feature = "core")]
239    #[test]
240    fn db_reexport_accessible() {
241        // DatabaseConfig is available through db re-export
242        let _cfg = db::DatabaseConfig::in_memory();
243    }
244
245    #[cfg(feature = "core")]
246    #[test]
247    fn observability_reexport_accessible() {
248        let _cfg = observability::MetricsConfig::default();
249    }
250
251    #[cfg(feature = "crypto")]
252    #[test]
253    fn crypto_reexport_accessible() {
254        let _ = crypto::ZERO_HASH;
255    }
256
257    #[cfg(feature = "sync")]
258    #[test]
259    fn sync_reexport_accessible() {
260        let runtime = SyncRuntimeConfig::new(
261            "https://sequencer.stateset.com",
262            sync::SyncConfig::new("agent-1", "tenant-1", "store-1"),
263        )
264        .with_api_key("ss_example_key")
265        .with_agent_key_id(11)
266        .build()
267        .unwrap();
268        assert_eq!(runtime.transport().agent_key_id(), 11);
269    }
270
271    #[cfg(feature = "policy")]
272    #[test]
273    fn policy_reexport_accessible() {
274        let _ = policy::PolicyEngine::new();
275    }
276
277    #[cfg(feature = "macros")]
278    #[test]
279    fn macros_reexport_accessible() {
280        #[allow(unused_imports)]
281        use crate::macros as _;
282    }
283}
284
285/// Compiles the code examples in `README.md` as doctests, so the crates.io
286/// landing page can never drift from the real API.
287#[cfg(doctest)]
288#[doc = include_str!("../README.md")]
289struct ReadmeDoctests;