hyperstack_interpreter/
lib.rs

1//! # hyperstack-interpreter
2//!
3//! AST transformation runtime and VM for HyperStack streaming pipelines.
4//!
5//! This crate provides the core components for processing Solana blockchain
6//! events into typed state projections:
7//!
8//! - **AST Definition** - Type-safe schemas for state and event handlers
9//! - **Bytecode Compiler** - Compiles specs into optimized bytecode  
10//! - **Virtual Machine** - Executes bytecode to process events
11//! - **TypeScript Generation** - Generate client SDKs automatically
12//!
13//! ## Example
14//!
15//! ```rust,ignore
16//! use hyperstack_interpreter::{TypeScriptCompiler, TypeScriptConfig};
17//!
18//! let config = TypeScriptConfig::default();
19//! let compiler = TypeScriptCompiler::new(config);
20//! let typescript = compiler.compile(&spec)?;
21//! ```
22//!
23//! ## Feature Flags
24//!
25//! - `otel` - OpenTelemetry integration for distributed tracing and metrics
26
27pub mod ast;
28pub mod canonical_log;
29pub mod compiler;
30pub mod metrics_context;
31pub mod proto_router;
32pub mod resolvers;
33pub mod rust;
34pub mod spec_trait;
35pub mod typescript;
36pub mod vm;
37pub mod vm_metrics;
38
39pub use canonical_log::{CanonicalLog, LogLevel};
40pub use metrics_context::{FieldAccessor, FieldRef, MetricsContext};
41pub use resolvers::{InstructionContext, KeyResolution, ResolveContext, ReverseLookupUpdater};
42pub use typescript::{write_typescript_to_file, TypeScriptCompiler, TypeScriptConfig};
43pub use vm::{
44    CapacityWarning, CleanupResult, DirtyTracker, FieldChange, PendingAccountUpdate,
45    PendingQueueStats, QueuedAccountUpdate, StateTableConfig, UpdateContext, VmMemoryStats,
46};
47
48// Re-export macros for convenient use
49// The field! macro is the new recommended way to create field references
50// The field_accessor! macro is kept for backward compatibility
51
52use serde::{Deserialize, Serialize};
53use serde_json::Value;
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct Mutation {
57    pub export: String,
58    pub key: Value,
59    pub patch: Value,
60    #[serde(skip_serializing_if = "Vec::is_empty", default)]
61    pub append: Vec<String>,
62}
63
64/// Generic wrapper for event data that includes context metadata
65/// This ensures type safety for events captured in entity specs
66///
67/// # Runtime Structure
68/// Events captured with `#[event]` are automatically wrapped in this structure:
69/// ```json
70/// {
71///   "timestamp": 1234567890,
72///   "data": { /* event-specific data */ },
73///   "slot": 381471241,
74///   "signature": "4xNEYTVL8DB28W87..."
75/// }
76/// ```
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct EventWrapper<T = Value> {
79    /// Unix timestamp when the event was processed
80    pub timestamp: i64,
81    /// The event-specific data
82    pub data: T,
83    /// Optional slot number from UpdateContext
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub slot: Option<u64>,
86    /// Optional transaction signature from UpdateContext
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub signature: Option<String>,
89}
90
91/// Generic wrapper for account capture data that includes context metadata
92/// This ensures type safety for accounts captured with `#[capture]` in entity specs
93///
94/// # Runtime Structure
95/// Accounts captured with `#[capture]` are automatically wrapped in this structure:
96/// ```json
97/// {
98///   "timestamp": 1234567890,
99///   "account_address": "C6P5CpJnYHgpGvCGuXYAWL6guKH5LApn3QwTAZmNUPCj",
100///   "data": { /* account-specific data (filtered, no __ fields) */ },
101///   "slot": 381471241,
102///   "signature": "4xNEYTVL8DB28W87..."
103/// }
104/// ```
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct CaptureWrapper<T = Value> {
107    /// Unix timestamp when the account was captured
108    pub timestamp: i64,
109    /// The account address (base58 encoded public key)
110    pub account_address: String,
111    /// The account data (already filtered to remove internal __ fields)
112    pub data: T,
113    /// Optional slot number from UpdateContext
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub slot: Option<u64>,
116    /// Optional transaction signature from UpdateContext
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub signature: Option<String>,
119}