meerkat_runtime/store/
mod.rs1pub mod memory;
7#[cfg(feature = "sqlite-store")]
8pub mod sqlite;
9
10use meerkat_core::lifecycle::{InputId, RunBoundaryReceipt, RunId};
11
12use crate::identifiers::LogicalRuntimeId;
13use crate::input_state::StoredInputState;
14use crate::runtime_state::RuntimeState;
15
16#[derive(Debug, Clone, thiserror::Error)]
18#[non_exhaustive]
19pub enum RuntimeStoreError {
20 #[error("Store write failed: {0}")]
22 WriteFailed(String),
23 #[error("Store read failed: {0}")]
25 ReadFailed(String),
26 #[error("Session store key mismatch: expected {expected}, actual {actual}")]
28 SessionKeyMismatch {
29 expected: meerkat_core::types::SessionId,
30 actual: meerkat_core::types::SessionId,
31 },
32 #[error("Not found: {0}")]
34 NotFound(String),
35 #[error("Unsupported store operation: {0}")]
37 Unsupported(String),
38 #[error("Internal error: {0}")]
40 Internal(String),
41}
42
43pub type AuthOAuthFlowSnapshotUpdate<'a> =
45 dyn FnMut(Option<&[u8]>) -> Result<Vec<u8>, RuntimeStoreError> + 'a;
46
47#[derive(Debug, Clone)]
49pub struct SessionDelta {
50 pub session_snapshot: Vec<u8>,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub struct MachineLifecycleCommit {
61 runtime_state: RuntimeState,
62}
63
64impl MachineLifecycleCommit {
65 pub(crate) fn new(runtime_state: RuntimeState) -> Self {
66 Self { runtime_state }
67 }
68
69 pub fn runtime_state(self) -> RuntimeState {
71 self.runtime_state
72 }
73}
74
75#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
81#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
82pub trait RuntimeStore: Send + Sync {
83 fn auth_authority_key(&self) -> Option<String> {
86 None
87 }
88
89 fn persist_auth_oauth_flow_snapshot(
95 &self,
96 snapshot_json: &[u8],
97 ) -> Result<(), RuntimeStoreError> {
98 let _ = snapshot_json;
99 Err(RuntimeStoreError::Unsupported(
100 "persist_auth_oauth_flow_snapshot".into(),
101 ))
102 }
103
104 fn load_auth_oauth_flow_snapshot(&self) -> Result<Option<Vec<u8>>, RuntimeStoreError> {
106 Err(RuntimeStoreError::Unsupported(
107 "load_auth_oauth_flow_snapshot".into(),
108 ))
109 }
110
111 fn update_auth_oauth_flow_snapshot(
117 &self,
118 _update: &mut AuthOAuthFlowSnapshotUpdate<'_>,
119 ) -> Result<(), RuntimeStoreError> {
120 Err(RuntimeStoreError::Unsupported(
121 "update_auth_oauth_flow_snapshot".into(),
122 ))
123 }
124
125 async fn commit_session_snapshot(
130 &self,
131 runtime_id: &LogicalRuntimeId,
132 session_delta: SessionDelta,
133 ) -> Result<(), RuntimeStoreError>;
134
135 async fn atomic_apply(
148 &self,
149 runtime_id: &LogicalRuntimeId,
150 session_delta: Option<SessionDelta>,
151 receipt: RunBoundaryReceipt,
152 input_updates: Vec<StoredInputState>,
153 session_store_key: Option<meerkat_core::types::SessionId>,
154 ) -> Result<(), RuntimeStoreError>;
155
156 async fn load_input_states(
158 &self,
159 runtime_id: &LogicalRuntimeId,
160 ) -> Result<Vec<StoredInputState>, RuntimeStoreError>;
161
162 async fn load_boundary_receipt(
164 &self,
165 runtime_id: &LogicalRuntimeId,
166 run_id: &RunId,
167 sequence: u64,
168 ) -> Result<Option<RunBoundaryReceipt>, RuntimeStoreError>;
169
170 async fn load_session_snapshot(
172 &self,
173 runtime_id: &LogicalRuntimeId,
174 ) -> Result<Option<Vec<u8>>, RuntimeStoreError>;
175
176 async fn persist_input_state(
178 &self,
179 runtime_id: &LogicalRuntimeId,
180 state: &StoredInputState,
181 ) -> Result<(), RuntimeStoreError>;
182
183 async fn load_input_state(
185 &self,
186 runtime_id: &LogicalRuntimeId,
187 input_id: &InputId,
188 ) -> Result<Option<StoredInputState>, RuntimeStoreError>;
189
190 async fn load_runtime_state(
192 &self,
193 runtime_id: &LogicalRuntimeId,
194 ) -> Result<Option<RuntimeState>, RuntimeStoreError>;
195
196 async fn commit_machine_lifecycle(
202 &self,
203 runtime_id: &LogicalRuntimeId,
204 commit: MachineLifecycleCommit,
205 input_states: &[StoredInputState],
206 ) -> Result<(), RuntimeStoreError>;
207
208 async fn persist_ops_lifecycle(
210 &self,
211 runtime_id: &LogicalRuntimeId,
212 snapshot: &crate::ops_lifecycle::PersistedOpsSnapshot,
213 ) -> Result<(), RuntimeStoreError> {
214 let _ = (runtime_id, snapshot);
215 Err(RuntimeStoreError::Unsupported(
216 "persist_ops_lifecycle".into(),
217 ))
218 }
219
220 async fn load_ops_lifecycle(
222 &self,
223 runtime_id: &LogicalRuntimeId,
224 ) -> Result<Option<crate::ops_lifecycle::PersistedOpsSnapshot>, RuntimeStoreError> {
225 let _ = runtime_id;
226 Err(RuntimeStoreError::Unsupported("load_ops_lifecycle".into()))
227 }
228}
229
230pub use memory::InMemoryRuntimeStore;
231#[cfg(feature = "sqlite-store")]
232pub use sqlite::SqliteRuntimeStore;