- Use hero_supervisor_openrpc_client::JobBuilder for both native and WASM builds - Simplified execute_script method by removing duplicate job building code - JobBuilder now works consistently across platforms - Removed separate WasmJobBuilder usage
OSIRIS
Object Storage with Rhai Scripting Integration
OSIRIS is a Rust-native object storage layer built on HeroDB, providing structured storage with automatic indexing, Rhai scripting support, and signatory-based access control.
Overview
OSIRIS provides a trait-based architecture for storing and retrieving typed objects with:
- Automatic Indexing: Fields marked with
#[index]are automatically indexed - Rhai Integration: Full scripting support with builder patterns
- Context-Based Storage: Multi-tenant contexts with signatory-based access control
- Type Safety: Compile-time guarantees through the
Objecttrait - HeroDB Backend: Built on top of HeroDB (Redis-compatible)
Quick Start
Build OSIRIS
cargo build --release --features rhai-support
Run a Rhai Script
cargo run --bin runner --features rhai-support -- runner1 \
--redis-url redis://localhost:6379 \
--db-id 1 \
--script-file examples/engine/01_note.rhai
Example Script
// Get a context (requires signatories)
let ctx = get_context(["alice_pk", "bob_pk"]);
// Create a note
let note = note("notes")
.title("My First Note")
.content("This is the content")
.tag("topic", "rust")
.tag("priority", "high");
// Save to context
ctx.save(note);
// Query by index
let ids = ctx.query("notes", "tags:tag", "topic=rust");
print(`Found ${ids.len()} notes`);
Architecture
Core Components
OSIRIS
├── objects/ – Domain objects (Note, Event, User, etc.)
│ ├── note/
│ │ ├── mod.rs – Note struct and impl
│ │ └── rhai.rs – Rhai bindings
│ └── event/
│ ├── mod.rs – Event struct and impl
│ └── rhai.rs – Rhai bindings
├── store/ – Storage layer
│ ├── generic_store.rs – Type-safe storage
│ └── type_registry.rs – Custom type registration
├── rhai/ – Rhai integration
│ ├── instance.rs – OsirisContext (multi-tenant)
│ └── engine.rs – Engine configuration
└── bin/
└── runner.rs – Standalone script runner
Object Trait
All OSIRIS objects implement the Object trait:
#[derive(Debug, Clone, Serialize, Deserialize, DeriveObject)]
pub struct Note {
pub base_data: BaseData,
#[index]
pub title: Option<String>,
pub content: Option<String>,
#[index]
pub tags: BTreeMap<String, String>,
}
The #[derive(DeriveObject)] macro automatically:
- Implements the
Objecttrait - Generates index keys from
#[index]fields - Provides serialization/deserialization
Key Features
1. Signatory-Based Access Control
Contexts use signatory-based access instead of owner-based permissions:
// Single participant
let ctx = get_context(["alice_pk"]);
// Shared context (all must be signatories)
let ctx = get_context(["alice_pk", "bob_pk", "charlie_pk"]);
Access is granted only if all participants are signatories of the script.
2. Automatic Indexing
Fields marked with #[index] are automatically indexed in HeroDB:
#[index]
pub title: Option<String>, // Indexed for fast queries
pub content: Option<String>, // Not indexed
Query by indexed fields:
let ids = ctx.query("notes", "title", "My Note");
let ids = ctx.query("notes", "tags:tag", "topic=rust");
3. Multi-Instance Support
Create multiple OSIRIS instances pointing to different databases:
cargo run --bin runner --features rhai-support -- runner1 \
--instance freezone:redis://localhost:6379:1 \
--instance my:redis://localhost:6379:2 \
--script-file script.rhai
// Instances are automatically available
freezone.save(note);
my.save(note);
4. Builder Pattern
Fluent API for creating objects:
let event = event("calendar", "Team Meeting")
.description("Weekly sync")
.location("Conference Room A")
.category("meetings")
.all_day(false);
ctx.save(event);
Creating Custom Objects
See docs/CREATING_NEW_OBJECTS.md for a complete guide on creating new object types.
Quick example:
#[derive(Debug, Clone, Serialize, Deserialize, DeriveObject)]
pub struct Task {
pub base_data: BaseData,
#[index]
pub title: String,
pub completed: bool,
}
Storage Model
HeroDB Keyspace
obj:<ns>:<id> → JSON serialized object
idx:<ns>:<field>:<value> → Set of object IDs
scan:<ns> → Set of all object IDs in namespace
Example:
obj:notes:abc123 → {"base_data":{...},"title":"My Note",...}
idx:notes:title:My Note → {abc123, def456}
idx:notes:tag:topic:rust → {abc123, xyz789}
scan:notes → {abc123, def456, xyz789}
Context Storage
Contexts store member privileges and metadata:
ctx:<context_id>:members → Map of user_id → privileges
ctx:<context_id>:meta → Context metadata
Examples
The examples/ directory contains comprehensive examples:
-
examples/engine/- Object creation and storage examples01_note.rhai- Note creation and querying02_event.rhai- Event management03_user.rhai- User objects- And more...
-
examples/freezone/- Complete freezone registration flow
Run examples:
cargo run --example engine examples/engine/01_note.rhai
Documentation
- docs/ARCHITECTURE.md - Detailed architecture and design patterns
- docs/CREATING_NEW_OBJECTS.md - Guide for creating custom objects
Building and Testing
# Build with Rhai support
cargo build --features rhai-support
# Run tests
cargo test --lib --features rhai-support
# Build release binary
cargo build --release --features rhai-support --bin runner
Integration
OSIRIS is used by:
- ZDFZ Backend - Freezone company and resident management
- Hero Actor System - Distributed job execution with object storage
License
See LICENSE file.