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}