1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Portable database and transactional state-store abstractions.
//!
//! Built-in databases are opened with [`Database::connect`], while built-in
//! state stores are opened with [`StateStore::connect`]. Caller-defined roots
//! implement [`DatabaseBackend`] or [`StateStoreBackend`] directly. Associated
//! state transactions remain owned by their parent backend.
//!
//! Supporting request, response, and configuration types live in the
//! functional [`database`] and [`state`] modules.
//!
//! [`Database`] owns application data and retrieval. [`StateStore`] owns
//! revisioned control-plane records, with a unique transaction for atomic writes.
//! A StateStore transaction cannot include Database effects. Bring the relevant
//! backend traits into scope to invoke behavior on the supplied handles.
//!
//! # Choose a workflow
//!
//! - Application builders: [collection writes, filtered/vector retrieval and
//! index cleanup](database), then [transactions and durable reopen](state).
//! - Custom implementers: [concrete Database composition](DatabaseBackend) and
//! [associated StateStore/Transaction composition](StateStoreBackend).
//! These examples delegate real storage semantics without an erased ingress.
//!
//! # Transactional state
//!
//! This example runs against process-local Lance and requires no service:
//!
//! ```
//! use storage_kit::{StateStore, StateStoreBackend, StateTransactionBackend};
//! use storage_kit::state::{
//! config::{LanceStateStoreConfig, StateStoreConfig},
//! record::{StateKey, StateRecord},
//! };
//! # tokio::runtime::Runtime::new()?.block_on(async {
//! let store = StateStore::connect(StateStoreConfig::lance(LanceStateStoreConfig::memory())).await?;
//! let key = StateKey::new("workflow", "run/1")?;
//! let mut transaction = store.begin_transaction().await?;
//! transaction.put(StateRecord::new(key.clone(), serde_json::json!({"status": "ready"}))).await?;
//! transaction.commit().await?;
//! let observed = store.load(key).await?.expect("committed record");
//! assert_eq!(observed.revision.get(), 1);
//! # Ok::<(), storage_kit::StateStoreError>(())
//! # })?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! Conditional writes must read their precondition through the same transaction
//! that commits them. Separate reads or listing pages do not establish a fence
//! or historical snapshot. After an uncertain commit result, reconcile durable
//! application state before retrying; losing a reply does not establish rollback.
//!
//! # Application data
//!
//! This example opens an in-memory LanceDB instance and performs a catalog read:
//!
//! ```
//! use storage_kit::{Database, DatabaseBackend};
//! use storage_kit::database::{
//! config::{DatabaseConfig, LanceConfig},
//! catalog::{CatalogRequest, CatalogResponse, ListCollectionsRequest},
//! };
//! # tokio::runtime::Runtime::new()?.block_on(async {
//! let database = Database::connect(DatabaseConfig::lance(LanceConfig::embedded_path("memory://"))).await?;
//! let response = database.catalog(CatalogRequest::ListCollections(ListCollectionsRequest {
//! namespace: Vec::new(), limit: Some(10), start_after: None,
//! })).await?;
//! assert!(matches!(response, CatalogResponse::Collections(_)));
//! # Ok::<(), storage_kit::StorageError>(())
//! # })?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! Use [`database::catalog`] for collections and schemas, [`database::data`] for
//! records and writes, [`database::query`] for retrieval, and [`database::index`]
//! for index lifecycle. Optional capabilities describe supported families;
//! operation results remain authoritative for each request.
//!
//! # Features
//!
//! LanceDB Database and the embedded Lance StateStore are always compiled as
//! distinct products. Cargo defaults are empty (`default = []`). Alternative backends
//! require explicit `redb`, `postgres`, `sqlite`, or `surrealdb`
//! features. Default and no-default builds both provide Lance alone.
//!
//! # Static composition
//!
//! Advanced DTOs are intentionally absent from the crate root:
//!
//! ```compile_fail
//! use storage_kit::DataRecord;
//! ```
//!
//! Each [`StateStoreBackend`] returns its own associated transaction type.
//! The built-in [`StateTransaction`] remains a unique owner:
//!
//! ```compile_fail
//! let _ = storage_kit::StateTransaction::from_backend;
//! ```
//!
//! ```compile_fail
//! fn require_clone<T: Clone>() {}
//! require_clone::<storage_kit::StateTransaction>();
//! ```
//!
//! RPITIT backend traits are implemented directly rather than exposed as
//! public trait objects:
//!
//! ```compile_fail
//! fn accept_erased(_: &dyn storage_kit::DatabaseBackend) {}
//! ```
pub use crateStorageError;
pub use crate;
pub use crate;
pub use crate*;
pub use cratePassword;
pub use crate*;
pub use crateStateNamespace;
pub use crate;