hyperstack-sdk
Rust client SDK for connecting to HyperStack streaming servers.
Installation
[]
= "0.2"
TLS Options
By default, the SDK uses rustls for TLS. You can switch to native TLS:
[]
= { = "0.1", = false, = ["native-tls"] }
Quick Start
use *;
use ;
async
The prelude module re-exports all commonly needed types including StreamExt, so you don't need separate imports from futures_util.
Lazy Streams with Chainable Operators
Streams are lazy - calling watch() returns immediately without subscribing. The subscription happens automatically on first poll. This enables ergonomic method chaining:
use HashSet;
let watchlist: = /* tokens to watch */;
let mut price_alerts = hs
.
.filter
.filter_map;
while let Some = price_alerts.next.await
Available Stream Operators
| Operator | Description |
|---|---|
.filter(predicate) |
Keep only updates matching the predicate |
.filter_map(f) |
Filter and transform in one step |
.map(f) |
Transform each update |
All operators are chainable and return streams that support the same operators.
API Reference
HyperStack Client
// Simple connection
let hs = connect.await?;
// With configuration
let hs = builder
.url
.auto_reconnect
.max_reconnect_attempts
.ping_interval
.initial_data_timeout
.connect
.await?;
Core Methods
| Method | Returns | Description |
|---|---|---|
get::<E>(key).await |
Option<T> |
Get a single entity by key |
list::<E>().await |
Vec<T> |
Get all entities of type E |
watch::<E>() |
EntityStream<T> |
Stream all updates (lazy) |
watch_key::<E>(key) |
EntityStream<T> |
Stream updates for a specific key (lazy) |
watch_keys::<E>(&[keys]) |
EntityStream<T> |
Stream updates for multiple keys (lazy) |
watch_rich::<E>() |
RichEntityStream<T> |
Stream with before/after values (lazy) |
watch_key_rich::<E>(key) |
RichEntityStream<T> |
Rich stream for specific key (lazy) |
connection_state().await |
ConnectionState |
Get current connection state |
disconnect().await |
() |
Close the connection |
Update Types
When streaming with watch(), you receive Update<T> variants:
Helper methods: key(), data(), is_delete(), has_data(), into_data(), into_key(), map(f)
Rich Updates (Before/After Diffs)
For tracking changes over time, use watch_rich():
The Updated variant includes patch - the raw JSON of changed fields, useful for checking what specifically changed:
if update.has_patch_field
Understanding Option<Option<T>> Fields
Generated entity types often have fields typed as Option<Option<T>>. This represents the patch semantics of HyperStack updates:
| Value | Meaning |
|---|---|
None |
Field was not included in this update (no change) |
Some(None) |
Field was explicitly set to null |
Some(Some(value)) |
Field has a concrete value |
This distinction matters for partial updates (patches). When the server sends a patch, only changed fields are included. An absent field means "keep the previous value", while an explicit null means "clear this field".
Working with Option<Option<T>>
// Access a nested optional field
let price = token.trading.last_trade_price.flatten.unwrap_or;
// Check if field was explicitly set (vs absent from patch)
match &token.reserves.current_price_sol
// Compare values in before/after
if before.trading.last_trade_price != after.trading.last_trade_price
Generating a Rust SDK
Use the HyperStack CLI to generate a typed Rust SDK from your spec:
# Generate SDK crate
# With custom output directory
# With custom crate name
This generates a crate with:
generated/settlement-game-stack/
├── Cargo.toml
└── src/
├── lib.rs # Re-exports
├── types.rs # Data structs (with Option<Option<T>> for patchable fields)
└── entity.rs # Entity trait implementations
Add the generated crate to your Cargo.toml:
[]
= "0.2"
= { = "./generated/settlement-game-stack" }
Connection Management
Auto-Reconnection
The SDK automatically reconnects on connection loss with configurable backoff:
let hs = builder
.url
.auto_reconnect
.reconnect_intervals
.max_reconnect_attempts
.connect
.await?;
Connection State
let state = hs.connection_state.await;
match state
Streaming Modes
| Mode | View | Description |
|---|---|---|
| State | Entity/state |
Single shared state object |
| List | Entity/list |
All entities, key-value lookups |
| Append | Entity/append |
Append-only event log |
License
MIT