Skip to main content

worldinterface_contextstore/
store.rs

1//! ContextStore trait — the contract for durable node output storage.
2
3use serde_json::Value;
4use worldinterface_core::id::{FlowRunId, NodeId};
5
6use crate::error::ContextStoreError;
7
8/// Durable store for flow node outputs.
9///
10/// Keyed by `(FlowRunId, NodeId)` for node outputs and by `String` for globals.
11/// All methods are synchronous — the SQLite backend runs on a blocking thread,
12/// and callers (Step handlers in Sprint 4) will invoke from a blocking context
13/// or use `spawn_blocking`.
14pub trait ContextStore: Send + Sync {
15    /// Write a node's output. Enforces write-once semantics:
16    /// - First call for a given (flow_run_id, node_id): stores the value, returns Ok(())
17    /// - Subsequent calls with the same key: returns Err(ContextStoreError::AlreadyExists)
18    fn put(
19        &self,
20        flow_run_id: FlowRunId,
21        node_id: NodeId,
22        value: &Value,
23    ) -> Result<(), ContextStoreError>;
24
25    /// Read a node's output. Returns None if not yet written.
26    fn get(
27        &self,
28        flow_run_id: FlowRunId,
29        node_id: NodeId,
30    ) -> Result<Option<Value>, ContextStoreError>;
31
32    /// List all node IDs that have outputs for a given flow run.
33    fn list_keys(&self, flow_run_id: FlowRunId) -> Result<Vec<NodeId>, ContextStoreError>;
34
35    /// Write a global key-value pair. Globals are not scoped to a flow run.
36    /// Write-once semantics: second put for the same key returns GlobalAlreadyExists.
37    fn put_global(&self, key: &str, value: &Value) -> Result<(), ContextStoreError>;
38
39    /// Write or update a global key-value pair.
40    /// Unlike `put_global`, this allows overwriting an existing value.
41    /// Used for mutable global metadata (e.g., coordinator map).
42    fn upsert_global(&self, key: &str, value: &Value) -> Result<(), ContextStoreError>;
43
44    /// Read a global value. Returns None if not yet written.
45    fn get_global(&self, key: &str) -> Result<Option<Value>, ContextStoreError>;
46}